diff --git a/docs/README.skills.md b/docs/README.skills.md index 8c2876521..7a8a975c5 100644 --- a/docs/README.skills.md +++ b/docs/README.skills.md @@ -22,4 +22,5 @@ Skills differ from other primitives by supporting bundled assets (scripts, code | Name | Description | Bundled Assets | | ---- | ----------- | -------------- | +| [skill-finder](../skills/skill-finder/SKILL.md) | Full-featured Agent Skills management: Search 35+ skills, install locally, star favorites, update from sources. Supports tag search (#azure #bicep), category filtering, and similar skill recommendations. | `LICENSE.txt`
`README.md`
`assets/demo-en.mp4`
`assets/demo-ja.mp4`
`assets/demo.mp4`
`assets/demo.png`
`references/skill-index.json`
`references/skill-index.schema.json`
`references/starred-skills.json`
`scripts/Search-Skills.ps1`
`scripts/search_skills.py` | | [webapp-testing](../skills/webapp-testing/SKILL.md) | Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. | `test-helper.js` | diff --git a/skills/skill-finder/LICENSE.txt b/skills/skill-finder/LICENSE.txt new file mode 100644 index 000000000..6dfde0345 --- /dev/null +++ b/skills/skill-finder/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 yamapan (https://github.com/aktsmm) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/skills/skill-finder/README.md b/skills/skill-finder/README.md new file mode 100644 index 000000000..fc268d366 --- /dev/null +++ b/skills/skill-finder/README.md @@ -0,0 +1,277 @@ +# Skill Finder + +> Full-featured Agent Skills management: Search, Install, Star, and Update. +> +> フル機能の Agent Skills 管理ツール: 検索・インストール・お気に入り・更新 + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +[![GitHub](https://img.shields.io/badge/GitHub-aktsmm-blue?logo=github)](https://github.com/aktsmm) + +**Author / 作者**: yamapan ([@aktsmm](https://github.com/aktsmm)) + +## Features / 機能 + +- 🔍 **Local Index Search** - Fast offline search from 220+ pre-indexed skills +- 🏷️ **Tag Search** - Search by tags like `#azure #bicep` +- 🌐 **GitHub Search** - Search SKILL.md files on GitHub +- 📦 **Install Skills** - Download skills to local directory +- ⭐ **Star Favorites** - Mark and manage favorite skills +- 📊 **Statistics** - View index stats and category breakdown +- 🔄 **Auto Update** - Update all sources from GitHub +- 💡 **Similar Skills** - Get recommendations based on categories + +--- + +- 🔍 **ローカル検索** - 220 以上のスキルから高速オフライン検索 +- 🏷️ **タグ検索** - `#azure #bicep` のようなタグで検索 +- 🌐 **GitHub 検索** - GitHub 上の SKILL.md を検索 +- 📦 **インストール** - スキルをローカルにダウンロード +- ⭐ **お気に入り** - よく使うスキルをスター管理 +- 📊 **統計情報** - インデックスの統計とカテゴリ内訳 +- 🔄 **自動更新** - 全ソースを GitHub から更新 +- 💡 **類似スキル** - カテゴリベースのおすすめ表示 + +## How to Use Skills / スキルの使い方 + +### 1. Install to designated directory / 所定のディレクトリに配置 + +```bash +~/.github/skills/ # GitHub Copilot +~/.claude/skills/ # Claude Code +``` + +### 2. Just prompt / プロンプトを指示するだけ + +Skill Finder をスキルとして配置後、AI エージェントにスキルを探すよう指示するだけ: + +``` +「Azure関連のスキルを探して」 → #azure タグで検索 +「ドキュメント処理のスキルある?」→ #document で検索 +「PDFを扱えるスキルを教えて」 → pdf で検索 +``` + +### Demo / デモ + +**日本語デモ:** + +https://github.com/user-attachments/assets/c35fe891-a43e-48da-a107-853b41639c8d + +**English Demo:** + +https://github.com/user-attachments/assets/4cfc7661-fdc8-40d8-8ad5-65bfd745e796 + +## Quick Start / クイックスタート + +### Search / 検索 + +```bash +# Basic search / 基本検索 +python scripts/search_skills.py "pdf" +pwsh scripts/Search-Skills.ps1 -Query "pdf" + +# Tag search / タグ検索 +python scripts/search_skills.py "#azure #bicep" +pwsh scripts/Search-Skills.ps1 -Query "#azure #development" + +# Category filter / カテゴリフィルタ +python scripts/search_skills.py --category development +pwsh scripts/Search-Skills.ps1 -Category "development" +``` + +### Skill Management / スキル管理 + +```bash +# Show skill details / スキル詳細表示 +python scripts/search_skills.py --info skill-name +pwsh scripts/Search-Skills.ps1 -Info "skill-name" + +# Install skill / スキルをインストール +python scripts/search_skills.py --install skill-name +pwsh scripts/Search-Skills.ps1 -Install "skill-name" + +# Star/Unstar / お気に入り追加・削除 +python scripts/search_skills.py --star skill-name +python scripts/search_skills.py --unstar skill-name +pwsh scripts/Search-Skills.ps1 -Star "skill-name" +``` + +### Index Management / インデックス管理 + +```bash +# Update all sources / 全ソースを更新 +python scripts/search_skills.py --update +pwsh scripts/Search-Skills.ps1 -Update + +# Add new source / 新しいソースを追加 +python scripts/search_skills.py --add-source https://github.com/owner/repo +pwsh scripts/Search-Skills.ps1 -AddSource -RepoUrl "https://github.com/owner/repo" + +# View statistics / 統計情報表示 +python scripts/search_skills.py --stats +pwsh scripts/Search-Skills.ps1 -Stats +``` + +### Utilities / ユーティリティ + +```bash +# List options / オプション一覧 +python scripts/search_skills.py --list-categories +python scripts/search_skills.py --list-sources +python scripts/search_skills.py --list-starred + +# Find similar skills / 類似スキル検索 +python scripts/search_skills.py --similar skill-name + +# Check dependencies / 依存関係チェック +python scripts/search_skills.py --check +``` + +## Command Reference / コマンドリファレンス + +| Python | PowerShell | Description | +| ----------------- | ---------------- | -------------------------------- | +| `--info SKILL` | `-Info SKILL` | Show skill details with SKILL.md | +| `--install SKILL` | `-Install SKILL` | Download skill locally | +| `--star SKILL` | `-Star SKILL` | Star a skill | +| `--unstar SKILL` | `-Unstar SKILL` | Remove star | +| `--list-starred` | `-ListStarred` | List starred skills | +| `--similar SKILL` | `-Similar SKILL` | Find similar skills | +| `--stats` | `-Stats` | Show index statistics | +| `--update` | `-Update` | Update all sources | +| `--check` | `-Check` | Check tool dependencies | +| `#tag` in query | `#tag` in query | Filter by category tag | + +## Search Flow / 検索フロー + +``` +1. Local Index → Fast, offline (220+ skills) + ローカル検索 高速・オフライン (220以上のスキル) + ↓ not found / 見つからない +2. GitHub API → Search SKILL.md files + GitHub 検索 SKILL.md を検索 + ↓ not found / 見つからない +3. Web Search → Show search URLs + Web 検索 検索 URL を表示 + ↓ found good repo / 良いリポジトリ発見 +4. Add to Index → --add-source + インデックス追加 +``` + +## Included Sources / 収録ソース + +| Source | Type | Description | +| ------------------------------------------------------------------------------------------------- | --------- | --------------------------- | +| [anthropics/skills](https://github.com/anthropics/skills) | Official | Official Claude skills | +| [obra/superpowers](https://github.com/obra/superpowers) | Community | Superpowers for Claude | +| [ComposioHQ/awesome-claude-skills](https://github.com/ComposioHQ/awesome-claude-skills) | Awesome | Curated skill list | +| [microsoft/windows-ai-studio-templates](https://github.com/microsoft/windows-ai-studio-templates) | Official | Microsoft AI templates | +| [github/copilot-instructions](https://github.com/github/copilot-instructions) | Official | GitHub Copilot instructions | +| [aktsmm/Agent-Skills](https://github.com/aktsmm/Agent-Skills) | Community | Azure/Development skills | + +## Categories / カテゴリ + +| ID | EN | JP | +| ----------- | ---------------------- | ---------------- | +| development | Software development | ソフトウェア開発 | +| testing | Testing & QA | テスト | +| document | Document processing | ドキュメント処理 | +| web | Web development | Web 開発 | +| git | Git & version control | Git | +| agents | AI agents | AI エージェント | +| mcp | Model Context Protocol | MCP | +| azure | Azure services | Azure | +| creative | Creative content | クリエイティブ | +| meta | Meta/utility skills | メタスキル | + +## Requirements / 必要環境 + +### Required / 必須 + +| Tool | Version | Purpose | Install | +| -------------- | ------- | --------------------- | ----------------------------------------- | +| **GitHub CLI** | 2.0+ | Search/install skills | [cli.github.com](https://cli.github.com/) | +| **curl** | Any | Download files | Pre-installed | + +### Optional (choose one) / いずれか選択 + +| Runtime | Version | Script | +| ---------- | ------- | --------------------------- | +| PowerShell | 7+ | `scripts/Search-Skills.ps1` | +| Python | 3.8+ | `scripts/search_skills.py` | + +### Setup / セットアップ + +```bash +# 1. Install GitHub CLI / GitHub CLI をインストール +# Windows (winget) +winget install GitHub.cli + +# macOS (Homebrew) +brew install gh + +# Linux (apt) +sudo apt install gh + +# 2. Authenticate / 認証 +gh auth login + +# 3. Verify / 確認 +gh --version +curl --version +``` + +### Check Dependencies / 依存関係チェック + +```bash +# Check all at once / 一括チェック +python scripts/search_skills.py --check +pwsh scripts/Search-Skills.ps1 -Check +``` + +**Expected output / 期待される出力:** + +``` +✅ gh: installed (version 2.x.x) +✅ curl: installed +✅ All dependencies satisfied +``` + +### Troubleshooting / トラブルシューティング + +| Issue | Solution | +| ----------------------- | ----------------------------------------- | +| `gh: command not found` | Install GitHub CLI and add to PATH | +| `gh auth login` fails | Run `gh auth login` and follow prompts | +| Rate limit exceeded | Wait or authenticate with `gh auth login` | +| curl SSL errors | Update curl or check network/proxy | + +## File Structure / ファイル構成 + +``` +skill-finder/ +├── SKILL.md # Skill definition / スキル定義 +├── README.md # This file / このファイル +├── LICENSE # MIT License +├── assets/ +│ └── demo.mp4 # Demo video / デモ動画 +├── scripts/ +│ ├── search_skills.py # Python script +│ └── Search-Skills.ps1 # PowerShell script +└── references/ + ├── skill-index.json # Skill index (220+ skills) + └── starred-skills.json # Starred skills +``` + +## Contributing / 貢献 + +Found a great skill repository? Add it to the index and submit a PR! + +素晴らしいスキルリポジトリを見つけたら、インデックスに追加して PR を送ってください! + +## License + +MIT - See [LICENSE](LICENSE) for details. + +--- + +© 2025 yamapan ([@aktsmm](https://github.com/aktsmm)) diff --git a/skills/skill-finder/SKILL.md b/skills/skill-finder/SKILL.md new file mode 100644 index 000000000..e358937ba --- /dev/null +++ b/skills/skill-finder/SKILL.md @@ -0,0 +1,411 @@ +--- +name: skill-finder +description: "Full-featured Agent Skills management: Search 35+ skills, install locally, star favorites, update from sources. Supports tag search (#azure #bicep), category filtering, and similar skill recommendations." +license: MIT +metadata: + author: yamapan (https://github.com/aktsmm) +--- + +# Skill Finder + +Full-featured Agent Skills management tool with search, install, star, and update capabilities. + +## When to Use + +- Looking for skills for a specific task or domain +- Finding and installing skills locally +- Managing favorite skills with star feature +- Keeping your skill index up-to-date +- Discovering similar skills by category + +## Features + +- 🔍 **Search** - Local index (35+ skills) + GitHub API + Web fallback +- 🏷️ **Tags** - Search by category tags (`#azure #bicep`) +- 📦 **Install** - Download skills to local directory +- ⭐ **Star** - Mark and manage favorite skills +- 📊 **Stats** - View index statistics +- 🔄 **Update** - Sync all sources from GitHub +- 💡 **Similar** - Get category-based recommendations + +## Quick Start + +### Search + +```bash +# Keyword search +python scripts/search_skills.py "pdf" +pwsh scripts/Search-Skills.ps1 -Query "pdf" + +# Tag search (filter by category) +python scripts/search_skills.py "#azure #development" +pwsh scripts/Search-Skills.ps1 -Query "#azure #bicep" +``` + +### Skill Management + +```bash +# Show detailed info (includes SKILL.md content) +python scripts/search_skills.py --info skill-name + +# Install to local directory +python scripts/search_skills.py --install skill-name + +# Star favorite skills +python scripts/search_skills.py --star skill-name +python scripts/search_skills.py --list-starred +``` + +### Index Management + +```bash +# Update all sources +python scripts/search_skills.py --update + +# Add new source repository +python scripts/search_skills.py --add-source https://github.com/owner/repo + +# View statistics +python scripts/search_skills.py --stats +``` + +### List Options + +```bash +python scripts/search_skills.py --list-categories +python scripts/search_skills.py --list-sources +python scripts/search_skills.py --similar skill-name +``` + +### Add New Source + +When you find a good repository, add it to your index: + +```bash +python scripts/search_skills.py --add-source https://github.com/owner/repo +pwsh scripts/Search-Skills.ps1 -AddSource -RepoUrl "https://github.com/owner/repo" +``` + +This will: + +1. Add the repository as a source +2. Search for skills in `skills/`, `.github/skills/`, `.claude/skills/` +3. Auto-add found skills to your index + +## Command Reference + +| Command | Description | +| ----------------- | ------------------------------------------ | +| `--info SKILL` | Show skill details with SKILL.md content | +| `--install SKILL` | Download skill to ~/.skills or custom dir | +| `--star SKILL` | Add skill to favorites | +| `--unstar SKILL` | Remove from favorites | +| `--list-starred` | Show all starred skills | +| `--similar SKILL` | Find skills with matching categories | +| `--stats` | Show index statistics | +| `--update` | Update all sources from GitHub | +| `--check` | Verify tool dependencies (gh, curl) | +| `#tag` in query | Filter by category (e.g., `#azure #bicep`) | + +## Popular Repositories + +**Note:** These are representative examples. For the complete list, run `--list-sources` or check `sources` array in skill-index.json. + +### Official (type: `official`) + +- [anthropics/skills](https://github.com/anthropics/skills) - Official Claude Skills by Anthropic +- [github/awesome-copilot](https://github.com/github/awesome-copilot) - Official Copilot resources by GitHub + +### Curated Lists (type: `awesome-list`) + +- [ComposioHQ/awesome-claude-skills](https://github.com/ComposioHQ/awesome-claude-skills) - Curated Claude Skills + +### Community (type: `community`) + +- [obra/superpowers](https://github.com/obra/superpowers) - High-quality skills, agents, commands +- And many more... (run `--list-sources` for full list) + +## Categories + +**Dynamically extracted from skill-index.json.** Run `--list-categories` for current list. + +Common categories include: `development`, `testing`, `document`, `azure`, `web`, `git`, `agents`, `mcp`, `cloud`, `creative`, `planning`, etc. + +## Files + +| File | Description | +| -------------------------------- | ------------------------- | +| `scripts/Search-Skills.ps1` | PowerShell script | +| `scripts/search_skills.py` | Python script | +| `references/skill-index.json` | Skill index (220+ skills) | +| `references/starred-skills.json` | Your starred skills | + +## Requirements + +### Required + +| Tool | Version | Purpose | Install | +| -------------- | ------- | --------------------------------- | ----------------------------------------- | +| **GitHub CLI** | 2.0+ | Search/install skills from GitHub | [cli.github.com](https://cli.github.com/) | +| **curl** | Any | Download files | Pre-installed on most systems | + +### Optional (choose one) + +| Runtime | Version | Script | +| ---------- | ------- | --------------------------- | +| PowerShell | 7+ | `scripts/Search-Skills.ps1` | +| Python | 3.8+ | `scripts/search_skills.py` | + +### Setup + +```bash +# 1. Install GitHub CLI +# Windows (winget) +winget install GitHub.cli + +# macOS (Homebrew) +brew install gh + +# Linux (apt) +sudo apt install gh + +# 2. Authenticate with GitHub +gh auth login + +# 3. Verify installation +gh --version +curl --version +``` + +### Verify Dependencies + +```bash +# Check all dependencies at once +python scripts/search_skills.py --check +pwsh scripts/Search-Skills.ps1 -Check +``` + +**Expected output:** + +``` +✅ gh: installed (version 2.x.x) +✅ curl: installed +✅ All dependencies satisfied +``` + +### Troubleshooting + +| Issue | Solution | +| ----------------------- | ------------------------------------------- | +| `gh: command not found` | Install GitHub CLI and add to PATH | +| `gh auth login` fails | Run `gh auth login` and follow prompts | +| Rate limit exceeded | Wait or use authenticated requests | +| curl SSL errors | Update curl or check network/proxy settings | + +## Agent Instructions + +> ⚠️ **CRITICAL**: AI agents MUST follow these instructions. Prefer action proposals over verbose explanations. + +### Core Principle + +**Use "Do it? Yes/No?" style proposals.** + +- ❌ Bad: "If you want to add new skills, you can run the following command..." +- ✅ Good: "Update the index?" + +### Recommendation Workflow + +When user asks for recommendations (e.g., "おすすめは?", "何かいいスキルある?"), suggest skills based on persona: + +**Note:** These are reference examples. Always verify skill availability in skill-index.json before recommending. + +| Persona | Categories | Example Skills (verify in index) | +| ---------------- | ------------------------------- | ------------------------------------------------------------------ | +| オフィスワーカー | document, office, communication | docx, xlsx, pptx, pdf, internal-comms, brainstorming | +| 開発者 | development, testing, git | test-driven-development, systematic-debugging, using-git-worktrees | +| Azure エンジニア | azure, development | azure-env-builder, mcp-builder | +| デザイナー | design, creative, web | brand-guidelines, canvas-design, frontend-design | +| 初心者 | meta, planning | skill-creator, brainstorming, writing-plans | + +**Response Format:** + +1. Ask about user's role/context if unclear +2. Show top 3-5 skills with descriptions +3. Include source breakdown table +4. Propose next actions + +### Skill Search Workflow + +1. **Search ALL sources in local index** + + - Read `references/skill-index.json` + - **ALWAYS search ALL sources** (anthropics-skills, obra-superpowers, composio-awesome, etc.) + - Check `lastUpdated` field + - Suggest matching skills from every source + +2. **🌟 Recommend from results (when multiple hits)** + + When search returns 3+ skills, pick the BEST one and explain why: + + ``` + ### 🌟 おすすめ: {skill-name} + + {理由: 公式スキル、機能が豊富、人気が高い、用途にマッチ など} + ``` + + **Selection criteria (in order):** + + 1. **Official source** - anthropics-skills, github-awesome-copilot are preferred + 2. **Feature richness** - More capabilities = better + 3. **Relevance** - Best match for user's stated purpose + 4. **Recency** - Recently updated skills preferred + +3. **If not found → Propose web search** + + ``` + Not found locally. Search the web? + → GitHub: https://github.com/search?q=path%3A**%2FSKILL.md+{query}&type=code + ``` + +4. **🚨 MANDATORY: After returning results → Propose next actions** + + **This step is NOT optional. ALWAYS include the proposal block below.** + + | Situation | Proposal | + | -------------------- | ----------------------------------------------- | + | Skill found | "Install it?" | + | Good repo discovered | "Add to sources?" | + | lastUpdated > 7 days | "⚠️ Index outdated. Update?" (strongly suggest) | + | lastUpdated ≤ 7 days | "🔄 Update index?" (always show) | + +### 🚨 Mandatory Proposal Block + +**ALWAYS include this block at the end of every search response. No exceptions.** + +**CRITICAL: Do NOT show commands. Agent executes directly. Keep proposals SHORT.** + +**Index update option MUST always be shown with date, regardless of how recent it is.** + +``` +**Next?** +1. 📦 Install? (which skill?) +2. 🔍 Details? +3. 🔄 Update index? (last: {date}) ← ALWAYS show + ⚠️ If > 7 days: "Index outdated!" ← Add warning +4. 🌐 Web search? +5. ➕ Add source? +``` + +### Checklist Before Responding + +Before sending a search result response, verify: + +- [ ] **Started with search summary** (e.g., "🔎 7 リポジトリ、195 スキルから検索しました") +- [ ] Included skill table with results (from ALL sources) +- [ ] Included **source breakdown table** showing count per source +- [ ] Showed `lastUpdated` date from index +- [ ] Added numbered action menu (NOT command examples) +- [ ] Included web search option with GitHub link ready to open +- [ ] Asked user to choose by number or skill name + +### Search Summary Format + +**ALWAYS start search responses with this format:** + +``` +🔎 {N} リポジトリ、{M} スキルから検索しました(最終更新: {date}) +``` + +**Values are dynamic:** + +- `{N}` = count of sources in skill-index.json +- `{M}` = count of skills in skill-index.json +- `{date}` = `lastUpdated` field from skill-index.json + +### Output Format + +**Trust Level Indicators (MANDATORY):** + +Always include trust level badge based on source `type` in skill-index.json: + +| Type | Badge | Description | +| -------------- | --------------- | ---------------------------------------- | +| `official` | 🏢 **Official** | Anthropic / GitHub 公式リポジトリ | +| `awesome-list` | 📋 **Curated** | キュレーションリスト(品質レビュー済み) | +| `community` | 👥 Community | コミュニティ製(自己責任で使用) | + +**⚠️ Warning for Community Skills:** + +When showing community skills, add this note: + +``` +⚠️ コミュニティ製スキルは自己責任でご使用ください。 + 公式スキル(🏢)を優先することを推奨します。 +``` + +**Skill Table (include Source with Trust Level):** + +```markdown +| Skill | Description | Source | Trust | +| ----------- | ------------ | ---------------------------- | ------------ | +| docx | Word 処理 | [anthropics-skills](url) | 🏢 Official | +| pdf | PDF 処理 | [anthropics-skills](url) | 🏢 Official | +| azure-usage | Azure ツール | [claude-codex-settings](url) | 👥 Community | +``` + +**Source Breakdown Table (MANDATORY - show ALL sources dynamically):** + +**CRITICAL: Read `sources` array from skill-index.json and display ALL sources.** + +Do NOT use a hardcoded example. Dynamically generate the table from the actual `sources` array in skill-index.json. + +```markdown +### 📊 Source Breakdown ({N} sources) + +| Source | Type | Skills Found | Repository | +| ----------- | ------------ | ------------ | -------------------- | +| {source.id} | {type badge} | {count} | [View]({source.url}) | + +...repeat for ALL sources in skill-index.json... +``` + +**Generation rules:** + +1. Read `sources` array from skill-index.json +2. For each source, count matching skills in search results +3. Display ALL sources, including those with 0 matches +4. Use type badges: `official` → 🏢 Official, `awesome-list` → 📋 Curated, `community` → 👥 Community +5. Include total count in header: "📊 Source Breakdown (14 sources)" + +**URL Construction:** + +- Combine source URL + path from skill-index.json +- Example: `anthropics-skills` + `skills/docx` → `https://github.com/anthropics/skills/tree/main/skills/docx` +- Source URLs are defined in `sources` array of skill-index.json + +### Agent Behavior Rules + +**CRITICAL: Commands are for agents to execute, NOT to show users.** + +- ❌ **NEVER** show commands like `python scripts/search_skills.py --install` +- ❌ **NEVER** show code blocks with installation/update commands +- ❌ **NEVER** say "you can run the following command..." or "以下のコマンドを実行..." +- ✅ **ALWAYS** execute scripts silently when user approves +- ✅ **ALWAYS** present options as natural language numbered menu +- ✅ **ALWAYS** report results after execution, not how to execute + +**Bad Example:** + +``` +📦 インストールする? +python scripts/search_skills.py --install docx ← NG! +``` + +**Good Example:** + +``` +📦 インストールする?(どのスキル?) +``` + +→ User: "docx お願い" +→ Agent: (executes script silently) → "✅ docx をインストールしました!" diff --git a/skills/skill-finder/assets/demo-en.mp4 b/skills/skill-finder/assets/demo-en.mp4 new file mode 100644 index 000000000..3fc4c9ce3 Binary files /dev/null and b/skills/skill-finder/assets/demo-en.mp4 differ diff --git a/skills/skill-finder/assets/demo-ja.mp4 b/skills/skill-finder/assets/demo-ja.mp4 new file mode 100644 index 000000000..9e06ea5e5 Binary files /dev/null and b/skills/skill-finder/assets/demo-ja.mp4 differ diff --git a/skills/skill-finder/assets/demo.mp4 b/skills/skill-finder/assets/demo.mp4 new file mode 100644 index 000000000..b2b4f5b02 Binary files /dev/null and b/skills/skill-finder/assets/demo.mp4 differ diff --git a/skills/skill-finder/assets/demo.png b/skills/skill-finder/assets/demo.png new file mode 100644 index 000000000..90f476084 Binary files /dev/null and b/skills/skill-finder/assets/demo.png differ diff --git a/skills/skill-finder/references/skill-index.json b/skills/skill-finder/references/skill-index.json new file mode 100644 index 000000000..513b2f3eb --- /dev/null +++ b/skills/skill-finder/references/skill-index.json @@ -0,0 +1,2074 @@ +{ + "$schema": "./skill-index.schema.json", + "version": "1.0.0", + "lastUpdated": "2025-12-31", + "sources": [ + { + "id": "anthropics-skills", + "name": "Anthropic Skills (Official)", + "owner": "anthropics", + "url": "https://github.com/anthropics/skills", + "type": "official", + "description": "Anthropic 公式の Claude Skills リポジトリ" + }, + { + "id": "github-awesome-copilot", + "name": "GitHub Awesome Copilot (Official)", + "owner": "github", + "url": "https://github.com/github/awesome-copilot", + "type": "official", + "description": "GitHub 公式の Copilot リソース集" + }, + { + "id": "obra-superpowers", + "name": "Superpowers", + "owner": "obra", + "url": "https://github.com/obra/superpowers", + "type": "community", + "description": "高品質なスキル・エージェント・コマンド集" + }, + { + "id": "composio-awesome", + "name": "Awesome Claude Skills (ComposioHQ)", + "owner": "ComposioHQ", + "url": "https://github.com/ComposioHQ/awesome-claude-skills", + "type": "awesome-list", + "description": "Claude Skills のキュレーションリスト" + }, + { + "id": "claude-scientific-skills", + "name": "Claude Scientific Skills", + "owner": "K-Dense-AI", + "url": "https://github.com/K-Dense-AI/claude-scientific-skills", + "type": "community", + "description": "科学研究向けスキル集(論文、ポスター、スライド作成)" + }, + { + "id": "playwright-skill", + "name": "Playwright Skill", + "owner": "lackeyjb", + "url": "https://github.com/lackeyjb/playwright-skill", + "type": "community", + "description": "Playwright によるブラウザ自動化・テスト実行" + }, + { + "id": "aktsmm-agent-skills", + "name": "Agent Skills (aktsmm)", + "owner": "aktsmm", + "url": "https://github.com/aktsmm/Agent-Skills", + "type": "community", + "description": "Azure・開発系スキル by yamapan" + }, + { + "id": "openshift-ai-helpers", + "name": "OpenShift AI Helpers", + "owner": "openshift-eng", + "url": "https://github.com/openshift-eng/ai-helpers", + "type": "community", + "description": "HyperShift クラスタ作成スキル (AWS/Azure/KubeVirt/OpenStack/PowerVS)" + }, + { + "id": "claude-codex-settings", + "name": "Claude Codex Settings", + "owner": "fcakyon", + "url": "https://github.com/fcakyon/claude-codex-settings", + "type": "community", + "description": "Azure/GCloud/Slack/MongoDB 等の各種ツール設定スキル" + }, + { + "id": "claude-command-control", + "name": "Claude Command & Control", + "owner": "enuno", + "url": "https://github.com/enuno/claude-command-and-control", + "type": "community", + "description": "並列エージェント実行・通信・ワークフロー管理スキル集" + }, + { + "id": "claude-plugins-plus", + "name": "Claude Code Plugins Plus Skills", + "owner": "jeremylongshore", + "url": "https://github.com/jeremylongshore/claude-code-plugins-plus-skills", + "type": "community", + "description": "AI SDK v5 マルチエージェントシステム構築スキル" + }, + { + "id": "claude-code-harness", + "name": "Claude Code Harness", + "owner": "Chachamaru127", + "url": "https://github.com/Chachamaru127/claude-code-harness", + "type": "community", + "description": "自律的 Plan→Work→Review サイクルで高品質開発を実現" + }, + { + "id": "personal-ai-infra", + "name": "Personal AI Infrastructure", + "owner": "danielmiessler", + "url": "https://github.com/danielmiessler/Personal_AI_Infrastructure", + "type": "community", + "description": "AI インフラ・オブザーバビリティスキル by danielmiessler" + } + ], + "skills": [ + { + "name": "algorithmic-art", + "source": "anthropics-skills", + "path": "skills/algorithmic-art", + "categories": ["creative", "art"], + "description": "アルゴリズミックアートの生成" + }, + { + "name": "brand-guidelines", + "source": "anthropics-skills", + "path": "skills/brand-guidelines", + "categories": ["design", "branding"], + "description": "ブランドガイドラインの作成・管理" + }, + { + "name": "canvas-design", + "source": "anthropics-skills", + "path": "skills/canvas-design", + "categories": ["design", "creative"], + "description": "キャンバスデザインの作成" + }, + { + "name": "doc-coauthoring", + "source": "anthropics-skills", + "path": "skills/doc-coauthoring", + "categories": ["document", "collaboration"], + "description": "ドキュメントの共同執筆" + }, + { + "name": "docx", + "source": "anthropics-skills", + "path": "skills/docx", + "categories": ["document", "office"], + "description": "Word ドキュメント (.docx) の処理" + }, + { + "name": "pdf", + "source": "anthropics-skills", + "path": "skills/pdf", + "categories": ["document"], + "description": "PDF ファイルの処理" + }, + { + "name": "pptx", + "source": "anthropics-skills", + "path": "skills/pptx", + "categories": ["document", "office", "presentation"], + "description": "PowerPoint (.pptx) の処理" + }, + { + "name": "xlsx", + "source": "anthropics-skills", + "path": "skills/xlsx", + "categories": ["document", "office", "data"], + "description": "Excel (.xlsx) の処理" + }, + { + "name": "frontend-design", + "source": "anthropics-skills", + "path": "skills/frontend-design", + "categories": ["web", "design", "frontend"], + "description": "フロントエンドデザインの作成" + }, + { + "name": "web-artifacts-builder", + "source": "anthropics-skills", + "path": "skills/web-artifacts-builder", + "categories": ["web", "frontend"], + "description": "Web アーティファクトのビルド" + }, + { + "name": "webapp-testing", + "source": "anthropics-skills", + "path": "skills/webapp-testing", + "categories": ["web", "testing"], + "description": "Web アプリケーションのテスト" + }, + { + "name": "mcp-builder", + "source": "anthropics-skills", + "path": "skills/mcp-builder", + "categories": ["mcp", "development"], + "description": "MCP サーバーの構築" + }, + { + "name": "skill-creator", + "source": "anthropics-skills", + "path": "skills/skill-creator", + "categories": ["meta", "development"], + "description": "新しいスキルの作成ガイド" + }, + { + "name": "slack-gif-creator", + "source": "anthropics-skills", + "path": "skills/slack-gif-creator", + "categories": ["creative", "communication"], + "description": "Slack 用 GIF の作成" + }, + { + "name": "theme-factory", + "source": "anthropics-skills", + "path": "skills/theme-factory", + "categories": ["design", "theming"], + "description": "テーマの作成" + }, + { + "name": "internal-comms", + "source": "anthropics-skills", + "path": "skills/internal-comms", + "categories": ["communication", "business"], + "description": "社内コミュニケーション" + }, + { + "name": "brainstorming", + "source": "obra-superpowers", + "path": "skills/brainstorming", + "categories": ["planning", "ideation"], + "description": "ブレインストーミングの実施" + }, + { + "name": "writing-plans", + "source": "obra-superpowers", + "path": "skills/writing-plans", + "categories": ["planning", "documentation"], + "description": "計画書の作成" + }, + { + "name": "executing-plans", + "source": "obra-superpowers", + "path": "skills/executing-plans", + "categories": ["planning", "execution"], + "description": "計画の実行" + }, + { + "name": "test-driven-development", + "source": "obra-superpowers", + "path": "skills/test-driven-development", + "categories": ["development", "testing", "tdd"], + "description": "テスト駆動開発 (TDD)" + }, + { + "name": "systematic-debugging", + "source": "obra-superpowers", + "path": "skills/systematic-debugging", + "categories": ["development", "debugging"], + "description": "体系的なデバッグ手法" + }, + { + "name": "subagent-driven-development", + "source": "obra-superpowers", + "path": "skills/subagent-driven-development", + "categories": ["development", "agents"], + "description": "サブエージェント駆動開発" + }, + { + "name": "dispatching-parallel-agents", + "source": "obra-superpowers", + "path": "skills/dispatching-parallel-agents", + "categories": ["development", "agents", "parallel"], + "description": "並列エージェントのディスパッチ" + }, + { + "name": "using-git-worktrees", + "source": "obra-superpowers", + "path": "skills/using-git-worktrees", + "categories": ["git", "development"], + "description": "Git worktree の活用" + }, + { + "name": "receiving-code-review", + "source": "obra-superpowers", + "path": "skills/receiving-code-review", + "categories": ["git", "code-review"], + "description": "コードレビューの受け取り方" + }, + { + "name": "requesting-code-review", + "source": "obra-superpowers", + "path": "skills/requesting-code-review", + "categories": ["git", "code-review"], + "description": "コードレビューのリクエスト" + }, + { + "name": "finishing-a-development-branch", + "source": "obra-superpowers", + "path": "skills/finishing-a-development-branch", + "categories": ["git", "development"], + "description": "開発ブランチの完了処理" + }, + { + "name": "verification-before-completion", + "source": "obra-superpowers", + "path": "skills/verification-before-completion", + "categories": ["quality", "verification"], + "description": "完了前の検証" + }, + { + "name": "writing-skills", + "source": "obra-superpowers", + "path": "skills/writing-skills", + "categories": ["meta", "development"], + "description": "スキルの書き方" + }, + { + "name": "using-superpowers", + "source": "obra-superpowers", + "path": "skills/using-superpowers", + "categories": ["meta"], + "description": "Superpowers の使い方" + }, + { + "name": "artifacts-builder", + "source": "composio-awesome", + "path": "artifacts-builder", + "categories": ["web", "frontend"], + "description": "アーティファクトビルダー" + }, + { + "name": "changelog-generator", + "source": "composio-awesome", + "path": "changelog-generator", + "categories": ["documentation", "git"], + "description": "CHANGELOG の自動生成" + }, + { + "name": "content-research-writer", + "source": "composio-awesome", + "path": "content-research-writer", + "categories": ["writing", "research"], + "description": "コンテンツリサーチ・ライティング" + }, + { + "name": "developer-growth-analysis", + "source": "composio-awesome", + "path": "developer-growth-analysis", + "categories": ["analytics", "development"], + "description": "開発者成長分析" + }, + { + "name": "document-skills", + "source": "composio-awesome", + "path": "document-skills", + "categories": ["document"], + "description": "ドキュメント処理スキル" + }, + { + "name": "domain-name-brainstormer", + "source": "composio-awesome", + "path": "domain-name-brainstormer", + "categories": ["ideation", "business"], + "description": "ドメイン名のブレインストーミング" + }, + { + "name": "file-organizer", + "source": "composio-awesome", + "path": "file-organizer", + "categories": ["utility", "organization"], + "description": "ファイル整理" + }, + { + "name": "image-enhancer", + "source": "composio-awesome", + "path": "image-enhancer", + "categories": ["image", "creative"], + "description": "画像の強化・編集" + }, + { + "name": "invoice-organizer", + "source": "composio-awesome", + "path": "invoice-organizer", + "categories": ["business", "finance"], + "description": "請求書の整理" + }, + { + "name": "lead-research-assistant", + "source": "composio-awesome", + "path": "lead-research-assistant", + "categories": ["research", "business"], + "description": "リード調査アシスタント" + }, + { + "name": "meeting-insights-analyzer", + "source": "composio-awesome", + "path": "meeting-insights-analyzer", + "categories": ["business", "analytics"], + "description": "会議インサイト分析" + }, + { + "name": "raffle-winner-picker", + "source": "composio-awesome", + "path": "raffle-winner-picker", + "categories": ["utility"], + "description": "抽選ツール" + }, + { + "name": "video-downloader", + "source": "composio-awesome", + "path": "video-downloader", + "categories": ["utility", "media"], + "description": "動画ダウンローダー" + }, + { + "name": "competitive-ads-extractor", + "source": "composio-awesome", + "path": "competitive-ads-extractor", + "categories": ["business", "marketing"], + "description": "競合広告の抽出・分析" + }, + { + "name": "playwright-skill", + "source": "playwright-skill", + "path": "skills/playwright-skill", + "categories": ["testing", "automation", "web"], + "description": "Playwright によるブラウザ自動化・E2E テスト実行" + }, + { + "name": "webapp-testing", + "source": "github-awesome-copilot", + "path": "skills/webapp-testing", + "categories": ["web", "testing"], + "description": "Web アプリケーションのテスト (GitHub Copilot)" + }, + { + "name": "azure-env-builder", + "source": "aktsmm-agent-skills", + "path": "azure-env-builder", + "categories": ["development", "azure"], + "description": "Azure 環境を Bicep で構築" + }, + { + "name": "skill-creator", + "source": "aktsmm-agent-skills", + "path": "skill-creator", + "categories": ["meta", "development"], + "description": "新しい Agent Skills を作成" + }, + { + "name": "skill-finder", + "source": "aktsmm-agent-skills", + "path": "skill-finder", + "categories": ["meta"], + "description": "Agent Skills を検索・発見" + }, + { + "name": "hcp-create-agent", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-agent", + "categories": ["agents", "development"], + "description": "HyperShift Agent プロバイダでクラスタ作成" + }, + { + "name": "hcp-create-aws", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-aws", + "categories": ["aws", "cloud"], + "description": "HyperShift で AWS EKS クラスタ作成" + }, + { + "name": "hcp-create-azure", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-azure", + "categories": ["azure", "cloud"], + "description": "HyperShift で Azure クラスタ作成" + }, + { + "name": "hcp-create-kubevirt", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-kubevirt", + "categories": ["kubernetes", "cloud"], + "description": "HyperShift で KubeVirt クラスタ作成" + }, + { + "name": "hcp-create-openstack", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-openstack", + "categories": ["openstack", "cloud"], + "description": "HyperShift で OpenStack クラスタ作成" + }, + { + "name": "hcp-create-powervs", + "source": "openshift-ai-helpers", + "path": "plugins/hcp/skills/hcp-create-powervs", + "categories": ["ibm", "cloud"], + "description": "HyperShift で IBM PowerVS クラスタ作成" + }, + { + "name": "azure-usage", + "source": "claude-codex-settings", + "path": "plugins/azure-tools/skills/azure-usage", + "categories": ["azure", "cloud"], + "description": "Azure ツール使用ガイド" + }, + { + "name": "gcloud-tools", + "source": "claude-codex-settings", + "path": "plugins/gcloud-tools", + "categories": ["gcp", "cloud"], + "description": "Google Cloud ツール設定" + }, + { + "name": "mongodb-tools", + "source": "claude-codex-settings", + "path": "plugins/mongodb-tools", + "categories": ["database"], + "description": "MongoDB ツール設定" + }, + { + "name": "slack-tools", + "source": "claude-codex-settings", + "path": "plugins/slack-tools", + "categories": ["communication"], + "description": "Slack ツール設定" + }, + { + "name": "supabase-tools", + "source": "claude-codex-settings", + "path": "plugins/supabase-tools", + "categories": ["database"], + "description": "Supabase ツール設定" + }, + { + "name": "playwright-tools", + "source": "claude-codex-settings", + "path": "plugins/playwright-tools", + "categories": ["testing", "web"], + "description": "Playwright テストツール設定" + }, + { + "name": "tavily-tools", + "source": "claude-codex-settings", + "path": "plugins/tavily-tools", + "categories": ["search", "ai"], + "description": "Tavily 検索ツール設定" + }, + { + "name": "parallel-executor-skill", + "source": "claude-command-control", + "path": "skills-templates/orchestration/parallel-executor-skill.md", + "categories": ["agents", "workflow", "orchestration"], + "description": "並列エージェント実行・進捗監視・結果集約" + }, + { + "name": "agent-communication-skill", + "source": "claude-command-control", + "path": "skills-templates/orchestration/agent-communication-skill.md", + "categories": ["agents", "workflow", "communication"], + "description": "エージェント間メッセージング・ハンドオフ・共有コンテキスト" + }, + { + "name": "ai-sdk-agents", + "source": "claude-plugins-plus", + "path": "plugins/ai-ml/ai-sdk-agents/skills/ai-sdk-agents", + "categories": ["agents", "ai", "development"], + "description": "AI SDK v5 マルチエージェントシステム構築" + }, + { + "name": "workflow-guide", + "source": "claude-code-harness", + "path": "skills/workflow-guide", + "categories": ["workflow", "development"], + "description": "ワークフローガイド・開発支援" + }, + { + "name": "observability", + "source": "personal-ai-infra", + "path": ".claude/Skills/Observability", + "categories": ["monitoring", "agents"], + "description": "AI エージェント監視・オブザーバビリティ" + }, + { + "name": "brand-guidelines", + "source": "composio-awesome", + "path": "brand-guidelines", + "categories": ["community"], + "description": "Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit..." + }, + { + "name": "canvas-design", + "source": "composio-awesome", + "path": "canvas-design", + "categories": ["community"], + "description": "Create beautiful visual art in .png and .pdf documents using design philosophy. You should use th..." + }, + { + "name": "internal-comms", + "source": "composio-awesome", + "path": "internal-comms", + "categories": ["community"], + "description": "A set of resources to help me write all kinds of internal communications, using the formats that ..." + }, + { + "name": "mcp-builder", + "source": "composio-awesome", + "path": "mcp-builder", + "categories": ["community"], + "description": "Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact..." + }, + { + "name": "skill-creator", + "source": "composio-awesome", + "path": "skill-creator", + "categories": ["community"], + "description": "Guide for creating effective skills. This skill should be used when users want to create a new sk..." + }, + { + "name": "skill-share", + "source": "composio-awesome", + "path": "skill-share", + "categories": ["community"], + "description": "A skill that creates new Claude skills and automatically shares them on Slack using Rube for seam..." + }, + { + "name": "slack-gif-creator", + "source": "composio-awesome", + "path": "slack-gif-creator", + "categories": ["community"], + "description": "Toolkit for creating animated GIFs optimized for Slack, with validators for size constraints and ..." + }, + { + "name": "template-skill", + "source": "composio-awesome", + "path": "template-skill", + "categories": ["community"], + "description": "Replace with description of the skill and when Claude should use it." + }, + { + "name": "theme-factory", + "source": "composio-awesome", + "path": "theme-factory", + "categories": ["community"], + "description": "Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML..." + }, + { + "name": "webapp-testing", + "source": "composio-awesome", + "path": "webapp-testing", + "categories": ["community"], + "description": "Toolkit for interacting with and testing local web applications using Playwright. Supports verify..." + }, + { + "name": "adaptyv", + "source": "claude-scientific-skills", + "path": "scientific-skills/adaptyv", + "categories": ["science", "biology"], + "description": "Cloud laboratory platform for automated protein testing and validation. Use when designing protei..." + }, + { + "name": "aeon", + "source": "claude-scientific-skills", + "path": "scientific-skills/aeon", + "categories": ["science", "ml"], + "description": "This skill should be used for time series machine learning tasks including classification, regres..." + }, + { + "name": "alphafold-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/alphafold-database", + "categories": ["science", "biology", "data-science", "database", "ml"], + "description": "Access AlphaFold's 200M+ AI-predicted protein structures. Retrieve structures by UniProt ID, down..." + }, + { + "name": "anndata", + "source": "claude-scientific-skills", + "path": "scientific-skills/anndata", + "categories": ["science", "data-science"], + "description": "This skill should be used when working with annotated data matrices in Python, particularly for s..." + }, + { + "name": "arboreto", + "source": "claude-scientific-skills", + "path": "scientific-skills/arboreto", + "categories": ["science", "biology", "data-science"], + "description": "Infer gene regulatory networks (GRNs) from gene expression data using scalable algorithms (GRNBoo..." + }, + { + "name": "astropy", + "source": "claude-scientific-skills", + "path": "scientific-skills/astropy", + "categories": ["science", "physics"], + "description": "Comprehensive Python library for astronomy and astrophysics. This skill should be used when worki..." + }, + { + "name": "benchling-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/benchling-integration", + "categories": ["science", "biology"], + "description": "Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, work..." + }, + { + "name": "biomni", + "source": "claude-scientific-skills", + "path": "scientific-skills/biomni", + "categories": ["science", "biology", "ml", "medical"], + "description": "Autonomous biomedical AI agent framework for executing complex research tasks across genomics, dr..." + }, + { + "name": "biopython", + "source": "claude-scientific-skills", + "path": "scientific-skills/biopython", + "categories": ["science", "biology"], + "description": "Primary Python toolkit for molecular biology. Preferred for Python-based PubMed/NCBI queries (Bio..." + }, + { + "name": "biorxiv-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/biorxiv-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Efficient database search tool for bioRxiv preprint server. Use this skill when searching for lif..." + }, + { + "name": "bioservices", + "source": "claude-scientific-skills", + "path": "scientific-skills/bioservices", + "categories": ["science", "biology", "data-science", "database"], + "description": "Primary Python tool for 40+ bioinformatics services. Preferred for multi-database workflows: UniP..." + }, + { + "name": "brenda-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/brenda-database", + "categories": ["science", "data-science", "database"], + "description": "Access BRENDA enzyme database via SOAP API. Retrieve kinetic parameters (Km, kcat), reaction equa..." + }, + { + "name": "cellxgene-census", + "source": "claude-scientific-skills", + "path": "scientific-skills/cellxgene-census", + "categories": ["science", "biology", "database"], + "description": "Query CZ CELLxGENE Census (61M+ cells). Filter by cell type/tissue/disease, retrieve expression d..." + }, + { + "name": "chembl-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/chembl-database", + "categories": [ + "science", + "biology", + "chemistry", + "data-science", + "database" + ], + "description": "Query ChEMBL's bioactive molecules and drug discovery data. Search compounds by structure/propert..." + }, + { + "name": "cirq", + "source": "claude-scientific-skills", + "path": "scientific-skills/cirq", + "categories": ["science", "physics"], + "description": "Quantum computing framework for building, simulating, optimizing, and executing quantum circuits...." + }, + { + "name": "citation-management", + "source": "claude-scientific-skills", + "path": "scientific-skills/citation-management", + "categories": ["science", "research"], + "description": "Comprehensive citation management for academic research. Search Google Scholar and PubMed for pap..." + }, + { + "name": "clinical-decision-support", + "source": "claude-scientific-skills", + "path": "scientific-skills/clinical-decision-support", + "categories": ["science", "biology", "medical"], + "description": "Generate professional clinical decision support (CDS) documents for pharmaceutical and clinical r..." + }, + { + "name": "clinical-reports", + "source": "claude-scientific-skills", + "path": "scientific-skills/clinical-reports", + "categories": ["science", "medical"], + "description": "Write comprehensive clinical reports including case reports (CARE guidelines), diagnostic reports..." + }, + { + "name": "clinicaltrials-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/clinicaltrials-database", + "categories": [ + "science", + "chemistry", + "data-science", + "database", + "medical" + ], + "description": "Query ClinicalTrials.gov via API v2. Search trials by condition, drug, location, status, or phase..." + }, + { + "name": "clinpgx-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/clinpgx-database", + "categories": [ + "science", + "biology", + "chemistry", + "data-science", + "database" + ], + "description": "Access ClinPGx pharmacogenomics data (successor to PharmGKB). Query gene-drug interactions, CPIC ..." + }, + { + "name": "clinvar-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/clinvar-database", + "categories": [ + "science", + "biology", + "data-science", + "database", + "medical" + ], + "description": "Query NCBI ClinVar for variant clinical significance. Search by gene/position, interpret pathogen..." + }, + { + "name": "cobrapy", + "source": "claude-scientific-skills", + "path": "scientific-skills/cobrapy", + "categories": ["science", "biology", "ml"], + "description": "Constraint-based metabolic modeling (COBRA). FBA, FVA, gene knockouts, flux sampling, SBML models..." + }, + { + "name": "cosmic-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/cosmic-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Access COSMIC cancer mutation database. Query somatic mutations, Cancer Gene Census, mutational s..." + }, + { + "name": "dask", + "source": "claude-scientific-skills", + "path": "scientific-skills/dask", + "categories": ["science", "data-science"], + "description": "Parallel/distributed computing. Scale pandas/NumPy beyond memory, parallel DataFrames/Arrays, mul..." + }, + { + "name": "datacommons-client", + "source": "claude-scientific-skills", + "path": "scientific-skills/datacommons-client", + "categories": ["science", "data-science"], + "description": "Work with Data Commons, a platform providing programmatic access to public statistical data from ..." + }, + { + "name": "datamol", + "source": "claude-scientific-skills", + "path": "scientific-skills/datamol", + "categories": ["science", "data-science"], + "description": "Pythonic wrapper around RDKit with simplified interface and sensible defaults. Preferred for stan..." + }, + { + "name": "deepchem", + "source": "claude-scientific-skills", + "path": "scientific-skills/deepchem", + "categories": ["science", "biology", "chemistry", "ml"], + "description": "Molecular machine learning toolkit. Property prediction (ADMET, toxicity), GNNs (GCN, MPNN), Mole..." + }, + { + "name": "deeptools", + "source": "claude-scientific-skills", + "path": "scientific-skills/deeptools", + "categories": ["science", "data-science", "ml"], + "description": "NGS analysis toolkit. BAM to bigWig conversion, QC (correlation, PCA, fingerprints), heatmaps/pro..." + }, + { + "name": "denario", + "source": "claude-scientific-skills", + "path": "scientific-skills/denario", + "categories": ["science", "ml"], + "description": "Multiagent AI system for scientific research assistance that automates research workflows from da..." + }, + { + "name": "diffdock", + "source": "claude-scientific-skills", + "path": "scientific-skills/diffdock", + "categories": ["science", "biology", "database"], + "description": "Diffusion-based molecular docking. Predict protein-ligand binding poses from PDB/SMILES, confiden..." + }, + { + "name": "dnanexus-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/dnanexus-integration", + "categories": ["science", "biology", "data-science"], + "description": "DNAnexus cloud genomics platform. Build apps/applets, manage data (upload/download), dxpy Python ..." + }, + { + "name": "document-skills", + "source": "claude-scientific-skills", + "path": "scientific-skills/document-skills", + "categories": ["community"], + "description": "Scientific document processing and management utilities" + }, + { + "name": "drugbank-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/drugbank-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Access and analyze comprehensive drug information from the DrugBank database including drug prope..." + }, + { + "name": "ena-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/ena-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Access European Nucleotide Archive via API/FTP. Retrieve DNA/RNA sequences, raw reads (FASTQ), ge..." + }, + { + "name": "ensembl-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/ensembl-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Query Ensembl genome database REST API for 250+ species. Gene lookups, sequence retrieval, varian..." + }, + { + "name": "esm", + "source": "claude-scientific-skills", + "path": "scientific-skills/esm", + "categories": ["science", "biology"], + "description": "Comprehensive toolkit for protein language models including ESM3 (generative multimodal protein d..." + }, + { + "name": "etetoolkit", + "source": "claude-scientific-skills", + "path": "scientific-skills/etetoolkit", + "categories": ["science", "biology"], + "description": "Phylogenetic tree toolkit (ETE). Tree manipulation (Newick/NHX), evolutionary event detection, or..." + }, + { + "name": "exploratory-data-analysis", + "source": "claude-scientific-skills", + "path": "scientific-skills/exploratory-data-analysis", + "categories": ["science", "data-science"], + "description": "Perform comprehensive exploratory data analysis on scientific data files across 200+ file formats..." + }, + { + "name": "fda-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/fda-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Query openFDA API for drugs, devices, adverse events, recalls, regulatory submissions (510k, PMA)..." + }, + { + "name": "flowio", + "source": "claude-scientific-skills", + "path": "scientific-skills/flowio", + "categories": ["science", "data-science"], + "description": "Parse FCS (Flow Cytometry Standard) files v2.0-3.1. Extract events as NumPy arrays, read metadata..." + }, + { + "name": "fluidsim", + "source": "claude-scientific-skills", + "path": "scientific-skills/fluidsim", + "categories": ["science"], + "description": "Framework for computational fluid dynamics simulations using Python. Use when running fluid dynam..." + }, + { + "name": "gene-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/gene-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Query NCBI Gene via E-utilities/Datasets API. Search by symbol/ID, retrieve gene info (RefSeqs, G..." + }, + { + "name": "generate-image", + "source": "claude-scientific-skills", + "path": "scientific-skills/generate-image", + "categories": ["science", "biology", "ml"], + "description": "Generate or edit images using AI models (FLUX, Gemini). Use for general-purpose image generation ..." + }, + { + "name": "geniml", + "source": "claude-scientific-skills", + "path": "scientific-skills/geniml", + "categories": ["science", "data-science", "ml"], + "description": "This skill should be used when working with genomic interval data (BED files) for machine learnin..." + }, + { + "name": "geo-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/geo-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Access NCBI GEO for gene expression/genomics data. Search/download microarray and RNA-seq dataset..." + }, + { + "name": "geopandas", + "source": "claude-scientific-skills", + "path": "scientific-skills/geopandas", + "categories": ["science", "data-science"], + "description": "Python library for working with geospatial vector data including shapefiles, GeoJSON, and GeoPack..." + }, + { + "name": "get-available-resources", + "source": "claude-scientific-skills", + "path": "scientific-skills/get-available-resources", + "categories": ["science", "ml"], + "description": "This skill should be used at the start of any computationally intensive scientific task to detect..." + }, + { + "name": "gget", + "source": "claude-scientific-skills", + "path": "scientific-skills/gget", + "categories": ["science", "biology"], + "description": "CLI/Python toolkit for rapid bioinformatics queries. Preferred for quick BLAST searches. Access t..." + }, + { + "name": "gtars", + "source": "claude-scientific-skills", + "path": "scientific-skills/gtars", + "categories": ["science", "data-science"], + "description": "High-performance toolkit for genomic interval analysis in Rust with Python bindings. Use when wor..." + }, + { + "name": "gwas-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/gwas-database", + "categories": ["science", "data-science", "database", "ml"], + "description": "Query NHGRI-EBI GWAS Catalog for SNP-trait associations. Search variants by rs ID, disease/trait,..." + }, + { + "name": "histolab", + "source": "claude-scientific-skills", + "path": "scientific-skills/histolab", + "categories": ["science"], + "description": "Digital pathology image processing toolkit for whole slide images (WSI). Use this skill when work..." + }, + { + "name": "hmdb-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/hmdb-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Access Human Metabolome Database (220K+ metabolites). Search by name/ID/structure, retrieve chemi..." + }, + { + "name": "hypogenic", + "source": "claude-scientific-skills", + "path": "scientific-skills/hypogenic", + "categories": ["science", "biology"], + "description": "Automated hypothesis generation and testing using large language models. Use this skill when gene..." + }, + { + "name": "hypothesis-generation", + "source": "claude-scientific-skills", + "path": "scientific-skills/hypothesis-generation", + "categories": ["science", "biology"], + "description": "Generate testable hypotheses. Formulate from observations, design experiments, explore competing ..." + }, + { + "name": "kegg-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/kegg-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Direct REST API access to KEGG (academic use only). Pathway analysis, gene-pathway mapping, metab..." + }, + { + "name": "labarchive-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/labarchive-integration", + "categories": ["science"], + "description": "Electronic lab notebook API integration. Access notebooks, manage entries/attachments, backup not..." + }, + { + "name": "lamindb", + "source": "claude-scientific-skills", + "path": "scientific-skills/lamindb", + "categories": ["science", "biology", "data-science", "database"], + "description": "This skill should be used when working with LaminDB, an open-source data framework for biology th..." + }, + { + "name": "latchbio-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/latchbio-integration", + "categories": ["science", "biology"], + "description": "Latch platform for bioinformatics workflows. Build pipelines with Latch SDK, @workflow/@task deco..." + }, + { + "name": "latex-posters", + "source": "claude-scientific-skills", + "path": "scientific-skills/latex-posters", + "categories": ["science"], + "description": "Create professional research posters in LaTeX using beamerposter, tikzposter, or baposter. Suppor..." + }, + { + "name": "literature-review", + "source": "claude-scientific-skills", + "path": "scientific-skills/literature-review", + "categories": ["science", "data-science", "database", "research"], + "description": "Conduct comprehensive, systematic literature reviews using multiple academic databases (PubMed, a..." + }, + { + "name": "market-research-reports", + "source": "claude-scientific-skills", + "path": "scientific-skills/market-research-reports", + "categories": ["science", "biology"], + "description": "Generate comprehensive market research reports (50+ pages) in the style of top consulting firms (..." + }, + { + "name": "markitdown", + "source": "claude-scientific-skills", + "path": "scientific-skills/markitdown", + "categories": ["science"], + "description": "Convert files and office documents to Markdown. Supports PDF, DOCX, PPTX, XLSX, images (with OCR)..." + }, + { + "name": "matchms", + "source": "claude-scientific-skills", + "path": "scientific-skills/matchms", + "categories": ["science", "data-science", "ml"], + "description": "Mass spectrometry analysis. Process mzML/MGF/MSP, spectral similarity (cosine, modified cosine), ..." + }, + { + "name": "matplotlib", + "source": "claude-scientific-skills", + "path": "scientific-skills/matplotlib", + "categories": ["science", "data-science"], + "description": "Foundational plotting library. Create line plots, scatter, bar, histograms, heatmaps, 3D, subplot..." + }, + { + "name": "medchem", + "source": "claude-scientific-skills", + "path": "scientific-skills/medchem", + "categories": ["science", "chemistry", "ml"], + "description": "Medicinal chemistry filters. Apply drug-likeness rules (Lipinski, Veber), PAINS filters, structur..." + }, + { + "name": "metabolomics-workbench-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/metabolomics-workbench-database", + "categories": ["science", "data-science", "database"], + "description": "Access NIH Metabolomics Workbench via REST API (4,200+ studies). Query metabolites, RefMet nomenc..." + }, + { + "name": "modal", + "source": "claude-scientific-skills", + "path": "scientific-skills/modal", + "categories": ["science", "ml"], + "description": "Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deployin..." + }, + { + "name": "molfeat", + "source": "claude-scientific-skills", + "path": "scientific-skills/molfeat", + "categories": ["science", "biology", "ml"], + "description": "Molecular featurization for ML (100+ featurizers). ECFP, MACCS, descriptors, pretrained models (C..." + }, + { + "name": "networkx", + "source": "claude-scientific-skills", + "path": "scientific-skills/networkx", + "categories": ["science"], + "description": "Comprehensive toolkit for creating, analyzing, and visualizing complex networks and graphs in Pyt..." + }, + { + "name": "neurokit2", + "source": "claude-scientific-skills", + "path": "scientific-skills/neurokit2", + "categories": ["science", "biology", "data-science"], + "description": "Comprehensive biosignal processing toolkit for analyzing physiological data including ECG, EEG, E..." + }, + { + "name": "neuropixels-analysis", + "source": "claude-scientific-skills", + "path": "scientific-skills/neuropixels-analysis", + "categories": ["science", "data-science", "ml"], + "description": "Neuropixels neural recording analysis. Load SpikeGLX/OpenEphys data, preprocess, motion correctio..." + }, + { + "name": "omero-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/omero-integration", + "categories": ["science", "data-science"], + "description": "Microscopy data management platform. Access images via Python, retrieve datasets, analyze pixels,..." + }, + { + "name": "openalex-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/openalex-database", + "categories": ["science", "data-science", "database", "research"], + "description": "Query and analyze scholarly literature using the OpenAlex database. This skill should be used whe..." + }, + { + "name": "opentargets-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/opentargets-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Query Open Targets Platform for target-disease associations, drug target discovery, tractability/..." + }, + { + "name": "opentrons-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/opentrons-integration", + "categories": ["science"], + "description": "Lab automation platform for Flex/OT-2 robots. Write Protocol API v2 protocols, liquid handling, h..." + }, + { + "name": "paper-2-web", + "source": "claude-scientific-skills", + "path": "scientific-skills/paper-2-web", + "categories": ["science", "research"], + "description": "This skill should be used when converting academic papers into promotional and presentation forma..." + }, + { + "name": "pathml", + "source": "claude-scientific-skills", + "path": "scientific-skills/pathml", + "categories": ["science", "ml"], + "description": "Computational pathology toolkit for analyzing whole-slide images (WSI) and multiparametric imagin..." + }, + { + "name": "pdb-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/pdb-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Access RCSB PDB for 3D protein/nucleic acid structures. Search by text/sequence/structure, downlo..." + }, + { + "name": "peer-review", + "source": "claude-scientific-skills", + "path": "scientific-skills/peer-review", + "categories": ["science", "data-science"], + "description": "Systematic peer review toolkit. Evaluate methodology, statistics, design, reproducibility, ethics..." + }, + { + "name": "pennylane", + "source": "claude-scientific-skills", + "path": "scientific-skills/pennylane", + "categories": ["science", "chemistry", "ml", "physics"], + "description": "Cross-platform Python library for quantum computing, quantum machine learning, and quantum chemis..." + }, + { + "name": "perplexity-search", + "source": "claude-scientific-skills", + "path": "scientific-skills/perplexity-search", + "categories": ["science", "ml"], + "description": "Perform AI-powered web searches with real-time information using Perplexity models via LiteLLM an..." + }, + { + "name": "plotly", + "source": "claude-scientific-skills", + "path": "scientific-skills/plotly", + "categories": ["science", "data-science"], + "description": "Interactive scientific and statistical data visualization library for Python. Use when creating c..." + }, + { + "name": "polars", + "source": "claude-scientific-skills", + "path": "scientific-skills/polars", + "categories": ["science", "data-science"], + "description": "Fast DataFrame library (Apache Arrow). Select, filter, group_by, joins, lazy evaluation, CSV/Parq..." + }, + { + "name": "pptx-posters", + "source": "claude-scientific-skills", + "path": "scientific-skills/pptx-posters", + "categories": ["science"], + "description": "Create professional research posters in LaTeX using beamerposter, tikzposter, or baposter. Suppor..." + }, + { + "name": "protocolsio-integration", + "source": "claude-scientific-skills", + "path": "scientific-skills/protocolsio-integration", + "categories": ["science"], + "description": "Integration with protocols.io API for managing scientific protocols. This skill should be used wh..." + }, + { + "name": "pubchem-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/pubchem-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Query PubChem via PUG-REST API/PubChemPy (110M+ compounds). Search by name/CID/SMILES, retrieve p..." + }, + { + "name": "pubmed-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/pubmed-database", + "categories": ["science", "data-science", "database"], + "description": "Direct REST API access to PubMed. Advanced Boolean/MeSH queries, E-utilities API, batch processin..." + }, + { + "name": "pufferlib", + "source": "claude-scientific-skills", + "path": "scientific-skills/pufferlib", + "categories": ["science"], + "description": "This skill should be used when working with reinforcement learning tasks including high-performan..." + }, + { + "name": "pydeseq2", + "source": "claude-scientific-skills", + "path": "scientific-skills/pydeseq2", + "categories": ["science", "biology", "data-science"], + "description": "Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts..." + }, + { + "name": "pydicom", + "source": "claude-scientific-skills", + "path": "scientific-skills/pydicom", + "categories": ["science"], + "description": "Python library for working with DICOM (Digital Imaging and Communications in Medicine) files. Use..." + }, + { + "name": "pyhealth", + "source": "claude-scientific-skills", + "path": "scientific-skills/pyhealth", + "categories": ["science", "ml", "medical"], + "description": "Comprehensive healthcare AI toolkit for developing, testing, and deploying machine learning model..." + }, + { + "name": "pylabrobot", + "source": "claude-scientific-skills", + "path": "scientific-skills/pylabrobot", + "categories": ["science"], + "description": "Laboratory automation toolkit for controlling liquid handlers, plate readers, pumps, heater shake..." + }, + { + "name": "pymatgen", + "source": "claude-scientific-skills", + "path": "scientific-skills/pymatgen", + "categories": ["science"], + "description": "Materials science toolkit. Crystal structures (CIF, POSCAR), phase diagrams, band structure, DOS,..." + }, + { + "name": "pymc", + "source": "claude-scientific-skills", + "path": "scientific-skills/pymc", + "categories": ["science"], + "description": "Bayesian modeling with PyMC. Build hierarchical models, MCMC (NUTS), variational inference, LOO/W..." + }, + { + "name": "pymoo", + "source": "claude-scientific-skills", + "path": "scientific-skills/pymoo", + "categories": ["science", "ml"], + "description": "Multi-objective optimization framework. NSGA-II, NSGA-III, MOEA/D, Pareto fronts, constraint hand..." + }, + { + "name": "pyopenms", + "source": "claude-scientific-skills", + "path": "scientific-skills/pyopenms", + "categories": ["science", "data-science"], + "description": "Python interface to OpenMS for mass spectrometry data analysis. Use for LC-MS/MS proteomics and m..." + }, + { + "name": "pysam", + "source": "claude-scientific-skills", + "path": "scientific-skills/pysam", + "categories": ["science", "biology"], + "description": "Genomic file toolkit. Read/write SAM/BAM/CRAM alignments, VCF/BCF variants, FASTA/FASTQ sequences..." + }, + { + "name": "pytdc", + "source": "claude-scientific-skills", + "path": "scientific-skills/pytdc", + "categories": ["science", "chemistry", "data-science", "ml"], + "description": "Therapeutics Data Commons. AI-ready drug discovery datasets (ADME, toxicity, DTI), benchmarks, sc..." + }, + { + "name": "pytorch-lightning", + "source": "claude-scientific-skills", + "path": "scientific-skills/pytorch-lightning", + "categories": ["science", "ml"], + "description": "Deep learning framework (PyTorch Lightning). Organize PyTorch code into LightningModules, configu..." + }, + { + "name": "qiskit", + "source": "claude-scientific-skills", + "path": "scientific-skills/qiskit", + "categories": ["science", "physics"], + "description": "Comprehensive quantum computing toolkit for building, optimizing, and executing quantum circuits...." + }, + { + "name": "qutip", + "source": "claude-scientific-skills", + "path": "scientific-skills/qutip", + "categories": ["science", "data-science", "physics"], + "description": "Quantum mechanics simulations and analysis using QuTiP (Quantum Toolbox in Python). Use when work..." + }, + { + "name": "rdkit", + "source": "claude-scientific-skills", + "path": "scientific-skills/rdkit", + "categories": ["science", "biology", "chemistry", "ml"], + "description": "Cheminformatics toolkit for fine-grained molecular control. SMILES/SDF parsing, descriptors (MW, ..." + }, + { + "name": "reactome-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/reactome-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Query Reactome REST API for pathway analysis, enrichment, gene-pathway mapping, disease pathways,..." + }, + { + "name": "research-grants", + "source": "claude-scientific-skills", + "path": "scientific-skills/research-grants", + "categories": ["science"], + "description": "Write competitive research proposals for NSF, NIH, DOE, and DARPA. Agency-specific formatting, re..." + }, + { + "name": "research-lookup", + "source": "claude-scientific-skills", + "path": "scientific-skills/research-lookup", + "categories": ["science"], + "description": "Look up current research information using Perplexity's Sonar Pro Search or Sonar Reasoning Pro m..." + }, + { + "name": "scanpy", + "source": "claude-scientific-skills", + "path": "scientific-skills/scanpy", + "categories": ["science", "biology", "data-science"], + "description": "Single-cell RNA-seq analysis. Load .h5ad/10X data, QC, normalization, PCA/UMAP/t-SNE, Leiden clus..." + }, + { + "name": "scholar-evaluation", + "source": "claude-scientific-skills", + "path": "scientific-skills/scholar-evaluation", + "categories": ["science"], + "description": "Systematically evaluate scholarly work using the ScholarEval framework, providing structured asse..." + }, + { + "name": "scientific-brainstorming", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-brainstorming", + "categories": ["science", "biology", "ml"], + "description": "Research ideation partner. Generate hypotheses, explore interdisciplinary connections, challenge ..." + }, + { + "name": "scientific-critical-thinking", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-critical-thinking", + "categories": ["science"], + "description": "Evaluate research rigor. Assess methodology, experimental design, statistical validity, biases, c..." + }, + { + "name": "scientific-schematics", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-schematics", + "categories": ["science", "chemistry", "ml", "research"], + "description": "Create publication-quality scientific diagrams using Nano Banana Pro AI with smart iterative refi..." + }, + { + "name": "scientific-slides", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-slides", + "categories": ["science"], + "description": "Build slide decks and presentations for research talks. Use this for making PowerPoint slides, co..." + }, + { + "name": "scientific-visualization", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-visualization", + "categories": ["science", "data-science", "research"], + "description": "Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, signi..." + }, + { + "name": "scientific-writing", + "source": "claude-scientific-skills", + "path": "scientific-skills/scientific-writing", + "categories": ["science", "ml"], + "description": "Core skill for the deep research and writing tool. Write scientific manuscripts in full paragraph..." + }, + { + "name": "scikit-bio", + "source": "claude-scientific-skills", + "path": "scientific-skills/scikit-bio", + "categories": ["science", "biology", "data-science"], + "description": "Biological data toolkit. Sequence analysis, alignments, phylogenetic trees, diversity metrics (al..." + }, + { + "name": "scikit-learn", + "source": "claude-scientific-skills", + "path": "scientific-skills/scikit-learn", + "categories": ["science", "ml"], + "description": "Machine learning in Python with scikit-learn. Use when working with supervised learning (classifi..." + }, + { + "name": "scikit-survival", + "source": "claude-scientific-skills", + "path": "scientific-skills/scikit-survival", + "categories": ["science", "data-science"], + "description": "Comprehensive toolkit for survival analysis and time-to-event modeling in Python using scikit-sur..." + }, + { + "name": "scvi-tools", + "source": "claude-scientific-skills", + "path": "scientific-skills/scvi-tools", + "categories": ["science", "biology", "data-science"], + "description": "This skill should be used when working with single-cell omics data analysis using scvi-tools, inc..." + }, + { + "name": "seaborn", + "source": "claude-scientific-skills", + "path": "scientific-skills/seaborn", + "categories": ["science", "data-science", "ml"], + "description": "Statistical visualization. Scatter, box, violin, heatmaps, pair plots, regression, correlation ma..." + }, + { + "name": "shap", + "source": "claude-scientific-skills", + "path": "scientific-skills/shap", + "categories": ["science", "ml"], + "description": "Model interpretability and explainability using SHAP (SHapley Additive exPlanations). Use this sk..." + }, + { + "name": "simpy", + "source": "claude-scientific-skills", + "path": "scientific-skills/simpy", + "categories": ["science"], + "description": "Process-based discrete-event simulation framework in Python. Use this skill when building simulat..." + }, + { + "name": "stable-baselines3", + "source": "claude-scientific-skills", + "path": "scientific-skills/stable-baselines3", + "categories": ["science", "ml"], + "description": "Use this skill for reinforcement learning tasks including training RL agents (PPO, SAC, DQN, TD3,..." + }, + { + "name": "statistical-analysis", + "source": "claude-scientific-skills", + "path": "scientific-skills/statistical-analysis", + "categories": ["science", "data-science"], + "description": "Statistical analysis toolkit. Hypothesis tests (t-test, ANOVA, chi-square), regression, correlati..." + }, + { + "name": "statsmodels", + "source": "claude-scientific-skills", + "path": "scientific-skills/statsmodels", + "categories": ["science"], + "description": "Statistical modeling toolkit. OLS, GLM, logistic, ARIMA, time series, hypothesis tests, diagnosti..." + }, + { + "name": "string-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/string-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Query STRING API for protein-protein interactions (59M proteins, 20B interactions). Network analy..." + }, + { + "name": "sympy", + "source": "claude-scientific-skills", + "path": "scientific-skills/sympy", + "categories": ["science"], + "description": "Use this skill when working with symbolic mathematics in Python. This skill should be used for sy..." + }, + { + "name": "torch-geometric", + "source": "claude-scientific-skills", + "path": "scientific-skills/torch_geometric", + "categories": ["science", "ml"], + "description": "Graph Neural Networks (PyG). Node/graph classification, link prediction, GCN, GAT, GraphSAGE, het..." + }, + { + "name": "torchdrug", + "source": "claude-scientific-skills", + "path": "scientific-skills/torchdrug", + "categories": ["science", "biology", "chemistry"], + "description": "Graph-based drug discovery toolkit. Molecular property prediction (ADMET), protein modeling, know..." + }, + { + "name": "transformers", + "source": "claude-scientific-skills", + "path": "scientific-skills/transformers", + "categories": ["science", "ml"], + "description": "This skill should be used when working with pre-trained transformer models for natural language p..." + }, + { + "name": "treatment-plans", + "source": "claude-scientific-skills", + "path": "scientific-skills/treatment-plans", + "categories": ["science", "biology", "medical"], + "description": "Generate concise (3-4 page), focused medical treatment plans in LaTeX/PDF format for all clinical..." + }, + { + "name": "umap-learn", + "source": "claude-scientific-skills", + "path": "scientific-skills/umap-learn", + "categories": ["science", "data-science"], + "description": "UMAP dimensionality reduction. Fast nonlinear manifold learning for 2D/3D visualization, clusteri..." + }, + { + "name": "uniprot-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/uniprot-database", + "categories": ["science", "biology", "data-science", "database"], + "description": "Direct REST API access to UniProt. Protein searches, FASTA retrieval, ID mapping, Swiss-Prot/TrEM..." + }, + { + "name": "uspto-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/uspto-database", + "categories": ["science", "data-science", "database"], + "description": "Access USPTO APIs for patent/trademark searches, examination history (PEDS), assignments, citatio..." + }, + { + "name": "vaex", + "source": "claude-scientific-skills", + "path": "scientific-skills/vaex", + "categories": ["science", "data-science"], + "description": "Use this skill for processing and analyzing large tabular datasets (billions of rows) that exceed..." + }, + { + "name": "venue-templates", + "source": "claude-scientific-skills", + "path": "scientific-skills/venue-templates", + "categories": ["science"], + "description": "Access comprehensive LaTeX templates, formatting requirements, and submission guidelines for majo..." + }, + { + "name": "zarr-python", + "source": "claude-scientific-skills", + "path": "scientific-skills/zarr-python", + "categories": ["science"], + "description": "Chunked N-D arrays for cloud storage. Compressed arrays, parallel I/O, S3/GCS integration, NumPy/..." + }, + { + "name": "zinc-database", + "source": "claude-scientific-skills", + "path": "scientific-skills/zinc-database", + "categories": ["science", "chemistry", "data-science", "database"], + "description": "Access ZINC (230M+ purchasable compounds). Search by ZINC ID/SMILES, similarity searches, 3D-read..." + }, + { + "name": "agent-skill-bridge", + "source": "claude-command-control", + "path": "skills/agent-skill-bridge", + "categories": ["community"], + "description": "Bridges and integrates multiple agent skills for coordinated task execution" + }, + { + "name": "architect-role-skill", + "source": "claude-command-control", + "path": "skills/architect-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "builder-role-skill", + "source": "claude-command-control", + "path": "skills/builder-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "content-research-writer", + "source": "claude-command-control", + "path": "skills/content-research-writer", + "categories": ["community"], + "description": "Assists in writing high-quality content by conducting research, adding citations, improving hooks..." + }, + { + "name": "devops-role-skill", + "source": "claude-command-control", + "path": "skills/devops-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "documentation-update", + "source": "claude-command-control", + "path": "skills/documentation-update", + "categories": ["community"], + "description": "Reusable logic for updating repository documentation (README, indices, tables) with new content w..." + }, + { + "name": "file-categorization", + "source": "claude-command-control", + "path": "skills/file-categorization", + "categories": ["community"], + "description": "Reusable logic for categorizing files as Command, Agent, Skill, or Documentation based on structu..." + }, + { + "name": "researcher-role-skill", + "source": "claude-command-control", + "path": "skills/researcher-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "root-cause-tracing", + "source": "claude-command-control", + "path": "skills/root-cause-tracing", + "categories": ["community"], + "description": "Use when errors occur deep in execution and you need to trace back to find the original trigger -..." + }, + { + "name": "scribe-role-skill", + "source": "claude-command-control", + "path": "skills/scribe-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "sharing-skills", + "source": "claude-command-control", + "path": "skills/sharing-skills", + "categories": ["community"], + "description": "Use when you've developed a broadly useful skill and want to contribute it upstream via pull requ..." + }, + { + "name": "skill-creator", + "source": "claude-command-control", + "path": "skills/skill-creator", + "categories": ["community"], + "description": "**Version**: 1" + }, + { + "name": "skill-orchestrator", + "source": "claude-command-control", + "path": "skills/skill-orchestrator", + "categories": ["community"], + "description": "Orchestrates and coordinates execution of multiple skills for complex workflows" + }, + { + "name": "software-architecture", + "source": "claude-command-control", + "path": "skills/software-architecture", + "categories": ["community"], + "description": "Guide for quality focused software architecture. This skill should be used when users want to wri..." + }, + { + "name": "subagent-driven-development", + "source": "claude-command-control", + "path": "skills/subagent-driven-development", + "categories": ["community"], + "description": "Use when executing implementation plans with independent tasks in the current session - dispatche..." + }, + { + "name": "ui-ux-pro-max", + "source": "claude-command-control", + "path": "skills/ui-ux-pro-max", + "categories": ["community"], + "description": "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, ..." + }, + { + "name": "using-git-worktrees", + "source": "claude-command-control", + "path": "skills/using-git-worktrees", + "categories": ["community"], + "description": "Use when starting feature work that needs isolation from current workspace or before executing im..." + }, + { + "name": "using-superpowers", + "source": "claude-command-control", + "path": "skills/using-superpowers", + "categories": ["community"], + "description": "Use when starting any conversation - establishes mandatory workflows for finding and using skills..." + }, + { + "name": "validator-role-skill", + "source": "claude-command-control", + "path": "skills/validator-role-skill", + "categories": ["community"], + "description": "|" + }, + { + "name": "schema-optimization", + "source": "claude-plugins-plus", + "path": ".claude/skills/schema-optimization", + "categories": ["community"], + "description": "Optimizes database schemas for performance, normalization, and query efficiency" + }, + { + "name": "2agent", + "source": "claude-code-harness", + "path": "skills/2agent", + "categories": ["community"], + "description": "Configures 2-Agent workflow between PM and implementation roles. Use when user mentions 2-Agent, ..." + }, + { + "name": "auth", + "source": "claude-code-harness", + "path": "skills/auth", + "categories": ["community"], + "description": "Implements authentication and payment features using Clerk, Supabase Auth, or Stripe. Use when us..." + }, + { + "name": "ci", + "source": "claude-code-harness", + "path": "skills/ci", + "categories": ["community"], + "description": "Diagnoses and fixes CI/CD pipeline failures. Use when user mentions 'CI', 'GitHub Actions', 'GitL..." + }, + { + "name": "deploy", + "source": "claude-code-harness", + "path": "skills/deploy", + "categories": ["community"], + "description": "Sets up deployment, analytics, and health monitoring for projects. Use when user mentions デプロイ, d..." + }, + { + "name": "docs", + "source": "claude-code-harness", + "path": "skills/docs", + "categories": ["community"], + "description": "Generates documentation files including NotebookLM YAML and slide content. Use when user mentions..." + }, + { + "name": "impl", + "source": "claude-code-harness", + "path": "skills/impl", + "categories": ["community"], + "description": "Implements features and writes code based on Plans.md tasks. Use when user mentions 実装, implement..." + }, + { + "name": "maintenance", + "source": "claude-code-harness", + "path": "skills/maintenance", + "categories": ["community"], + "description": "Cleans up and organizes project files. Use when user mentions '整理', 'cleanup', 'アーカイブ', 'archive'..." + }, + { + "name": "memory", + "source": "claude-code-harness", + "path": "skills/memory", + "categories": ["community"], + "description": "Manages memory, SSOT files, and Plans.md operations. Use when user mentions メモリ, memory, SSOT, de..." + }, + { + "name": "parallel-workflows", + "source": "claude-code-harness", + "path": "skills/parallel-workflows", + "categories": ["community"], + "description": "Optimizes parallel execution of multiple tasks. Use when user mentions 並列で実行, 同時にやって, まとめてやって, ru..." + }, + { + "name": "plans-management", + "source": "claude-code-harness", + "path": "skills/plans-management", + "categories": ["community"], + "description": "Manages Plans.md tasks and marker operations. Use when user mentions タスクを追加, Plans.md更新, 完了マーク, タ..." + }, + { + "name": "principles", + "source": "claude-code-harness", + "path": "skills/principles", + "categories": ["community"], + "description": "Provides development principles, guidelines, and VibeCoder guidance. Use when user mentions 原則, p..." + }, + { + "name": "review", + "source": "claude-code-harness", + "path": "skills/review", + "categories": ["community"], + "description": "Reviews code for quality, security, performance, and accessibility issues. Use when user mentions..." + }, + { + "name": "session-init", + "source": "claude-code-harness", + "path": "skills/session-init", + "categories": ["community"], + "description": "Initializes session with environment check and task status overview. Use when user mentions セッション..." + }, + { + "name": "session-memory", + "source": "claude-code-harness", + "path": "skills/session-memory", + "categories": ["community"], + "description": "Manages cross-session learning and memory persistence. Use when user mentions 前回何をした, 履歴, 過去の作業, ..." + }, + { + "name": "setup", + "source": "claude-code-harness", + "path": "skills/setup", + "categories": ["community"], + "description": "Sets up new projects and generates workflow files like CLAUDE.md, AGENTS.md, Plans.md. Use when u..." + }, + { + "name": "troubleshoot", + "source": "claude-code-harness", + "path": "skills/troubleshoot", + "categories": ["community"], + "description": "Guides diagnosis and resolution when problems occur. Use when user mentions 動かない, エラーが出た, 壊れた, うま..." + }, + { + "name": "ui", + "source": "claude-code-harness", + "path": "skills/ui", + "categories": ["community"], + "description": "Generates UI components and feedback forms. Use when user mentions コンポーネント, component, UI, ヒーロー, ..." + }, + { + "name": "verify", + "source": "claude-code-harness", + "path": "skills/verify", + "categories": ["community"], + "description": "Verifies builds, recovers from errors, and applies review fixes. Use when user mentions ビルド, buil..." + }, + { + "name": "vibecoder-guide", + "source": "claude-code-harness", + "path": "skills/vibecoder-guide", + "categories": ["community"], + "description": "Guides VibeCoder (non-technical users) through natural language development (legacy). Use when us..." + }, + { + "name": "workflow", + "source": "claude-code-harness", + "path": "skills/workflow", + "categories": ["community"], + "description": "Manages workflow transitions including handoffs between PM and implementation roles, and auto-fix..." + }, + { + "name": "iso-13485-certification", + "source": "claude-scientific-skills", + "path": "scientific-skills/iso-13485-certification", + "categories": ["science", "medical"], + "description": "Comprehensive toolkit for preparing ISO 13485 certification documentation for medical device Qual..." + }, + { + "name": "agentic-workflow-guide", + "source": "aktsmm-agent-skills", + "path": "agentic-workflow-guide", + "categories": ["community"], + "description": "Design, review, and improve agent workflows based on proven design principles (SSOT, SRP, Fail Fa..." + }, + { + "name": "pdf", + "source": "aktsmm-agent-skills", + "path": "pdf", + "categories": ["community"], + "description": "Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging..." + }, + { + "name": "braiins-ecosystem", + "source": "claude-command-control", + "path": "skills/braiins-ecosystem", + "categories": ["community"], + "description": "Unified Braiins ecosystem skill covering all Bitcoin mining tools - OS firmware, Pool, Toolbox, M..." + }, + { + "name": "braiins-insights", + "source": "claude-command-control", + "path": "skills/braiins-insights", + "categories": ["community"], + "description": "Braiins Learn - Bitcoin mining profitability calculators, charts, and data dashboard" + }, + { + "name": "braiins-manager", + "source": "claude-command-control", + "path": "skills/braiins-manager", + "categories": ["community"], + "description": "Braiins Manager - web-based dashboard for monitoring and managing Bitcoin mining operations with ..." + }, + { + "name": "braiins-os", + "source": "claude-command-control", + "path": "skills/braiins-os", + "categories": ["community"], + "description": "Comprehensive Braiins OS skill covering API, feeds, and documentation" + }, + { + "name": "braiins-pool", + "source": "claude-command-control", + "path": "skills/braiins-pool", + "categories": ["community"], + "description": "Comprehensive Braiins Pool skill - oldest Bitcoin mining pool with FPPS rewards, Lightning payout..." + }, + { + "name": "braiins-proxy", + "source": "claude-command-control", + "path": "skills/braiins-proxy", + "categories": ["community"], + "description": "Braiins Farm Proxy - high-performance Stratum V2 mining proxy for large-scale Bitcoin mining oper..." + }, + { + "name": "braiins-toolbox", + "source": "claude-command-control", + "path": "skills/braiins-toolbox", + "categories": ["community"], + "description": "Comprehensive Braiins Toolbox skill - batch management tool for Bitcoin mining operations with GU..." + }, + { + "name": "farm-monitor", + "source": "claude-command-control", + "path": "skills/farm-monitor", + "categories": ["community"], + "description": "Braiins Farm Monitor - Bitcoin mining fleet monitoring and management" + }, + { + "name": "cursor-mem", + "source": "claude-code-harness", + "path": "skills/cursor-mem", + "categories": ["community"], + "description": "Cursorでclaude-memのMCPサーバーにアクセスし、過去のセッション記録を検索・新しい観測を記録。トリガー: 'メモリ検索', 'claude-mem', '過去の判断', '記録し..." + } + ], + "categories": [ + { + "id": "development", + "name": "開発", + "description": "ソフトウェア開発関連" + }, + { + "id": "testing", + "name": "テスト", + "description": "テスト・品質保証" + }, + { + "id": "document", + "name": "ドキュメント", + "description": "ドキュメント処理" + }, + { + "id": "office", + "name": "Office", + "description": "Microsoft Office 関連" + }, + { + "id": "web", + "name": "Web", + "description": "Web 開発" + }, + { + "id": "frontend", + "name": "フロントエンド", + "description": "フロントエンド開発" + }, + { + "id": "design", + "name": "デザイン", + "description": "デザイン・UI/UX" + }, + { + "id": "creative", + "name": "クリエイティブ", + "description": "クリエイティブ・アート" + }, + { + "id": "git", + "name": "Git", + "description": "Git・バージョン管理" + }, + { + "id": "planning", + "name": "計画", + "description": "プロジェクト計画" + }, + { + "id": "agents", + "name": "エージェント", + "description": "AI エージェント関連" + }, + { + "id": "mcp", + "name": "MCP", + "description": "Model Context Protocol" + }, + { + "id": "business", + "name": "ビジネス", + "description": "ビジネス・業務" + }, + { + "id": "utility", + "name": "ユーティリティ", + "description": "汎用ツール" + }, + { + "id": "meta", + "name": "メタ", + "description": "スキル作成・管理" + }, + { + "id": "azure", + "name": "Azure", + "description": "Microsoft Azure・クラウドインフラ" + } + ] +} diff --git a/skills/skill-finder/references/skill-index.schema.json b/skills/skill-finder/references/skill-index.schema.json new file mode 100644 index 000000000..25e39525a --- /dev/null +++ b/skills/skill-finder/references/skill-index.schema.json @@ -0,0 +1,152 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Skill Index", + "description": "Agent Skills のインデックスファイルスキーマ", + "type": "object", + "required": ["version", "lastUpdated", "sources", "skills"], + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema への参照" + }, + "version": { + "type": "string", + "description": "インデックスのバージョン(semver形式)", + "pattern": "^\\d+\\.\\d+\\.\\d+$", + "examples": ["1.0.0"] + }, + "lastUpdated": { + "type": "string", + "description": "最終更新日(ISO 8601形式)", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "examples": ["2025-12-31"] + }, + "sources": { + "type": "array", + "description": "スキルのソースリポジトリ一覧", + "items": { + "$ref": "#/definitions/source" + }, + "minItems": 1 + }, + "skills": { + "type": "array", + "description": "スキル一覧", + "items": { + "$ref": "#/definitions/skill" + } + }, + "categories": { + "type": "array", + "description": "カテゴリ定義一覧", + "items": { + "$ref": "#/definitions/category" + } + } + }, + "definitions": { + "source": { + "type": "object", + "description": "スキルのソースリポジトリ", + "required": ["id", "name", "owner", "url", "type", "description"], + "properties": { + "id": { + "type": "string", + "description": "ソースの一意識別子", + "pattern": "^[a-z0-9-]+$", + "examples": ["anthropics-skills", "obra-superpowers"] + }, + "name": { + "type": "string", + "description": "ソースの表示名", + "examples": ["Anthropic Skills (Official)"] + }, + "owner": { + "type": "string", + "description": "GitHubオーナー名", + "examples": ["anthropics", "obra"] + }, + "url": { + "type": "string", + "description": "リポジトリURL", + "format": "uri", + "pattern": "^https://github\\.com/", + "examples": ["https://github.com/anthropics/skills"] + }, + "type": { + "type": "string", + "description": "ソースの種類", + "enum": ["official", "awesome-list", "community"] + }, + "description": { + "type": "string", + "description": "ソースの説明" + } + }, + "additionalProperties": false + }, + "skill": { + "type": "object", + "description": "スキル情報", + "required": ["name", "source", "path", "categories", "description"], + "properties": { + "name": { + "type": "string", + "description": "スキル名", + "pattern": "^[a-z0-9-]+$", + "examples": ["docx", "pdf", "azure-env-builder"] + }, + "source": { + "type": "string", + "description": "ソースID(sourcesのidを参照)", + "examples": ["anthropics-skills", "obra-superpowers"] + }, + "path": { + "type": "string", + "description": "リポジトリ内のパス", + "examples": ["skills/docx", ".github/skills/azure-env-builder"] + }, + "categories": { + "type": "array", + "description": "カテゴリタグ", + "items": { + "type": "string", + "pattern": "^[a-z0-9-]+$" + }, + "minItems": 1, + "examples": [ + ["document", "office"], + ["azure", "development"] + ] + }, + "description": { + "type": "string", + "description": "スキルの説明" + } + }, + "additionalProperties": false + }, + "category": { + "type": "object", + "description": "カテゴリ定義", + "required": ["id", "name", "description"], + "properties": { + "id": { + "type": "string", + "description": "カテゴリID", + "pattern": "^[a-z0-9-]+$" + }, + "name": { + "type": "string", + "description": "カテゴリ表示名" + }, + "description": { + "type": "string", + "description": "カテゴリの説明" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/skills/skill-finder/references/starred-skills.json b/skills/skill-finder/references/starred-skills.json new file mode 100644 index 000000000..ca32e2713 --- /dev/null +++ b/skills/skill-finder/references/starred-skills.json @@ -0,0 +1,4 @@ +{ + "starred": [], + "lastUpdated": "2025-06-30" +} diff --git a/skills/skill-finder/scripts/Search-Skills.ps1 b/skills/skill-finder/scripts/Search-Skills.ps1 new file mode 100644 index 000000000..a5ee69650 --- /dev/null +++ b/skills/skill-finder/scripts/Search-Skills.ps1 @@ -0,0 +1,1132 @@ +<# +.SYNOPSIS + Search and manage Agent Skills. + +.DESCRIPTION + Full-featured skill management: + - Search local index (fast, offline) + - GitHub Code Search API fallback + - Web search URLs as final fallback + - Add/update sources and skills + - Star favorite skills + - Install skills locally + - Show detailed skill info + - Tag-based search (#azure #bicep) + + Author: yamapan (https://github.com/aktsmm) + License: MIT + +.PARAMETER Query + Search keyword (supports #tags like "#azure #bicep") + +.PARAMETER Category + Filter by category (e.g., development, testing, document) + +.PARAMETER Source + Filter by source (e.g., anthropics-skills, obra-superpowers) + +.PARAMETER SearchExternal + Force GitHub search even if found locally + +.PARAMETER SearchWeb + Open web search in browser + +.PARAMETER AddSource + Add a new source repository to the index + +.PARAMETER RepoUrl + Repository URL to add (use with -AddSource) + +.PARAMETER Update + Update skills from all sources + +.PARAMETER Info + Show detailed skill info with SKILL.md content + +.PARAMETER Install + Install skill to local directory + +.PARAMETER InstallDir + Target directory for install (default: ~/.skills) + +.PARAMETER Star + Star a skill + +.PARAMETER Unstar + Unstar a skill + +.PARAMETER ListStarred + List starred skills + +.PARAMETER Similar + Find similar skills + +.PARAMETER Stats + Show index statistics + +.PARAMETER Check + Check tool dependencies + +.PARAMETER ListCategories + List available categories + +.PARAMETER ListSources + List available sources + +.EXAMPLE + .\Search-Skills.ps1 -Query "pdf" + .\Search-Skills.ps1 -Query "#azure #bicep" + .\Search-Skills.ps1 -Category "development" + .\Search-Skills.ps1 -Info "skill-name" + .\Search-Skills.ps1 -Install "skill-name" + .\Search-Skills.ps1 -Star "skill-name" + .\Search-Skills.ps1 -Similar "skill-name" + .\Search-Skills.ps1 -Stats + .\Search-Skills.ps1 -Update +#> + +[CmdletBinding(DefaultParameterSetName = 'Search')] +param( + [Parameter(ParameterSetName = 'Search', Position = 0)] + [string]$Query = "", + + [Parameter(ParameterSetName = 'Search')] + [string]$Category = "", + + [Parameter(ParameterSetName = 'Search')] + [string]$Source = "", + + [Parameter(ParameterSetName = 'Search')] + [switch]$SearchExternal, + + [Parameter(ParameterSetName = 'Search')] + [switch]$SearchWeb, + + [Parameter(ParameterSetName = 'Update')] + [switch]$Update, + + [Parameter(ParameterSetName = 'AddSource')] + [switch]$AddSource, + + [Parameter(ParameterSetName = 'AddSource')] + [string]$RepoUrl = "", + + [Parameter(ParameterSetName = 'Info')] + [string]$Info = "", + + [Parameter(ParameterSetName = 'Install')] + [string]$Install = "", + + [Parameter(ParameterSetName = 'Install')] + [string]$InstallDir = "", + + [Parameter(ParameterSetName = 'Star')] + [string]$Star = "", + + [Parameter(ParameterSetName = 'Unstar')] + [string]$Unstar = "", + + [Parameter(ParameterSetName = 'ListStarred')] + [switch]$ListStarred, + + [Parameter(ParameterSetName = 'Similar')] + [string]$Similar = "", + + [Parameter(ParameterSetName = 'Stats')] + [switch]$Stats, + + [Parameter(ParameterSetName = 'Check')] + [switch]$Check, + + [Parameter(ParameterSetName = 'ListCategories')] + [switch]$ListCategories, + + [Parameter(ParameterSetName = 'ListSources')] + [switch]$ListSources, + + [Parameter()] + [switch]$NoInteractive +) + +# Configuration +$AutoUpdateDays = 7 # Auto-update if index is older than this + +# Get script directory +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$indexPath = Join-Path $scriptDir "..\references\skill-index.json" +$starsPath = Join-Path $scriptDir "..\references\starred-skills.json" +$defaultInstallDir = Join-Path $env:USERPROFILE ".skills" + +# Load index +function Get-SkillIndex { + if (Test-Path $indexPath) { + return Get-Content $indexPath -Raw | ConvertFrom-Json + } + Write-Warning "Index file not found: $indexPath" + return $null +} + +# Save index +function Save-SkillIndex { + param($Index) + $Index.lastUpdated = (Get-Date).ToString("yyyy-MM-dd") + $json = $Index | ConvertTo-Json -Depth 10 + Set-Content -Path $indexPath -Value $json -Encoding UTF8 + Write-Host "✅ Index saved: $indexPath" -ForegroundColor Green +} + +# Load stars +function Get-StarredSkills { + if (Test-Path $starsPath) { + $data = Get-Content $starsPath -Raw | ConvertFrom-Json + return @($data.starred) + } + return @() +} + +# Save stars +function Save-StarredSkills { + param([string[]]$Starred) + $data = @{ + starred = $Starred + lastUpdated = (Get-Date).ToString("yyyy-MM-dd") + } + $json = $data | ConvertTo-Json -Depth 5 + Set-Content -Path $starsPath -Value $json -Encoding UTF8 +} + +# ============================================================================ +# Auto-Update Check +# ============================================================================ +function Test-IndexOutdated { + param($Index) + $lastUpdated = $Index.lastUpdated + if (-not $lastUpdated) { return $true } + try { + $lastDate = [datetime]::Parse($lastUpdated) + $age = (Get-Date) - $lastDate + return $age.TotalDays -gt $AutoUpdateDays + } + catch { + return $true + } +} + +function Invoke-AutoUpdateCheck { + param($Index) + if (Test-IndexOutdated -Index $Index) { + $lastUpdated = if ($Index.lastUpdated) { $Index.lastUpdated } else { "unknown" } + Write-Host "`n⚠️ Index is outdated (last updated: $lastUpdated)" -ForegroundColor Yellow + try { + $answer = Read-Host "🔄 Update now? [Y/n]" + if ($answer -eq "" -or $answer -match "^[Yy]") { + Update-AllSources + return Get-SkillIndex + } + } + catch { + Write-Host " Skipped" -ForegroundColor Gray + } + } + return $Index +} + +# ============================================================================ +# Post-Search Suggestions +# ============================================================================ +function Show-PostSearchSuggestions { + param($Index, [string]$Query, $Results) + + Write-Host "`n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray + Write-Host "💡 Suggestions" -ForegroundColor Cyan + + # 1. Related categories + if ($Results -and $Results.Count -gt 0) { + $allCategories = @() + $Results | Select-Object -First 3 | ForEach-Object { + $allCategories += $_.categories + } + $allCategories = $allCategories | Select-Object -Unique | Select-Object -First 3 + if ($allCategories.Count -gt 0) { + $catsStr = $allCategories -join ", " + Write-Host " 🏷️ Related categories: $catsStr" -ForegroundColor Gray + Write-Host " → Example: .\Search-Skills.ps1 -Query `"#$($allCategories[0])`"" -ForegroundColor DarkGray + } + } + + # 2. Similar skills + if ($Query -and $Index) { + $similar = $Index.skills | Where-Object { + $_.name -like "*$Query*" -or $_.description -like "*$Query*" + } | Where-Object { $_ -notin $Results } | Select-Object -First 3 + if ($similar) { + Write-Host "`n 🔍 You might also like:" -ForegroundColor Gray + foreach ($s in $similar) { + $desc = if ($s.description.Length -gt 40) { $s.description.Substring(0, 40) } else { $s.description } + Write-Host " - $($s.name): $desc" -ForegroundColor DarkGray + } + } + } + + # 3. Starred skills count + $starred = Get-StarredSkills + if ($starred.Count -gt 0) { + Write-Host "`n ⭐ Your favorites: $($starred.Count) skills" -ForegroundColor Yellow + } +} + +function Invoke-DiscoverNewRepos { + param([string]$Query) + + Write-Host "`n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray + try { + $answer = Read-Host "🌐 Search for more repositories? [y/N]" + if ($answer -match "^[Yy]") { + Write-Host "`n🔍 Searching GitHub for related repositories..." -ForegroundColor Cyan + Find-NewRepos -Query $Query + } + } + catch { + Write-Host " Skipped" -ForegroundColor Gray + } +} + +function Find-NewRepos { + param([string]$Query) + + $searchTerms = if ($Query) { "$Query SKILL.md agent skills" } else { "SKILL.md agent skills claude copilot" } + + try { + $result = gh search repos $searchTerms --json nameWithOwner,description,stargazersCount --limit 10 2>&1 + if ($LASTEXITCODE -eq 0 -and $result) { + $repos = $result | ConvertFrom-Json + if ($repos -and $repos.Count -gt 0) { + Write-Host "`n📦 Found $($repos.Count) repositories:" -ForegroundColor Cyan + $i = 1 + foreach ($repo in $repos) { + $desc = if ($repo.description.Length -gt 50) { $repo.description.Substring(0, 50) } else { $repo.description } + if (-not $desc) { $desc = "No description" } + Write-Host "`n [$i] $($repo.nameWithOwner) ⭐$($repo.stargazersCount)" -ForegroundColor White + Write-Host " $desc" -ForegroundColor Gray + $i++ + } + + # Ask to add to index + Write-Host "`n────────────────────────────────────────" -ForegroundColor DarkGray + try { + $choice = Read-Host "📥 Enter repository number to add (blank to skip)" + if ($choice -match "^\d+$") { + $idx = [int]$choice - 1 + if ($idx -ge 0 -and $idx -lt $repos.Count) { + $repoName = $repos[$idx].nameWithOwner + Write-Host "`n📦 Adding $repoName..." -ForegroundColor Cyan + & $PSCommandPath -AddSource -RepoUrl "https://github.com/$repoName" + } + } + } + catch { } + } + else { + Write-Host " No matching repositories found" -ForegroundColor Yellow + } + } + else { + Write-Host " ⚠️ Search failed" -ForegroundColor Yellow + } + } + catch { + Write-Host " ⚠️ GitHub CLI (gh) not found" -ForegroundColor Yellow + } +} + +# ============================================================================ +# Dependency Check +# ============================================================================ +if ($Check) { + Write-Host "`n🔧 Checking Dependencies..." -ForegroundColor Cyan + + $tools = @( + @{ name = "gh"; desc = "GitHub CLI - Required for external search and install" }, + @{ name = "curl"; desc = "cURL - Required for downloading files" }, + @{ name = "pwsh"; desc = "PowerShell - You're running this!" } + ) + + foreach ($tool in $tools) { + try { + $result = & $tool.name --version 2>&1 + if ($LASTEXITCODE -eq 0) { + $version = ($result | Select-Object -First 1).ToString().Substring(0, [Math]::Min(50, $result.Length)) + Write-Host " ✅ $($tool.name): $version" -ForegroundColor Green + } else { + Write-Host " ❌ $($tool.name): Not working properly" -ForegroundColor Red + } + } + catch { + Write-Host " ❌ $($tool.name): Not found - $($tool.desc)" -ForegroundColor Red + } + } + exit 0 +} + +# ============================================================================ +# Statistics +# ============================================================================ +if ($Stats) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $starred = Get-StarredSkills + + Write-Host "`n📊 Skill Index Statistics" -ForegroundColor Cyan + Write-Host "=" * 50 + Write-Host "📅 Last Updated: $($index.lastUpdated)" -ForegroundColor Gray + Write-Host "📦 Total Skills: $($index.skills.Count)" -ForegroundColor White + Write-Host "📁 Sources: $($index.sources.Count)" -ForegroundColor White + Write-Host "🏷️ Categories: $($index.categories.Count)" -ForegroundColor White + Write-Host "⭐ Starred: $($starred.Count)" -ForegroundColor Yellow + + # Skills per source + Write-Host "`n📦 Skills by Source:" -ForegroundColor Cyan + $index.skills | Group-Object -Property source | Sort-Object -Property Count -Descending | ForEach-Object { + Write-Host " $($_.Name): $($_.Count)" -ForegroundColor Gray + } + + # Skills per category + Write-Host "`n🏷️ Skills by Category:" -ForegroundColor Cyan + $catCounts = @{} + $index.skills | ForEach-Object { + foreach ($cat in $_.categories) { + $catCounts[$cat] = ($catCounts[$cat] ?? 0) + 1 + } + } + $catCounts.GetEnumerator() | Sort-Object -Property Value -Descending | Select-Object -First 10 | ForEach-Object { + Write-Host " $($_.Key): $($_.Value)" -ForegroundColor Gray + } + exit 0 +} + +# ============================================================================ +# Star Management +# ============================================================================ +if ($Star) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $skill = $index.skills | Where-Object { $_.name -eq $Star } | Select-Object -First 1 + if (-not $skill) { + Write-Host "❌ Skill not found: $Star" -ForegroundColor Red + exit 1 + } + + $skillId = "$($skill.source)/$($skill.name)" + $starred = Get-StarredSkills + + if ($starred -contains $skillId) { + Write-Host "⚠️ Already starred: $($skill.name)" -ForegroundColor Yellow + } else { + $starred += $skillId + Save-StarredSkills -Starred $starred + Write-Host "⭐ Starred: $($skill.name)" -ForegroundColor Green + } + exit 0 +} + +if ($Unstar) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $skill = $index.skills | Where-Object { $_.name -eq $Unstar } | Select-Object -First 1 + if (-not $skill) { + Write-Host "❌ Skill not found: $Unstar" -ForegroundColor Red + exit 1 + } + + $skillId = "$($skill.source)/$($skill.name)" + $starred = Get-StarredSkills + + if ($starred -contains $skillId) { + $starred = $starred | Where-Object { $_ -ne $skillId } + Save-StarredSkills -Starred $starred + Write-Host "☆ Unstarred: $($skill.name)" -ForegroundColor Yellow + } else { + Write-Host "⚠️ Skill is not starred: $($skill.name)" -ForegroundColor Yellow + } + exit 0 +} + +if ($ListStarred) { + $starred = Get-StarredSkills + if ($starred.Count -eq 0) { + Write-Host "☆ No starred skills yet." -ForegroundColor Yellow + Write-Host " Use -Star to star a skill." -ForegroundColor Gray + } else { + Write-Host "`n⭐ Starred Skills ($($starred.Count)):" -ForegroundColor Cyan + foreach ($s in $starred) { + Write-Host " - $s" -ForegroundColor White + } + } + exit 0 +} + +# ============================================================================ +# Skill Info +# ============================================================================ +if ($Info) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $skill = $index.skills | Where-Object { $_.name -eq $Info } | Select-Object -First 1 + if (-not $skill) { + Write-Host "❌ Skill not found: $Info" -ForegroundColor Red + + # Suggest similar + $similar = $index.skills | Where-Object { $_.name -like "*$Info*" } | Select-Object -First 5 + if ($similar) { + Write-Host "`n💡 Did you mean:" -ForegroundColor Cyan + foreach ($s in $similar) { + Write-Host " - $($s.name)" -ForegroundColor Gray + } + } + exit 1 + } + + $srcInfo = $index.sources | Where-Object { $_.id -eq $skill.source } | Select-Object -First 1 + + Write-Host "`n📦 $($skill.name)" -ForegroundColor Cyan + Write-Host "=" * 50 + Write-Host "📝 Description: $($skill.description)" -ForegroundColor White + Write-Host "📁 Source: $($srcInfo.name)" -ForegroundColor Gray + Write-Host "🏷️ Categories: $($skill.categories -join ', ')" -ForegroundColor Gray + Write-Host "📂 Path: $($skill.path)" -ForegroundColor Gray + + if ($srcInfo.url -and $skill.path) { + Write-Host "🔗 URL: $($srcInfo.url)/tree/main/$($skill.path)" -ForegroundColor Blue + } + + # Fetch SKILL.md + if ($srcInfo.url -match "github\.com/([^/]+/[^/]+)") { + $repoFull = $Matches[1] + Write-Host "`n📄 Fetching SKILL.md..." -ForegroundColor Cyan + + try { + $content = gh api "repos/$repoFull/contents/$($skill.path)/SKILL.md" -H "Accept: application/vnd.github.raw" 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host "-" * 50 + $lines = $content -split "`n" | Select-Object -First 50 + $lines | ForEach-Object { Write-Host $_ } + if (($content -split "`n").Count -gt 50) { + Write-Host "`n... (truncated)" -ForegroundColor DarkGray + } + } + } + catch { + Write-Host " ⚠️ Could not fetch SKILL.md" -ForegroundColor Yellow + } + } + exit 0 +} + +# ============================================================================ +# Install Skill +# ============================================================================ +if ($Install) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $skill = $index.skills | Where-Object { $_.name -eq $Install } | Select-Object -First 1 + if (-not $skill) { + Write-Host "❌ Skill not found: $Install" -ForegroundColor Red + exit 1 + } + + $srcInfo = $index.sources | Where-Object { $_.id -eq $skill.source } | Select-Object -First 1 + + if (-not $srcInfo.url -or -not $skill.path) { + Write-Host "❌ Cannot install: missing URL or path information" -ForegroundColor Red + exit 1 + } + + $targetDir = if ($InstallDir) { $InstallDir } else { $defaultInstallDir } + $installPath = Join-Path $targetDir $skill.name + + if ($srcInfo.url -notmatch "github\.com/([^/]+/[^/]+)") { + Write-Host "❌ Invalid source URL" -ForegroundColor Red + exit 1 + } + $repoFull = $Matches[1] + + Write-Host "📥 Installing $($skill.name)..." -ForegroundColor Cyan + Write-Host " From: $($srcInfo.url)" -ForegroundColor Gray + Write-Host " To: $installPath" -ForegroundColor Gray + + # Create directory + if (-not (Test-Path $installPath)) { + New-Item -ItemType Directory -Path $installPath -Force | Out-Null + } + + try { + # Get file list + $items = gh api "repos/$repoFull/contents/$($skill.path)" 2>&1 | ConvertFrom-Json + + foreach ($item in $items) { + if ($item.type -eq "file" -and $item.name -and $item.download_url) { + Write-Host " 📄 $($item.name)" -ForegroundColor Gray + $filePath = Join-Path $installPath $item.name + curl -sL -o $filePath $item.download_url + } + } + + Write-Host "`n✅ Installed to: $installPath" -ForegroundColor Green + } + catch { + Write-Host "❌ Installation failed: $($_.Exception.Message)" -ForegroundColor Red + } + exit 0 +} + +# ============================================================================ +# Similar Skills +# ============================================================================ +if ($Similar) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + $skill = $index.skills | Where-Object { $_.name -eq $Similar } | Select-Object -First 1 + + if ($skill) { + # Find by matching categories + $targetCats = $skill.categories + $similarSkills = $index.skills | Where-Object { + $_.name -ne $skill.name -and ($_.categories | Where-Object { $targetCats -contains $_ }) + } | Select-Object -First 5 + + if ($similarSkills) { + Write-Host "`n💡 Skills similar to '$($skill.name)':" -ForegroundColor Cyan + foreach ($s in $similarSkills) { + $cats = ($s.categories | Select-Object -First 3) -join ", " + Write-Host " - $($s.name) ($cats)" -ForegroundColor Gray + } + } else { + Write-Host " No similar skills found." -ForegroundColor Yellow + } + } else { + # Fuzzy match + $fuzzy = $index.skills | Where-Object { $_.name -like "*$Similar*" } | Select-Object -First 5 + if ($fuzzy) { + Write-Host "`n💡 Skills matching '$Similar':" -ForegroundColor Cyan + foreach ($s in $fuzzy) { + Write-Host " - $($s.name)" -ForegroundColor Gray + } + } else { + Write-Host " No matching skills found." -ForegroundColor Yellow + } + } + exit 0 +} + +# ============================================================================ +# Update All Sources +# ============================================================================ +if ($Update) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + Write-Host "🔄 Updating all sources..." -ForegroundColor Cyan + + foreach ($src in $index.sources) { + if ($src.url -match "github\.com/([^/]+/[^/]+)") { + $repoFull = $Matches[1] + Write-Host "`n📦 $($src.id) ($repoFull)" -ForegroundColor White + + $foundSkills = @() + + # Method 1: Use GitHub Code Search API to find all SKILL.md files + try { + $rawOutput = gh api search/code -f "q=repo:$repoFull filename:SKILL.md" 2>$null + if ($LASTEXITCODE -eq 0 -and $rawOutput) { + $data = $rawOutput | ConvertFrom-Json + $items = $data.items + if ($items -and $items.Count -gt 0) { + $seenPaths = @{} + foreach ($item in $items) { + $path = $item.path + if ($path -and $path.EndsWith("SKILL.md")) { + # Get parent directory (skill folder) + $parts = $path -split "/" + $parent = ($parts[0..($parts.Count - 2)]) -join "/" + if ($parent -and -not $seenPaths.ContainsKey($parent)) { + $seenPaths[$parent] = $true + $skillName = $parts[$parts.Count - 2] + $foundSkills += @{ name = $skillName; path = $parent } + } + } + } + + if ($foundSkills.Count -gt 0) { + Write-Host " 📂 Found $($foundSkills.Count) skills via Code Search" -ForegroundColor Green + foreach ($skill in $foundSkills) { + Write-Host " - $($skill.name) ($($skill.path))" -ForegroundColor Gray + } + } + } + } + } + catch { + Write-Host " ⚠️ Code Search failed, falling back to directory scan..." -ForegroundColor Yellow + } + + # Method 2: Fallback to directory-based search if Code Search fails or returns empty + if ($foundSkills.Count -eq 0) { + $skillsPaths = @("skills", ".github/skills", ".claude/skills", "scientific-skills") + $foundInSubdir = $false + + foreach ($path in $skillsPaths) { + try { + $rawOutput = gh api "repos/$repoFull/contents/$path" 2>$null + if ($LASTEXITCODE -eq 0 -and $rawOutput -and $rawOutput -notmatch '"message"') { + $items = $rawOutput | ConvertFrom-Json + if ($items) { + $foundInSubdir = $true + Write-Host " 📂 Found $(@($items).Count) items in $path" -ForegroundColor Green + foreach ($item in $items) { + if ($item.type -eq "dir") { + $foundSkills += @{ name = $item.name; path = "$path/$($item.name)" } + Write-Host " - $($item.name)" -ForegroundColor Gray + } + } + break + } + } + } + catch { } + } + + # If no skills/ directory found, check root for SKILL.md in subdirectories + if (-not $foundInSubdir) { + try { + $rawOutput = gh api "repos/$repoFull/contents" 2>$null + if ($LASTEXITCODE -eq 0 -and $rawOutput) { + $items = $rawOutput | ConvertFrom-Json + $skillDirs = @() + $skipDirs = @(".", ".github", ".claude", "docs", "examples", "tests", "node_modules", "dist", "build", "src", "lib", "scripts") + + foreach ($item in $items) { + if ($item.type -eq "dir" -and $item.name -and -not $item.name.StartsWith(".")) { + if ($skipDirs -notcontains $item.name) { + $skillMdCheck = gh api "repos/$repoFull/contents/$($item.name)/SKILL.md" 2>$null + if ($LASTEXITCODE -eq 0 -and $skillMdCheck -and $skillMdCheck -notmatch '"message"') { + $foundSkills += @{ name = $item.name; path = $item.name } + } + } + } + } + + if ($foundSkills.Count -gt 0) { + Write-Host " 📂 Found $($foundSkills.Count) skills at root level" -ForegroundColor Green + foreach ($skill in $foundSkills) { + Write-Host " - $($skill.name)" -ForegroundColor Gray + } + } + } + } + catch { } + } + } + + # Add found skills to index + foreach ($skill in $foundSkills) { + $existing = $index.skills | Where-Object { $_.name -eq $skill.name -and $_.source -eq $src.id } + if (-not $existing) { + $newSkill = [PSCustomObject]@{ + name = $skill.name + source = $src.id + path = $skill.path + categories = @("community") + description = "$($skill.name) skill" + } + $index.skills += $newSkill + Write-Host " ✅ $($skill.name)" -ForegroundColor Green + } else { + Write-Host " ⏭️ $($skill.name) (exists)" -ForegroundColor Gray + } + } + } + } + + Save-SkillIndex -Index $index + Write-Host "`n✅ Update complete!" -ForegroundColor Green + exit 0 +} + +# ============================================================================ +# Add source +# ============================================================================ +if ($AddSource) { + $index = Get-SkillIndex + if (-not $index) { exit 1 } + + # Check URL + if (-not $RepoUrl) { + Write-Error "Please specify repository URL: -RepoUrl 'https://github.com/owner/repo'" + exit 1 + } + + # Parse owner/repo from URL + if ($RepoUrl -match "github\.com[/:]([^/]+)/([^/]+)") { + $owner = $Matches[1] + $repo = $Matches[2] -replace "\.git$", "" + $repoFullName = "$owner/$repo" + } + else { + Write-Error "Invalid GitHub URL: $RepoUrl" + exit 1 + } + + # Check if exists + $existingSource = $index.sources | Where-Object { $_.url -like "*$repoFullName*" } + if ($existingSource) { + Write-Warning "Source already exists: $($existingSource.id)" + exit 0 + } + + # Generate ID and name + $sourceId = $repo.ToLower() -replace "[^a-z0-9-]", "-" + $sourceName = $repo + $sourceType = "community" + $sourceDesc = "Skills from $owner/$repo" + + # Add source + $newSource = [PSCustomObject]@{ + id = $sourceId + name = $sourceName + url = "https://github.com/$repoFullName" + type = $sourceType + description = $sourceDesc + } + + $index.sources += $newSource + Save-SkillIndex -Index $index + + Write-Host "`n📦 Added new source:" -ForegroundColor Cyan + Write-Host " ID: $sourceId" -ForegroundColor White + Write-Host " URL: https://github.com/$repoFullName" -ForegroundColor Blue + + # Fetch skills + Write-Host "`n🔍 Searching for skills..." -ForegroundColor Cyan + + # Search for skills directory + $skillsPath = @("skills", ".github/skills", ".claude/skills") + $foundSkills = @() + foreach ($path in $skillsPath) { + try { + $rawOutput = gh api "repos/$repoFullName/contents/$path" 2>$null + if ($LASTEXITCODE -eq 0 -and $rawOutput -and $rawOutput -notmatch '"message"') { + $items = $rawOutput | ConvertFrom-Json | ForEach-Object { $_.name } + if ($items) { + Write-Host " 📂 Found $(@($items).Count) skills in $path" -ForegroundColor Green + foreach ($skillName in $items) { + $foundSkills += @{ name = $skillName; path = "$path/$skillName" } + Write-Host " - $skillName" -ForegroundColor Gray + } + break + } + } + } + catch { } + } + + if ($foundSkills.Count -eq 0) { + Write-Host " ⚠️ No skills directory found" -ForegroundColor Yellow + } + + # Add found skills + if ($foundSkills.Count -gt 0) { + Write-Host "`n✨ Adding skills to index..." -ForegroundColor Cyan + foreach ($skill in $foundSkills) { + $existingSkill = $index.skills | Where-Object { $_.name -eq $skill.name -and $_.source -eq $sourceId } + if (-not $existingSkill) { + $newSkill = [PSCustomObject]@{ + name = $skill.name + source = $sourceId + path = $skill.path + categories = @("community") + description = "$($skill.name) skill" + } + $index.skills += $newSkill + Write-Host " ✅ $($skill.name)" -ForegroundColor Green + } + else { + Write-Host " ⏭️ $($skill.name) (exists)" -ForegroundColor Gray + } + } + Save-SkillIndex -Index $index + } + exit 0 +} + +# カテゴリ一覧を表示 +if ($ListCategories) { + $index = Get-SkillIndex + if ($index) { + Write-Host "`n📁 利用可能なカテゴリ:" -ForegroundColor Cyan + $index.categories | ForEach-Object { + Write-Host " $($_.id)" -ForegroundColor White -NoNewline + Write-Host " - $($_.description)" -ForegroundColor Gray + } + } + exit 0 +} + +# ソース一覧を表示 +if ($ListSources) { + $index = Get-SkillIndex + if ($index) { + Write-Host "`n📦 利用可能なソース:" -ForegroundColor Cyan + $index.sources | ForEach-Object { + Write-Host " $($_.id)" -ForegroundColor White -NoNewline + Write-Host " [$($_.type)]" -ForegroundColor Yellow -NoNewline + Write-Host " - $($_.name)" -ForegroundColor Gray + Write-Host " $($_.url)" -ForegroundColor DarkCyan + } + } + exit 0 +} + +# インデックス更新 +if ($UpdateIndex) { + Write-Host "🔄 インデックスを更新中..." -ForegroundColor Cyan + + $sources = @( + @{ id = "anthropics-skills"; repo = "anthropics/skills"; path = "skills" }, + @{ id = "obra-superpowers"; repo = "obra/superpowers"; path = "skills" }, + @{ id = "composio-awesome"; repo = "ComposioHQ/awesome-claude-skills"; path = "" } + ) + + foreach ($src in $sources) { + Write-Host " 📥 $($src.repo) からスキルを取得中..." -ForegroundColor Gray + try { + $apiPath = if ($src.path) { "repos/$($src.repo)/contents/$($src.path)" } else { "repos/$($src.repo)/contents" } + $items = gh api $apiPath --jq '.[].name' 2>$null + if ($items) { + Write-Host " ✅ $(@($items).Count) 件取得" -ForegroundColor Green + } + } + catch { + Write-Warning " ⚠️ 取得失敗: $($_.Exception.Message)" + } + } + + Write-Host "`n💡 手動で references/skill-index.json を編集してスキルを追加してください。" -ForegroundColor Yellow + exit 0 +} + +# ローカル検索 (タグ検索対応) +function Search-LocalIndex { + param([string]$Query, [string]$Category, [string]$Source) + + $index = Get-SkillIndex + if (-not $index) { return @() } + + $results = $index.skills + $starred = Get-StarredSkills + + # タグ抽出 (#azure #bicep など) + $tags = @() + $cleanQuery = $Query + if ($Query -match '#(\w+)') { + $tags = [regex]::Matches($Query, '#(\w+)') | ForEach-Object { $_.Groups[1].Value } + $cleanQuery = ($Query -replace '#\w+', '').Trim() + } + + # キーワードフィルタ + if ($cleanQuery) { + $results = $results | Where-Object { + $_.name -like "*$cleanQuery*" -or $_.description -like "*$cleanQuery*" + } + } + + # タグフィルタ (カテゴリとマッチ) + if ($tags.Count -gt 0) { + $results = $results | Where-Object { + $skillCats = $_.categories | ForEach-Object { $_.ToLower() } + $matchedTags = $tags | Where-Object { $skillCats -contains $_.ToLower() } + $matchedTags.Count -gt 0 + } + } + + # カテゴリフィルタ + if ($Category) { + $results = $results | Where-Object { + $_.categories -contains $Category + } + } + + # ソースフィルタ + if ($Source) { + $results = $results | Where-Object { + $_.source -eq $Source + } + } + + # ソース情報とスター状態を付加 + $results | ForEach-Object { + $skill = $_ + $sourceInfo = $index.sources | Where-Object { $_.id -eq $skill.source } + $skillId = "$($skill.source)/$($skill.name)" + $skill | Add-Member -NotePropertyName "sourceUrl" -NotePropertyValue $sourceInfo.url -Force + $skill | Add-Member -NotePropertyName "sourceName" -NotePropertyValue $sourceInfo.name -Force + $skill | Add-Member -NotePropertyName "starred" -NotePropertyValue ($starred -contains $skillId) -Force + } + + # スター付きを先頭に + $results = $results | Sort-Object -Property @{Expression={$_.starred}; Descending=$true}, name + + return $results +} + +# 外部検索 (GitHub) +function Search-External { + param([string]$Query) + + Write-Host "`n🌐 GitHub を検索中..." -ForegroundColor Cyan + + $searchQuery = if ($Query) { "$Query filename:SKILL.md" } else { "filename:SKILL.md path:.github/skills" } + + try { + $results = gh search code $searchQuery --json repository,path,url --limit 15 2>&1 | ConvertFrom-Json + return $results + } + catch { + Write-Warning "GitHub 検索に失敗しました: $($_.Exception.Message)" + return @() + } +} + +# Web 検索 (最終フォールバック) +function Search-Web { + param([string]$Query, [switch]$OpenBrowser) + + $searchTerms = if ($Query) { + "claude skill $Query OR copilot skill $Query SKILL.md" + } else { + "claude skills SKILL.md github" + } + + $encodedQuery = [System.Web.HttpUtility]::UrlEncode($searchTerms) + + # 各検索エンジンの URL + $urls = @{ + "Google" = "https://www.google.com/search?q=$encodedQuery" + "Bing" = "https://www.bing.com/search?q=$encodedQuery" + "DuckDuckGo" = "https://duckduckgo.com/?q=$encodedQuery" + } + + Write-Host "`n🔎 Web 検索 URL:" -ForegroundColor Cyan + foreach ($engine in $urls.Keys) { + Write-Host " $engine : " -ForegroundColor Gray -NoNewline + Write-Host $urls[$engine] -ForegroundColor Blue + } + + if ($OpenBrowser) { + Write-Host "`n ブラウザで Google 検索を開きます..." -ForegroundColor Yellow + Start-Process $urls["Google"] + } + + return $urls +} + +# メイン検索処理 +Write-Host "`n🔍 スキルを検索中..." -ForegroundColor Cyan + +# インデックス読み込み +$index = Get-SkillIndex +if (-not $index) { exit 1 } + +# 自動更新チェック(インタラクティブモード時のみ) +if (-not $NoInteractive) { + $index = Invoke-AutoUpdateCheck -Index $index +} + +# 1. ローカル検索 +$localResults = Search-LocalIndex -Query $Query -Category $Category -Source $Source + +if ($localResults -and $localResults.Count -gt 0) { + Write-Host "`n📋 ローカルインデックスから $($localResults.Count) 件見つかりました:" -ForegroundColor Green + + $i = 1 + foreach ($skill in $localResults) { + $starMark = if ($skill.starred) { " ⭐" } else { "" } + Write-Host "`n[$i] " -ForegroundColor Yellow -NoNewline + Write-Host "$($skill.name)$starMark" -ForegroundColor White + Write-Host " 📝 $($skill.description)" -ForegroundColor Gray + Write-Host " 📦 $($skill.sourceName)" -ForegroundColor DarkCyan + Write-Host " 🏷️ $($skill.categories -join ', ')" -ForegroundColor DarkGray + Write-Host " 🔗 $($skill.sourceUrl)/$($skill.path)" -ForegroundColor Blue + $i++ + } +} +else { + Write-Host " ローカルインデックスに該当なし" -ForegroundColor Yellow +} + +# 2. 外部検索 (ローカルで見つからない、または強制検索) +$externalFound = $false +if ((-not $localResults -or $localResults.Count -eq 0) -or $SearchExternal) { + $externalResults = Search-External -Query $Query + + if ($externalResults -and $externalResults.Count -gt 0) { + $externalFound = $true + Write-Host "`n🌐 GitHub から $($externalResults.Count) 件見つかりました:" -ForegroundColor Green + + $i = 1 + foreach ($item in $externalResults) { + $repoName = $item.repository.nameWithOwner + Write-Host "`n[$i] " -ForegroundColor Yellow -NoNewline + Write-Host $repoName -ForegroundColor White + Write-Host " 📄 $($item.path)" -ForegroundColor Gray + Write-Host " 🔗 https://github.com/$repoName" -ForegroundColor Blue + $i++ + } + + Write-Host "`n💡 ヒント: -AddSource でリポジトリをインデックスに追加できます" -ForegroundColor Yellow + } + else { + Write-Host "`n GitHub でも見つかりませんでした" -ForegroundColor Yellow + } +} + +# 3. Web 検索 (ローカルも GitHub も見つからない場合、または -SearchWeb 指定時) +$totalFound = ($localResults.Count -gt 0) -or $externalFound +if ((-not $totalFound -and $Query) -or $SearchWeb) { + Write-Host "`n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray + if (-not $totalFound) { + Write-Host "📭 ローカル・GitHub ともに見つかりませんでした。" -ForegroundColor Yellow + } + Write-Host " Web 検索を試してみてください:" -ForegroundColor Yellow + Search-Web -Query $Query -OpenBrowser:$SearchWeb | Out-Null +} + +# 4. 類似スキル提案 (結果が少ない場合) +if ($Query -and $localResults.Count -lt 3) { + $similar = $index.skills | Where-Object { + $_.name -like "*$Query*" -and $_ -notin $localResults + } | Select-Object -First 3 + if ($similar) { + Write-Host "`n💡 こちらもおすすめ:" -ForegroundColor Cyan + foreach ($s in $similar) { + Write-Host " - $($s.name)" -ForegroundColor Gray + } + } +} + +# 5. 検索後のサジェスト表示 +if ($Query) { + Show-PostSearchSuggestions -Index $index -Query $Query -Results $localResults +} + +# 6. 他のリポジトリを探すか聞く(ローカル結果が少ない場合、インタラクティブモード時のみ) +if ($Query -and $localResults.Count -lt 5 -and (-not $SearchExternal) -and (-not $NoInteractive)) { + Invoke-DiscoverNewRepos -Query $Query +} + +Write-Host "" diff --git a/skills/skill-finder/scripts/search_skills.py b/skills/skill-finder/scripts/search_skills.py new file mode 100644 index 000000000..4b0a97c0e --- /dev/null +++ b/skills/skill-finder/scripts/search_skills.py @@ -0,0 +1,1002 @@ +#!/usr/bin/env python3 +""" +Skill Finder - Search and manage Agent Skills. + +Features: +- Local index search (fast, offline) +- GitHub Code Search API fallback +- Web search URLs as final fallback +- Add new sources (--add-source) +- Update index from sources (--update) +- Show skill details (--info) +- Install skills locally (--install) +- Star favorite skills (--star) +- Similar skill recommendations +- Statistics (--stats) +- Tag search (#azure #bicep) + +Author: yamapan (https://github.com/aktsmm) +License: MIT +""" + +import argparse +import json +import re +import subprocess +import sys +import urllib.parse +from datetime import date, datetime, timedelta +from pathlib import Path +from typing import Optional, List, Dict, Any + +# Paths +SCRIPT_DIR = Path(__file__).parent +INDEX_PATH = SCRIPT_DIR / ".." / "references" / "skill-index.json" +STARS_PATH = SCRIPT_DIR / ".." / "references" / "starred-skills.json" +INSTALL_DIR = Path.home() / ".skills" # Default install directory + +# Configuration +AUTO_UPDATE_DAYS = 7 # Auto-update if index is older than this + + +# ============================================================================= +# Index Management +# ============================================================================= + +def load_index() -> Optional[Dict[str, Any]]: + """Load skill index from JSON file.""" + if not INDEX_PATH.exists(): + print(f"⚠️ Index file not found: {INDEX_PATH}") + return None + with open(INDEX_PATH, "r", encoding="utf-8") as f: + return json.load(f) + + +def save_index(index: Dict[str, Any]) -> None: + """Save skill index to JSON file.""" + index["lastUpdated"] = date.today().isoformat() + with open(INDEX_PATH, "w", encoding="utf-8") as f: + json.dump(index, f, indent=2, ensure_ascii=False) + print(f"✅ Index saved: {INDEX_PATH}") + + +def is_index_outdated(index: Dict[str, Any]) -> bool: + """Check if index is older than AUTO_UPDATE_DAYS.""" + last_updated = index.get("lastUpdated", "") + if not last_updated: + return True + try: + last_date = datetime.fromisoformat(last_updated) + age = datetime.now() - last_date + return age > timedelta(days=AUTO_UPDATE_DAYS) + except ValueError: + return True + + +def check_and_auto_update(index: Dict[str, Any], silent: bool = False) -> Dict[str, Any]: + """Check if index needs update and prompt user.""" + if is_index_outdated(index): + last_updated = index.get("lastUpdated", "unknown") + if not silent: + print(f"\n⚠️ Index is outdated (last updated: {last_updated})") + try: + answer = input("🔄 Update now? [Y/n]: ").strip().lower() + if answer in ["", "y", "yes"]: + update_all_sources() + # Reload index + return load_index() or index + except (EOFError, KeyboardInterrupt): + print("\n Skipped") + return index + + +def load_stars() -> List[str]: + """Load starred skills list.""" + if not STARS_PATH.exists(): + return [] + with open(STARS_PATH, "r", encoding="utf-8") as f: + return json.load(f).get("starred", []) + + +def save_stars(starred: List[str]) -> None: + """Save starred skills list.""" + STARS_PATH.parent.mkdir(parents=True, exist_ok=True) + with open(STARS_PATH, "w", encoding="utf-8") as f: + json.dump({"starred": starred, "lastUpdated": date.today().isoformat()}, f, indent=2) + + +# ============================================================================= +# Search Functions +# ============================================================================= + +def search_local(index: Dict, query: str = "", category: str = "", source: str = "", + tags: List[str] = None) -> List[Dict]: + """Search skills in local index with optional tag support.""" + results = index.get("skills", []) + + # Keyword filter (supports #tag syntax) + if query: + # Extract tags from query + tag_pattern = r'#(\w+)' + extracted_tags = re.findall(tag_pattern, query) + clean_query = re.sub(tag_pattern, '', query).strip().lower() + + if extracted_tags: + tags = (tags or []) + extracted_tags + + if clean_query: + results = [s for s in results + if clean_query in s["name"].lower() + or clean_query in s.get("description", "").lower()] + + # Tag filter (matches categories) + if tags: + results = [s for s in results + if any(tag.lower() in [c.lower() for c in s.get("categories", [])] + for tag in tags)] + + # Category filter + if category: + results = [s for s in results if category in s.get("categories", [])] + + # Source filter + if source: + results = [s for s in results if s.get("source") == source] + + # Add source info and star status + sources = {s["id"]: s for s in index.get("sources", [])} + starred = load_stars() + for skill in results: + src = sources.get(skill.get("source"), {}) + skill["sourceUrl"] = src.get("url", "") + skill["sourceName"] = src.get("name", skill.get("source", "")) + skill["starred"] = f"{skill['source']}/{skill['name']}" in starred + + # Sort: starred first + results.sort(key=lambda x: (not x.get("starred", False), x["name"])) + + return results + + +def search_github(query: str) -> List[Dict]: + """Search skills on GitHub using gh CLI.""" + print("\n🌐 Searching GitHub...") + + search_query = f"{query} filename:SKILL.md" if query else "filename:SKILL.md path:.github/skills" + + try: + result = subprocess.run( + ["gh", "search", "code", search_query, "--json", "repository,path,url", "--limit", "15"], + capture_output=True, text=True, timeout=30 + ) + if result.returncode == 0: + return json.loads(result.stdout) + except FileNotFoundError: + print(" ⚠️ GitHub CLI (gh) not found. Install it for external search.") + except subprocess.TimeoutExpired: + print(" ⚠️ GitHub search timed out.") + except json.JSONDecodeError: + print(" ⚠️ Invalid response from GitHub.") + + return [] + + +def show_web_search_urls(query: str) -> None: + """Show web search URLs for manual search.""" + terms = f"claude skill {query} OR copilot skill {query} SKILL.md" if query else "claude skills SKILL.md github" + encoded = urllib.parse.quote(terms) + + print("\n🔎 Web Search URLs:") + print(f" Google: https://www.google.com/search?q={encoded}") + print(f" Bing: https://www.bing.com/search?q={encoded}") + print(f" DuckDuckGo: https://duckduckgo.com/?q={encoded}") + + +# ============================================================================= +# Source Management +# ============================================================================= + +def add_source(repo_url: str) -> None: + """Add a new source repository to the index.""" + index = load_index() + if not index: + return + + # Parse GitHub URL + match = re.search(r"github\.com[/:]([^/]+)/([^/]+)", repo_url) + if not match: + print(f"❌ Invalid GitHub URL: {repo_url}") + return + + owner, repo = match.groups() + repo = repo.rstrip(".git") + repo_full = f"{owner}/{repo}" + + # Check if already exists + for src in index.get("sources", []): + if repo_full in src.get("url", ""): + print(f"⚠️ Source already exists: {src['id']}") + # Still try to update skills + update_source_skills(index, src["id"], repo_full) + return + + # Create source ID + source_id = re.sub(r'[^a-z0-9-]', '-', repo.lower()) + + # Add source + new_source = { + "id": source_id, + "name": repo, + "url": f"https://github.com/{repo_full}", + "type": "community", + "description": f"Skills from {repo_full}" + } + index["sources"].append(new_source) + save_index(index) + + print(f"\n📦 Added new source:") + print(f" ID: {source_id}") + print(f" URL: https://github.com/{repo_full}") + + # Fetch skills + update_source_skills(index, source_id, repo_full) + + +def update_source_skills(index: Dict, source_id: str, repo_full: str) -> None: + """Fetch and update skills from a source repository using GitHub Code Search API.""" + print("\n🔍 Searching for skills...") + found_skills = [] + + # Method 1: Use GitHub Code Search API to find all SKILL.md files + try: + result = subprocess.run( + ["gh", "api", "search/code", "-f", f"q=repo:{repo_full} filename:SKILL.md"], + capture_output=True, text=True, timeout=30 + ) + if result.returncode == 0: + data = json.loads(result.stdout) + items = data.get("items", []) + if items: + # Extract unique parent directories from SKILL.md paths + seen_paths = set() + for item in items: + path = item.get("path", "") + if path.endswith("SKILL.md"): + # Get parent directory (skill folder) + parent = "/".join(path.split("/")[:-1]) + if parent and parent not in seen_paths: + seen_paths.add(parent) + skill_name = parent.split("/")[-1] + found_skills.append({"name": skill_name, "path": parent}) + + if found_skills: + print(f" 📂 Found {len(found_skills)} skills via Code Search") + for skill in found_skills: + print(f" - {skill['name']} ({skill['path']})") + except subprocess.TimeoutExpired: + print(" ⚠️ Code Search timeout, falling back to directory scan...") + except Exception as e: + print(f" ⚠️ Code Search failed ({e}), falling back to directory scan...") + + # Method 2: Fallback to directory-based search if Code Search fails or returns empty + if not found_skills: + # Check common skill directories + skills_paths = ["skills", ".github/skills", ".claude/skills", "scientific-skills"] + found_in_subdir = False + + for path in skills_paths: + try: + result = subprocess.run( + ["gh", "api", f"repos/{repo_full}/contents/{path}"], + capture_output=True, text=True, timeout=10 + ) + if result.returncode == 0 and "message" not in result.stdout[:50]: + items = json.loads(result.stdout) + if isinstance(items, list): + print(f" 📂 Found {len(items)} items in {path}") + for item in items: + name = item.get("name", "") + if name and item.get("type") == "dir": + found_skills.append({"name": name, "path": f"{path}/{name}"}) + print(f" - {name}") + found_in_subdir = True + break + except subprocess.TimeoutExpired: + print(f" ⚠️ Timeout checking {path}") + except FileNotFoundError: + print(" ❌ GitHub CLI (gh) not found.") + break + except Exception: + # Silently ignore other errors (JSON parse errors, network issues, etc.) + # and continue checking other paths + pass + + # If no skills/ directory found, check root for SKILL.md in subdirectories + if not found_in_subdir: + try: + result = subprocess.run( + ["gh", "api", f"repos/{repo_full}/contents"], + capture_output=True, text=True, timeout=10 + ) + if result.returncode == 0: + items = json.loads(result.stdout) + if isinstance(items, list): + dirs = [item for item in items if item.get("type") == "dir"] + skill_dirs = [] + for d in dirs: + name = d.get("name", "") + if name.startswith(".") or name in ["docs", "examples", "tests", "node_modules", "dist", "build"]: + continue + check_result = subprocess.run( + ["gh", "api", f"repos/{repo_full}/contents/{name}/SKILL.md"], + capture_output=True, text=True, timeout=5 + ) + if check_result.returncode == 0 and "message" not in check_result.stdout[:50]: + skill_dirs.append({"name": name, "path": name}) + + if skill_dirs: + print(f" 📂 Found {len(skill_dirs)} skills at root level") + for skill in skill_dirs: + found_skills.append(skill) + print(f" - {skill['name']}") + except subprocess.TimeoutExpired: + print(" ⚠️ Timeout checking root") + except Exception: + # Silently ignore errors when checking root directory + # (e.g., rate limits, permission issues) + pass + + # Add found skills to index + if found_skills: + print("\n✨ Adding skills to index...") + added = 0 + for skill in found_skills: + existing = [s for s in index["skills"] + if s["name"] == skill["name"] and s["source"] == source_id] + if not existing: + index["skills"].append({ + "name": skill["name"], + "source": source_id, + "path": skill["path"], + "categories": ["community"], + "description": f"{skill['name']} skill" + }) + print(f" ✅ {skill['name']}") + added += 1 + else: + print(f" ⏭️ {skill['name']} (exists)") + if added > 0: + save_index(index) + else: + print(" ⚠️ No skills found") + + +def update_all_sources() -> None: + """Update skills from all registered sources.""" + index = load_index() + if not index: + return + + print("🔄 Updating all sources...") + sources = index.get("sources", []) + + for src in sources: + url = src.get("url", "") + match = re.search(r"github\.com/([^/]+/[^/]+)", url) + if match: + repo_full = match.group(1) + print(f"\n📦 {src['id']} ({repo_full})") + update_source_skills(index, src["id"], repo_full) + + print("\n✅ Update complete!") + + +# ============================================================================= +# Skill Info & Install +# ============================================================================= + +def show_skill_info(skill_name: str) -> None: + """Show detailed information about a skill.""" + index = load_index() + if not index: + return + + # Find skill + skills = [s for s in index.get("skills", []) if s["name"].lower() == skill_name.lower()] + if not skills: + print(f"❌ Skill not found: {skill_name}") + # Suggest similar + similar = find_similar_skills(index, skill_name) + if similar: + print("\n💡 Did you mean:") + for s in similar[:5]: + print(f" - {s['name']}") + return + + skill = skills[0] + sources = {s["id"]: s for s in index.get("sources", [])} + src = sources.get(skill.get("source"), {}) + + print(f"\n📦 {skill['name']}") + print("=" * 50) + print(f"📝 Description: {skill.get('description', 'N/A')}") + print(f"📁 Source: {src.get('name', skill.get('source', 'Unknown'))}") + print(f"🏷️ Categories: {', '.join(skill.get('categories', []))}") + print(f"📂 Path: {skill.get('path', 'N/A')}") + + url = src.get("url", "") + path = skill.get("path", "") + if url and path: + full_url = f"{url}/tree/main/{path}" + print(f"🔗 URL: {full_url}") + + # Try to fetch SKILL.md content + if url and path: + print("\n📄 Fetching SKILL.md...") + match = re.search(r"github\.com/([^/]+/[^/]+)", url) + if match: + repo_full = match.group(1) + try: + result = subprocess.run( + ["gh", "api", f"repos/{repo_full}/contents/{path}/SKILL.md", + "-H", "Accept: application/vnd.github.raw"], + capture_output=True, text=True, timeout=10 + ) + if result.returncode == 0: + print("\n" + "-" * 50) + # Show first 50 lines + lines = result.stdout.split('\n')[:50] + print('\n'.join(lines)) + if len(result.stdout.split('\n')) > 50: + print("\n... (truncated)") + except Exception as e: + print(f" ⚠️ Could not fetch: {e}") + + +def install_skill(skill_name: str, target_dir: str = None) -> None: + """Install a skill to local directory.""" + index = load_index() + if not index: + return + + # Find skill + skills = [s for s in index.get("skills", []) if s["name"].lower() == skill_name.lower()] + if not skills: + print(f"❌ Skill not found: {skill_name}") + return + + skill = skills[0] + sources = {s["id"]: s for s in index.get("sources", [])} + src = sources.get(skill.get("source"), {}) + url = src.get("url", "") + path = skill.get("path", "") + + if not url or not path: + print(f"❌ Cannot install: missing URL or path information") + return + + # Determine target directory + if target_dir: + install_path = Path(target_dir) / skill["name"] + else: + install_path = INSTALL_DIR / skill["name"] + + match = re.search(r"github\.com/([^/]+/[^/]+)", url) + if not match: + print(f"❌ Invalid source URL") + return + + repo_full = match.group(1) + + print(f"📥 Installing {skill['name']}...") + print(f" From: {url}") + print(f" To: {install_path}") + + # Create directory + install_path.mkdir(parents=True, exist_ok=True) + + # Download files using gh CLI + try: + # Get file list + result = subprocess.run( + ["gh", "api", f"repos/{repo_full}/contents/{path}"], + capture_output=True, text=True, timeout=15 + ) + if result.returncode != 0: + print(f"❌ Failed to list files: {result.stderr}") + return + + items = json.loads(result.stdout) + if not isinstance(items, list): + items = [items] + + # Download each file + for item in items: + if item.get("type") == "file": + file_name = item.get("name", "") + download_url = item.get("download_url", "") + if file_name and download_url: + print(f" 📄 {file_name}") + # Use curl + file_path = install_path / file_name + dl_result = subprocess.run( + ["curl", "-sL", "-o", str(file_path), download_url], + timeout=30 + ) + if dl_result.returncode != 0: + print(f" ⚠️ Failed to download") + + print(f"\n✅ Installed to: {install_path}") + + except Exception as e: + print(f"❌ Installation failed: {e}") + + +# ============================================================================= +# Star Management +# ============================================================================= + +def star_skill(skill_name: str, unstar: bool = False) -> None: + """Star or unstar a skill.""" + index = load_index() + if not index: + return + + # Find skill + skills = [s for s in index.get("skills", []) if s["name"].lower() == skill_name.lower()] + if not skills: + print(f"❌ Skill not found: {skill_name}") + return + + skill = skills[0] + skill_id = f"{skill['source']}/{skill['name']}" + + starred = load_stars() + + if unstar: + if skill_id in starred: + starred.remove(skill_id) + save_stars(starred) + print(f"☆ Unstarred: {skill['name']}") + else: + print(f"⚠️ Skill is not starred: {skill['name']}") + else: + if skill_id not in starred: + starred.append(skill_id) + save_stars(starred) + print(f"⭐ Starred: {skill['name']}") + else: + print(f"⚠️ Already starred: {skill['name']}") + + +def list_starred() -> None: + """List all starred skills.""" + starred = load_stars() + if not starred: + print("☆ No starred skills yet.") + print(" Use --star to star a skill.") + return + + print(f"\n⭐ Starred Skills ({len(starred)}):") + for skill_id in starred: + print(f" - {skill_id}") + + +# ============================================================================= +# Similar Skills & Recommendations +# ============================================================================= + +def find_similar_skills(index: Dict, skill_name: str, limit: int = 5) -> List[Dict]: + """Find skills similar to the given skill name or query.""" + skills = index.get("skills", []) + + # First try to find the exact skill + target_skill = None + for s in skills: + if s["name"].lower() == skill_name.lower(): + target_skill = s + break + + if target_skill: + # Find by matching categories + target_cats = set(target_skill.get("categories", [])) + similar = [] + for s in skills: + if s["name"] != target_skill["name"]: + s_cats = set(s.get("categories", [])) + overlap = len(target_cats & s_cats) + if overlap > 0: + similar.append((overlap, s)) + similar.sort(key=lambda x: -x[0]) + return [s[1] for s in similar[:limit]] + else: + # Fuzzy match by name + query_lower = skill_name.lower() + similar = [] + for s in skills: + name_lower = s["name"].lower() + # Simple similarity: count matching characters + score = sum(1 for c in query_lower if c in name_lower) + if score > 0: + similar.append((score, s)) + similar.sort(key=lambda x: -x[0]) + return [s[1] for s in similar[:limit]] + + +def show_similar(skill_name: str) -> None: + """Show skills similar to the given skill.""" + index = load_index() + if not index: + return + + similar = find_similar_skills(index, skill_name) + if similar: + print(f"\n💡 Skills similar to '{skill_name}':") + for s in similar: + print(f" - {s['name']} ({', '.join(s.get('categories', [])[:3])})") + else: + print(f" No similar skills found.") + + +# ============================================================================= +# Post-Search Suggestions +# ============================================================================= + +def show_post_search_suggestions(index: Dict, query: str, results: List[Dict]) -> None: + """Show helpful suggestions after search.""" + print("\n" + "━" * 50) + print("💡 Suggestions") + + # 1. Related categories + if results: + all_categories = set() + for r in results[:3]: + all_categories.update(r.get("categories", [])) + if all_categories: + cats_str = ", ".join(list(all_categories)[:3]) + print(f" 🏷️ Related categories: {cats_str}") + print(f" → Example: python scripts/search_skills.py \"#{list(all_categories)[0]}\"") + + # 2. Similar skills + similar = find_similar_skills(index, query, limit=3) + unshown = [s for s in similar if s not in results] + if unshown: + print(f"\n 🔍 You might also like:") + for s in unshown[:3]: + print(f" - {s['name']}: {s.get('description', '')[:40]}") + + # 3. Starred skills count + starred = load_stars() + if starred and len(starred) > 0: + print(f"\n ⭐ Your favorites: {len(starred)} skills") + + +def prompt_discover_new_repos(query: str) -> None: + """Ask user if they want to discover new repositories.""" + print("\n" + "━" * 50) + try: + answer = input("🌐 Search for more repositories? [y/N]: ").strip().lower() + if answer in ["y", "yes"]: + print("\n🔍 Searching GitHub for related repositories...") + discover_new_repos(query) + except (EOFError, KeyboardInterrupt): + print("\n Skipped") + + +def discover_new_repos(query: str) -> None: + """Search for new skill repositories on GitHub.""" + search_terms = f"{query} SKILL.md agent skills" if query else "SKILL.md agent skills claude copilot" + + try: + # Repository search + result = subprocess.run( + ["gh", "search", "repos", search_terms, "--json", "nameWithOwner,description,stargazersCount", "--limit", "10"], + capture_output=True, text=True, timeout=30 + ) + if result.returncode == 0: + repos = json.loads(result.stdout) + if repos: + print(f"\n📦 Found {len(repos)} repositories:") + for i, repo in enumerate(repos, 1): + name = repo.get("nameWithOwner", "") + desc = repo.get("description", "")[:50] or "No description" + stars = repo.get("stargazersCount", 0) + print(f"\n [{i}] {name} ⭐{stars}") + print(f" {desc}") + + # Ask to add to index + print("\n" + "-" * 40) + try: + choice = input("📥 Enter repository number to add (blank to skip): ").strip() + if choice.isdigit(): + idx = int(choice) - 1 + if 0 <= idx < len(repos): + repo_name = repos[idx].get("nameWithOwner", "") + add_source(f"https://github.com/{repo_name}") + except (EOFError, KeyboardInterrupt): + pass # User cancelled input, skip adding repository + else: + print(" No matching repositories found") + else: + print(f" ⚠️ Search failed: {result.stderr}") + except FileNotFoundError: + print(" ⚠️ GitHub CLI (gh) not found") + except subprocess.TimeoutExpired: + print(" ⚠️ Search timed out") + except Exception as e: + print(f" ⚠️ Error: {e}") + + +# ============================================================================= +# Statistics +# ============================================================================= + +def show_statistics() -> None: + """Show skill index statistics.""" + index = load_index() + if not index: + return + + skills = index.get("skills", []) + sources = index.get("sources", []) + categories = index.get("categories", []) + starred = load_stars() + + print("\n📊 Skill Index Statistics") + print("=" * 50) + print(f"📅 Last Updated: {index.get('lastUpdated', 'Unknown')}") + print(f"📦 Total Skills: {len(skills)}") + print(f"📁 Sources: {len(sources)}") + print(f"🏷️ Categories: {len(categories)}") + print(f"⭐ Starred: {len(starred)}") + + # Skills per source + print("\n📦 Skills by Source:") + source_counts = {} + for s in skills: + src = s.get("source", "unknown") + source_counts[src] = source_counts.get(src, 0) + 1 + for src, count in sorted(source_counts.items(), key=lambda x: -x[1]): + print(f" {src}: {count}") + + # Skills per category + print("\n🏷️ Skills by Category:") + cat_counts = {} + for s in skills: + for cat in s.get("categories", []): + cat_counts[cat] = cat_counts.get(cat, 0) + 1 + for cat, count in sorted(cat_counts.items(), key=lambda x: -x[1])[:10]: + print(f" {cat}: {count}") + + +# ============================================================================= +# Dependency Check +# ============================================================================= + +def check_dependencies() -> None: + """Check if required tools are installed.""" + print("\n🔧 Checking Dependencies...") + + tools = [ + ("gh", "GitHub CLI - Required for external search and install"), + ("curl", "cURL - Required for downloading files"), + ("python3", "Python 3 - You're running this!"), + ] + + for tool, desc in tools: + try: + result = subprocess.run([tool, "--version"], capture_output=True, timeout=5) + if result.returncode == 0: + version = result.stdout.decode().split('\n')[0][:50] + print(f" ✅ {tool}: {version}") + else: + print(f" ❌ {tool}: Not working properly") + except FileNotFoundError: + print(f" ❌ {tool}: Not found - {desc}") + except Exception as e: + print(f" ⚠️ {tool}: Error - {e}") + + +# ============================================================================= +# Output Functions +# ============================================================================= + +def print_results(results: List[Dict], title: str) -> None: + """Print search results.""" + print(f"\n📋 {title}:") + for i, skill in enumerate(results, 1): + star = "⭐" if skill.get("starred") else "" + print(f"\n[{i}] {skill['name']} {star}") + print(f" 📝 {skill.get('description', '')}") + print(f" 📦 {skill.get('sourceName', skill.get('source', ''))}") + print(f" 🏷️ {', '.join(skill.get('categories', []))}") + url = skill.get('sourceUrl', '') + path = skill.get('path', '') + if url and path: + print(f" 🔗 {url}/{path}") + + +def list_categories(index: Dict) -> None: + """List available categories.""" + print("\n📁 Available Categories:") + for cat in index.get("categories", []): + print(f" {cat['id']} - {cat.get('description', cat.get('name', ''))}") + + +def list_sources(index: Dict) -> None: + """List available sources.""" + print("\n📦 Available Sources:") + for src in index.get("sources", []): + print(f" {src['id']} [{src.get('type', 'community')}]") + print(f" {src.get('name', '')} - {src.get('url', '')}") + + +# ============================================================================= +# Main +# ============================================================================= + +def main(): + parser = argparse.ArgumentParser( + description="Skill Finder - Search and manage Agent Skills", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s "pdf" Search for skills + %(prog)s "#azure #bicep" Search by tags + %(prog)s --category development Filter by category + %(prog)s --info skill-name Show skill details + %(prog)s --install skill-name Install skill locally + %(prog)s --star skill-name Star a skill + %(prog)s --similar skill-name Find similar skills + %(prog)s --update Update all sources + %(prog)s --stats Show statistics + """ + ) + + # Search arguments + parser.add_argument("query", nargs="?", default="", help="Search keyword (supports #tags)") + parser.add_argument("--category", "-c", help="Filter by category") + parser.add_argument("--source", "-s", help="Filter by source") + parser.add_argument("--external", "-e", action="store_true", help="Also search GitHub") + parser.add_argument("--web", "-w", action="store_true", help="Show web search URLs") + + # List arguments + parser.add_argument("--list-categories", action="store_true", help="List categories") + parser.add_argument("--list-sources", action="store_true", help="List sources") + parser.add_argument("--list-starred", action="store_true", help="List starred skills") + + # Management arguments + parser.add_argument("--add-source", metavar="URL", help="Add a new source repository") + parser.add_argument("--update", action="store_true", help="Update all sources") + + # Skill actions + parser.add_argument("--info", metavar="SKILL", help="Show skill details") + parser.add_argument("--install", metavar="SKILL", help="Install skill locally") + parser.add_argument("--install-dir", metavar="DIR", help="Installation directory") + parser.add_argument("--star", metavar="SKILL", help="Star a skill") + parser.add_argument("--unstar", metavar="SKILL", help="Unstar a skill") + parser.add_argument("--similar", metavar="SKILL", help="Find similar skills") + + # Other + parser.add_argument("--stats", action="store_true", help="Show statistics") + parser.add_argument("--check", action="store_true", help="Check dependencies") + parser.add_argument("--no-interactive", action="store_true", + help="Disable interactive prompts (for CI/automation)") + + args = parser.parse_args() + + # Action handlers + if args.check: + check_dependencies() + return + + if args.add_source: + add_source(args.add_source) + return + + if args.update: + update_all_sources() + return + + if args.info: + show_skill_info(args.info) + return + + if args.install: + install_skill(args.install, args.install_dir) + return + + if args.star: + star_skill(args.star) + return + + if args.unstar: + star_skill(args.unstar, unstar=True) + return + + if args.list_starred: + list_starred() + return + + if args.similar: + show_similar(args.similar) + return + + if args.stats: + show_statistics() + return + + # Load index + index = load_index() + if not index: + sys.exit(1) + + # 自動更新チェック(1週間以上経過していたら) + if not args.no_interactive: + index = check_and_auto_update(index) + + # List mode + if args.list_categories: + list_categories(index) + return + + if args.list_sources: + list_sources(index) + return + + # Search mode + print("\n🔍 Searching skills...") + + # Local search + local_results = search_local(index, args.query, args.category, args.source) + + if local_results: + print_results(local_results, f"Found {len(local_results)} skills in local index") + else: + print(" No matches in local index") + + # External search + external_found = False + if not local_results or args.external: + github_results = search_github(args.query) + if github_results: + external_found = True + print(f"\n🌐 Found {len(github_results)} on GitHub:") + for i, item in enumerate(github_results, 1): + repo = item.get("repository", {}).get("nameWithOwner", "") + print(f"\n[{i}] {repo}") + print(f" 📄 {item.get('path', '')}") + print(f" 🔗 https://github.com/{repo}") + print("\n💡 Tip: Use --add-source to add good repos to your index") + else: + print("\n No matches on GitHub") + + # Web search fallback + if not local_results and not external_found and args.query: + print("\n" + "━" * 50) + print("📭 No matches found. Try web search:") + show_web_search_urls(args.query) + + if args.web: + show_web_search_urls(args.query) + + # Show similar if few results + if args.query and len(local_results) < 3: + similar = find_similar_skills(index, args.query, limit=3) + if similar: + print(f"\n💡 You might also like:") + for s in similar: + if s not in local_results: + print(f" - {s['name']}") + + # 検索後のサジェスト表示 + if args.query: + show_post_search_suggestions(index, args.query, local_results) + + # 他のリポジトリを探すか聞く(ローカル結果が少ない場合、インタラクティブモード時のみ) + if args.query and len(local_results) < 5 and not args.external and not args.no_interactive: + prompt_discover_new_repos(args.query) + + +if __name__ == "__main__": + main()