Commit 3c8952e467de88621ecff0120a9b11c03a35ad91
1 parent
5454b2cd
feat: track template agent skills and sync latest updates
Showing
10 changed files
with
613 additions
and
12 deletions
.gitignore
| ... | ... | @@ -62,6 +62,15 @@ tmp/ |
| 62 | 62 | |
| 63 | 63 | # === 运行时文件 (不提交) === |
| 64 | 64 | .claude/ |
| 65 | +!system/templates/*/.claude/ | |
| 66 | +system/templates/*/.claude/* | |
| 67 | +!system/templates/*/.claude/skills/ | |
| 68 | +!system/templates/*/.claude/skills/** | |
| 69 | +!system/templates/*/.claude/*.lock | |
| 70 | +!system/agents/*/.claude/ | |
| 71 | +system/agents/*/.claude/* | |
| 72 | +!system/agents/*/.claude/skills/ | |
| 73 | +!system/agents/*/.claude/skills/** | |
| 65 | 74 | .pylibs/ |
| 66 | 75 | nohup.out |
| 67 | 76 | data/agents/ | ... | ... |
system/agents/master/.claude/scheduled_tasks.json
| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | "cron": "*/5 * * * *", |
| 6 | 6 | "prompt": "执行系统巡检:读取 plan.md 和 todo.md,检查所有任务状态。已完成的更新标记,卡住的分析原因后自主处理(重新分发或修复),未开始的按优先级立即分发。不要请示用户,直接行动。", |
| 7 | 7 | "createdAt": 1775231859266, |
| 8 | + "lastFiredAt": 1775235913481, | |
| 8 | 9 | "recurring": true |
| 9 | 10 | }, |
| 10 | 11 | { |
| ... | ... | @@ -12,6 +13,22 @@ |
| 12 | 13 | "cron": "*/30 * * * *", |
| 13 | 14 | "prompt": "生成系统状态日报,统计所有 Agent 任务完成率和异常情况,写入 memory/daily/ 今日文件。", |
| 14 | 15 | "createdAt": 1775231859272, |
| 16 | + "lastFiredAt": 1775235574165, | |
| 17 | + "recurring": true | |
| 18 | + }, | |
| 19 | + { | |
| 20 | + "id": "7868eeb3", | |
| 21 | + "cron": "*/5 * * * *", | |
| 22 | + "prompt": "执行系统巡检:读取 plan.md 和 todo.md,检查所有任务状态。已完成的更新标记,卡住的分析原因后自主处理(重新分发或修复),未开始的按优先级立即分发。不要请示用户,直接行动。", | |
| 23 | + "createdAt": 1775235820776, | |
| 24 | + "recurring": true, | |
| 25 | + "lastFiredAt": 1775235971536 | |
| 26 | + }, | |
| 27 | + { | |
| 28 | + "id": "695f0a30", | |
| 29 | + "cron": "*/30 * * * *", | |
| 30 | + "prompt": "生成系统状态日报,统计所有 Agent 任务完成率和异常情况,写入 memory/daily/ 今日文件。", | |
| 31 | + "createdAt": 1775235825837, | |
| 15 | 32 | "recurring": true |
| 16 | 33 | } |
| 17 | 34 | ] | ... | ... |
system/templates/claude-youtube-skills/.claude/skills/skills.md
0 → 100644
system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/SKILL.md
0 → 100644
| 1 | +--- | |
| 2 | +name: youtube-competitor-analyzer | |
| 3 | +description: "Find and analyze YouTube competitor channels using YouTube Data API v3. Discover competitors through keyword search, category matching, content similarity, and related channel discovery. Compare metrics, content strategies, and market positioning. Use when users want to (1) Find competitors for their YouTube channel, (2) Analyze competitor performance metrics, (3) Compare their channel against competitors, (4) Identify content gaps and opportunities, (5) Benchmark against similar creators, (6) Generate competitive analysis reports. Requires user's YouTube Data API v3 key." | |
| 4 | +--- | |
| 5 | + | |
| 6 | +# YouTube Competitor Analyzer | |
| 7 | + | |
| 8 | +Find and analyze competitor channels using YouTube Data API v3. | |
| 9 | + | |
| 10 | +## Setup | |
| 11 | + | |
| 12 | +1. **API Key**: Get from [Google Cloud Console](https://console.cloud.google.com/apis/credentials) - enable YouTube Data API v3 | |
| 13 | +2. **Input**: User's channel (for context) OR list of competitor channels to analyze directly | |
| 14 | + | |
| 15 | +## API Endpoints | |
| 16 | + | |
| 17 | +``` | |
| 18 | +BASE_URL = https://www.googleapis.com/youtube/v3 | |
| 19 | + | |
| 20 | +# Search channels | |
| 21 | +GET /search?part=snippet&q={query}&type=channel&maxResults={n}&key={API_KEY} | |
| 22 | + | |
| 23 | +# Channel details | |
| 24 | +GET /channels?part=snippet,statistics,contentDetails,brandingSettings&id={ids}&key={API_KEY} | |
| 25 | + | |
| 26 | +# Channel videos | |
| 27 | +GET /search?part=snippet&channelId={id}&order=date&type=video&maxResults=50&key={API_KEY} | |
| 28 | + | |
| 29 | +# Video details | |
| 30 | +GET /videos?part=snippet,statistics,contentDetails&id={ids}&key={API_KEY} | |
| 31 | +``` | |
| 32 | + | |
| 33 | +## Competitor Discovery Methods | |
| 34 | + | |
| 35 | +### 1. Keyword Search | |
| 36 | +Extract keywords from user's channel (description, title, brandingSettings.keywords), search for channels: | |
| 37 | +``` | |
| 38 | +GET /search?q={keyword}&type=channel&maxResults=10 | |
| 39 | +``` | |
| 40 | + | |
| 41 | +### 2. Content Similarity | |
| 42 | +Get user's recent video titles, extract frequent words (>4 chars), search channels with those terms. | |
| 43 | + | |
| 44 | +### 3. Category Search | |
| 45 | +Search within same YouTube category as user's channel. | |
| 46 | + | |
| 47 | +### 4. Related Discovery | |
| 48 | +Search using user's video titles/descriptions to find channels creating similar content. | |
| 49 | + | |
| 50 | +### 5. Direct Input | |
| 51 | +User provides specific channels to analyze: @handles, channel IDs, or URLs. | |
| 52 | + | |
| 53 | +## Competitor Ranking | |
| 54 | + | |
| 55 | +```javascript | |
| 56 | +// Size similarity (log scale) | |
| 57 | +sizeSimilarity = 1 - Math.abs(Math.log10(compSubs+1) - Math.log10(targetSubs+1)) / 10; | |
| 58 | + | |
| 59 | +// Engagement per video | |
| 60 | +engagementRate = viewCount / (videoCount || 1); | |
| 61 | + | |
| 62 | +// Overall score | |
| 63 | +overallScore = sizeSimilarity * 0.3 + relevanceScore * 0.7; | |
| 64 | +``` | |
| 65 | + | |
| 66 | +Sort by overallScore, return top 10-15. | |
| 67 | + | |
| 68 | +## Comparative Analysis | |
| 69 | + | |
| 70 | +For each competitor, extract: | |
| 71 | +| Metric | Description | | |
| 72 | +|--------|-------------| | |
| 73 | +| Subscribers | Direct count | | |
| 74 | +| Total Views | Channel lifetime views | | |
| 75 | +| Video Count | Total videos published | | |
| 76 | +| Views/Video | Average performance | | |
| 77 | +| Upload Frequency | Videos per month | | |
| 78 | +| Channel Age | Days since creation | | |
| 79 | + | |
| 80 | +Compare user channel vs competitor averages: | |
| 81 | +- Above/below average positioning | |
| 82 | +- Growth rate comparison | |
| 83 | +- Content volume gaps | |
| 84 | + | |
| 85 | +## Content Gap Analysis | |
| 86 | + | |
| 87 | +Compare across competitors: | |
| 88 | +- Content types they cover vs user doesn't | |
| 89 | +- Duration preferences | |
| 90 | +- Upload schedules | |
| 91 | +- Title/thumbnail patterns | |
| 92 | +- High-performing topics | |
| 93 | + | |
| 94 | +## Output Report Structure | |
| 95 | + | |
| 96 | +```markdown | |
| 97 | +# Competitive Analysis Report | |
| 98 | +## Executive Summary | |
| 99 | +- Competitors found, key positioning insights | |
| 100 | +## Competitor Table | |
| 101 | +| Channel | Subs | Videos | Views | Views/Video | Score | | |
| 102 | +## Competitive Positioning | |
| 103 | +- User vs competitor averages | |
| 104 | +- Market position assessment | |
| 105 | +## Content Strategy Comparison | |
| 106 | +- What competitors do differently | |
| 107 | +- Common patterns among top performers | |
| 108 | +## Opportunities | |
| 109 | +- Content gaps to fill | |
| 110 | +- Underserved niches | |
| 111 | +- Schedule optimization | |
| 112 | +## Recommendations | |
| 113 | +- Strategic actions based on analysis | |
| 114 | +``` | |
| 115 | + | |
| 116 | +## Niche-Specific Search Terms | |
| 117 | + | |
| 118 | +For spiritual/wellness channels: | |
| 119 | +``` | |
| 120 | +meditation, mindfulness, yoga, spiritual, consciousness, wellness, self-help, awakening | |
| 121 | +``` | |
| 122 | + | |
| 123 | +For tech channels: | |
| 124 | +``` | |
| 125 | +tech review, unboxing, tutorial, how to, comparison, tips, gadget | |
| 126 | +``` | |
| 127 | + | |
| 128 | +For gaming: | |
| 129 | +``` | |
| 130 | +gameplay, let's play, walkthrough, gaming, stream, esports | |
| 131 | +``` | |
| 132 | + | |
| 133 | +## Quota Optimization | |
| 134 | + | |
| 135 | +- Limit discovery to 20-30 initial channels | |
| 136 | +- Detailed analysis for top 10-15 only | |
| 137 | +- Batch video IDs (max 50 per call) | |
| 138 | +- Cache results when comparing multiple times | ... | ... |
system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/references/api_reference.md
0 → 100644
| 1 | +# YouTube Data API v3 Reference | |
| 2 | + | |
| 3 | +## Authentication | |
| 4 | + | |
| 5 | +All requests require `key={API_KEY}` parameter. | |
| 6 | + | |
| 7 | +Get API key: [Google Cloud Console](https://console.cloud.google.com/apis/credentials) | |
| 8 | +1. Create project → Enable YouTube Data API v3 → Create credentials → API Key | |
| 9 | + | |
| 10 | +## Channels Endpoint | |
| 11 | + | |
| 12 | +``` | |
| 13 | +GET https://www.googleapis.com/youtube/v3/channels | |
| 14 | +``` | |
| 15 | + | |
| 16 | +### Parameters | |
| 17 | +| Param | Required | Description | | |
| 18 | +|-------|----------|-------------| | |
| 19 | +| part | Yes | snippet,statistics,contentDetails,brandingSettings | | |
| 20 | +| id | One of | Channel ID (UC...) - can be comma-separated for multiple | | |
| 21 | +| forUsername | One of | Legacy username | | |
| 22 | +| key | Yes | API key | | |
| 23 | + | |
| 24 | +### Response Fields | |
| 25 | +```json | |
| 26 | +{ | |
| 27 | + "items": [{ | |
| 28 | + "id": "UC...", | |
| 29 | + "snippet": { | |
| 30 | + "title": "Channel Name", | |
| 31 | + "description": "...", | |
| 32 | + "customUrl": "@handle", | |
| 33 | + "publishedAt": "2020-01-01T00:00:00Z", | |
| 34 | + "country": "US", | |
| 35 | + "thumbnails": { "default": {}, "medium": {}, "high": {} } | |
| 36 | + }, | |
| 37 | + "statistics": { | |
| 38 | + "viewCount": "1000000", | |
| 39 | + "subscriberCount": "50000", | |
| 40 | + "hiddenSubscriberCount": false, | |
| 41 | + "videoCount": "200" | |
| 42 | + }, | |
| 43 | + "contentDetails": { | |
| 44 | + "relatedPlaylists": { | |
| 45 | + "uploads": "UU..." | |
| 46 | + } | |
| 47 | + }, | |
| 48 | + "brandingSettings": { | |
| 49 | + "channel": { | |
| 50 | + "keywords": "keyword1 keyword2" | |
| 51 | + } | |
| 52 | + } | |
| 53 | + }] | |
| 54 | +} | |
| 55 | +``` | |
| 56 | + | |
| 57 | +## Search Endpoint (Channel Discovery) | |
| 58 | + | |
| 59 | +``` | |
| 60 | +GET https://www.googleapis.com/youtube/v3/search | |
| 61 | +``` | |
| 62 | + | |
| 63 | +### Parameters | |
| 64 | +| Param | Required | Description | | |
| 65 | +|-------|----------|-------------| | |
| 66 | +| part | Yes | snippet | | |
| 67 | +| q | Yes | Search query (keywords, channel names) | | |
| 68 | +| type | Yes | channel (for competitor discovery) | | |
| 69 | +| order | No | relevance (default), viewCount | | |
| 70 | +| maxResults | No | 1-50 (default 5) | | |
| 71 | +| pageToken | No | For pagination | | |
| 72 | +| key | Yes | API key | | |
| 73 | + | |
| 74 | +### Response | |
| 75 | +```json | |
| 76 | +{ | |
| 77 | + "nextPageToken": "...", | |
| 78 | + "items": [{ | |
| 79 | + "id": { | |
| 80 | + "kind": "youtube#channel", | |
| 81 | + "channelId": "UC..." | |
| 82 | + }, | |
| 83 | + "snippet": { | |
| 84 | + "channelId": "UC...", | |
| 85 | + "title": "Channel Name", | |
| 86 | + "description": "...", | |
| 87 | + "thumbnails": {} | |
| 88 | + } | |
| 89 | + }] | |
| 90 | +} | |
| 91 | +``` | |
| 92 | + | |
| 93 | +## Videos Endpoint | |
| 94 | + | |
| 95 | +``` | |
| 96 | +GET https://www.googleapis.com/youtube/v3/videos | |
| 97 | +``` | |
| 98 | + | |
| 99 | +### Parameters | |
| 100 | +| Param | Required | Description | | |
| 101 | +|-------|----------|-------------| | |
| 102 | +| part | Yes | snippet,statistics,contentDetails | | |
| 103 | +| id | Yes | Comma-separated video IDs (max 50) | | |
| 104 | +| key | Yes | API key | | |
| 105 | + | |
| 106 | +### Response Fields | |
| 107 | +```json | |
| 108 | +{ | |
| 109 | + "items": [{ | |
| 110 | + "id": "videoId", | |
| 111 | + "snippet": { | |
| 112 | + "publishedAt": "...", | |
| 113 | + "channelId": "...", | |
| 114 | + "title": "...", | |
| 115 | + "description": "...", | |
| 116 | + "tags": ["tag1", "tag2"], | |
| 117 | + "categoryId": "22" | |
| 118 | + }, | |
| 119 | + "statistics": { | |
| 120 | + "viewCount": "10000", | |
| 121 | + "likeCount": "500", | |
| 122 | + "commentCount": "50" | |
| 123 | + }, | |
| 124 | + "contentDetails": { | |
| 125 | + "duration": "PT10M30S", | |
| 126 | + "definition": "hd" | |
| 127 | + } | |
| 128 | + }] | |
| 129 | +} | |
| 130 | +``` | |
| 131 | + | |
| 132 | +## Quota Costs | |
| 133 | + | |
| 134 | +| Operation | Cost | | |
| 135 | +|-----------|------| | |
| 136 | +| search.list | 100 | | |
| 137 | +| channels.list | 1 | | |
| 138 | +| videos.list | 1 | | |
| 139 | +| playlistItems.list | 1 | | |
| 140 | + | |
| 141 | +**Daily quota**: 10,000 units (default) | |
| 142 | + | |
| 143 | +**Optimization for competitor analysis**: | |
| 144 | +- Batch channel IDs (comma-separated) to reduce calls | |
| 145 | +- Limit initial discovery searches to essential keywords | |
| 146 | +- Get detailed video data only for top-ranked competitors | |
| 147 | + | |
| 148 | +## Error Codes | |
| 149 | + | |
| 150 | +| Code | Meaning | | |
| 151 | +|------|---------| | |
| 152 | +| 400 | Bad request (invalid params) | | |
| 153 | +| 403 | Forbidden (quota exceeded, API not enabled) | | |
| 154 | +| 404 | Not found | | |
| 155 | +| 429 | Too many requests | | |
| 156 | + | |
| 157 | +## Channel ID Formats | |
| 158 | + | |
| 159 | +| Format | Example | Resolution | | |
| 160 | +|--------|---------|------------| | |
| 161 | +| Direct ID | UC... | Use directly | | |
| 162 | +| @handle | @channelname | Search API with handle as query | | |
| 163 | +| /channel/ URL | youtube.com/channel/UC... | Extract ID from URL | | |
| 164 | +| /c/ URL | youtube.com/c/name | forUsername parameter | | |
| 165 | +| /user/ URL | youtube.com/user/name | forUsername parameter | | |
| 166 | + | |
| 167 | +## Duration Format (ISO 8601) | |
| 168 | + | |
| 169 | +Format: `PT{hours}H{minutes}M{seconds}S` | |
| 170 | + | |
| 171 | +Examples: | |
| 172 | +- `PT1H30M` = 1 hour 30 minutes | |
| 173 | +- `PT10M30S` = 10 minutes 30 seconds | |
| 174 | + | |
| 175 | +Parse: `/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/` | ... | ... |
system/templates/claude-youtube-skills/.claude/skills/youtube-trending-crawler/SKILL.md
0 → 100644
| 1 | +--- | |
| 2 | +name: youtube-trending-crawler | |
| 3 | +description: "Fetch YouTube trending videos using YouTube Data API v3. Get popular videos by region and category with complete metadata. Use when users want to (1) Get trending videos for a region, (2) Fetch popular videos by category, (3) Batch crawl multiple regions, (4) Monitor trending content across markets. Requires YouTube Data API v3 key." | |
| 4 | +--- | |
| 5 | + | |
| 6 | +# YouTube Trending Crawler | |
| 7 | + | |
| 8 | +Fetch YouTube trending/popular videos using YouTube Data API v3. | |
| 9 | + | |
| 10 | +## Setup | |
| 11 | + | |
| 12 | +1. **API Key**: Get from [Google Cloud Console](https://console.cloud.google.com/apis/credentials) - enable YouTube Data API v3 | |
| 13 | +2. **Regions**: ISO 3166-1 alpha-2 codes (US, JP, KR, GB, DE, FR, IN, BR, etc.) | |
| 14 | +3. **Categories**: Video category IDs (1=Film, 2=Autos, 10=Music, 17=Sports, 20=Gaming, 24=Entertainment, 28=Tech, etc.) | |
| 15 | + | |
| 16 | +## Core API | |
| 17 | + | |
| 18 | +### Primary: videos endpoint (1 quota unit) | |
| 19 | + | |
| 20 | +```bash | |
| 21 | +# Most Popular Videos (CHART endpoint - 1 unit) | |
| 22 | +curl "https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics,contentDetails&chart=mostPopular®ionCode=US&videoCategoryId=10&maxResults=10&key=API_KEY" | |
| 23 | + | |
| 24 | +# Batch video IDs (max 50 per call) | |
| 25 | +curl "https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics,contentDetails&id=VIDEO_IDS&key=API_KEY" | |
| 26 | +``` | |
| 27 | + | |
| 28 | +### Fallback: yt-dlp (when API fails) | |
| 29 | + | |
| 30 | +```bash | |
| 31 | +# Get trending page | |
| 32 | +yt-dlp "https://www.youtube.com/results?sp=CAA%253D&q=trending" --flat-playlist --print "%(id)s|%(title)s|%(channel_id)s|%(channel)s|%(view_count)s|%(like_count)s|%(comment_count)s|%(upload_date)s|%(description)s|%(thumbnail)s|%(categories)s|%(duration)s" | |
| 33 | + | |
| 34 | +# Get specific video details | |
| 35 | +yt-dlp "https://youtube.com/watch?v=VIDEO_ID" --print "%(id)s|%(title)s|%(channel_id)s|%(channel)s|%(view_count)s|%(like_count)s|%(comment_count)s|%(upload_date)s|%(description)s|%(thumbnail)s|%(categories)s|%(duration)s|%(tags)s" | |
| 36 | +``` | |
| 37 | + | |
| 38 | +## Parameters | |
| 39 | + | |
| 40 | +| Parameter | Type | Required | Description | | |
| 41 | +|-----------|------|----------|-------------| | |
| 42 | +| regionCode | string | No | ISO 3166-1 alpha-2 (default: US) | | |
| 43 | +| videoCategoryId | int | No | 1-44 category ID | | |
| 44 | +| maxResults | int | No | 1-50 (default: 10) | | |
| 45 | +| pageToken | string | No | Pagination token | | |
| 46 | + | |
| 47 | +## Supported Regions | |
| 48 | + | |
| 49 | +```javascript | |
| 50 | +const SUPPORTED_REGIONS = [ | |
| 51 | + 'US', 'JP', 'KR', 'GB', 'DE', 'FR', 'IN', 'BR', // Primary | |
| 52 | + 'CA', 'AU', 'RU', 'MX', 'ES', 'IT', 'NL', 'SE' // Extended | |
| 53 | +]; | |
| 54 | +``` | |
| 55 | + | |
| 56 | +## Supported Categories | |
| 57 | + | |
| 58 | +```javascript | |
| 59 | +const CATEGORIES = { | |
| 60 | + 1: 'Film & Animation', | |
| 61 | + 2: 'Autos & Vehicles', | |
| 62 | + 10: 'Music', | |
| 63 | + 15: 'Pets & Animals', | |
| 64 | + 17: 'Sports', | |
| 65 | + 20: 'Gaming', | |
| 66 | + 22: 'People & Blogs', | |
| 67 | + 23: 'Comedy', | |
| 68 | + 24: 'Entertainment', | |
| 69 | + 25: 'News & Politics', | |
| 70 | + 27: 'Education', | |
| 71 | + 28: 'Science & Technology' | |
| 72 | +}; | |
| 73 | +``` | |
| 74 | + | |
| 75 | +## Output Fields (18 fields) | |
| 76 | + | |
| 77 | +| Field | Source | Type | | |
| 78 | +|-------|--------|------| | |
| 79 | +| rank | generated (1-N) | int | | |
| 80 | +| videoId | id | string | | |
| 81 | +| title | snippet.title | string | | |
| 82 | +| url | https://youtube.com/watch?v={id} | string | | |
| 83 | +| channelTitle | snippet.channelTitle | string | | |
| 84 | +| channelId | snippet.channelId | string | | |
| 85 | +| subscriberCount | channels.list (separate call) | int | | |
| 86 | +| viewCount | statistics.viewCount | int | | |
| 87 | +| likeCount | statistics.likeCount | int | | |
| 88 | +| commentCount | statistics.commentCount | int | | |
| 89 | +| publishedAt | snippet.publishedAt | ISO8601 | | |
| 90 | +| description | snippet.description (truncated 500 chars) | string | | |
| 91 | +| thumbnail | snippet.thumbnails.default.url | string | | |
| 92 | +| categoryId | snippet.categoryId | string | | |
| 93 | +| categoryName | mapped from CATEGORIES | string | | |
| 94 | +| duration | contentDetails.duration (ISO 8601) | string | | |
| 95 | +| crawlTime | generated | ISO8601 | | |
| 96 | +| regionCode | from request | string | | |
| 97 | + | |
| 98 | +## Output File | |
| 99 | + | |
| 100 | +Save to: `data/companies/test/workspace/{date}-youtube-trending-{region}-{category}.json` | |
| 101 | + | |
| 102 | +Example: `2026-04-04-youtube-trending-us-politics.json` | |
| 103 | + | |
| 104 | +```json | |
| 105 | +{ | |
| 106 | + "videos": [ | |
| 107 | + { | |
| 108 | + "rank": 1, | |
| 109 | + "videoId": "dQw4w9WgXcQ", | |
| 110 | + "title": "Video Title", | |
| 111 | + "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", | |
| 112 | + "channelTitle": "Channel Name", | |
| 113 | + "channelId": "UCxxxx", | |
| 114 | + "subscriberCount": 1000000, | |
| 115 | + "viewCount": 5000000, | |
| 116 | + "likeCount": 250000, | |
| 117 | + "commentCount": 50000, | |
| 118 | + "publishedAt": "2024-01-15T10:00:00Z", | |
| 119 | + "description": "Video description...", | |
| 120 | + "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg", | |
| 121 | + "categoryId": "25", | |
| 122 | + "categoryName": "News & Politics", | |
| 123 | + "duration": "PT21M4S", | |
| 124 | + "crawlTime": "2026-04-04T00:00:00Z", | |
| 125 | + "regionCode": "US" | |
| 126 | + } | |
| 127 | + ], | |
| 128 | + "metadata": { | |
| 129 | + "regionCode": "US", | |
| 130 | + "videoCategoryId": "25", | |
| 131 | + "categoryName": "News & Politics", | |
| 132 | + "totalResults": 20, | |
| 133 | + "crawlTime": "2026-04-04T00:00:00Z" | |
| 134 | + } | |
| 135 | +} | |
| 136 | +``` | |
| 137 | + | |
| 138 | +## Error Handling | |
| 139 | + | |
| 140 | +### 403 Quota Exceeded | |
| 141 | +```javascript | |
| 142 | +if (error.code === 403 && error.message.includes('quota')) { | |
| 143 | + // Fallback to yt-dlp | |
| 144 | + return await fetchWithYtDlp(params); | |
| 145 | +} | |
| 146 | +``` | |
| 147 | + | |
| 148 | +### 404 Video Not Found | |
| 149 | +```javascript | |
| 150 | +if (error.code === 404) { | |
| 151 | + console.log(`Video ${videoId} not found, skipping`); | |
| 152 | + return null; | |
| 153 | +} | |
| 154 | +``` | |
| 155 | + | |
| 156 | +### 500 Server Error | |
| 157 | +```javascript | |
| 158 | +// Exponential backoff retry | |
| 159 | +const maxRetries = 3; | |
| 160 | +for (let i = 0; i < maxRetries; i++) { | |
| 161 | + try { | |
| 162 | + return await fetch(...); | |
| 163 | + } catch (e) { | |
| 164 | + if (e.code === 500 && i < maxRetries - 1) { | |
| 165 | + await sleep(Math.pow(2, i) * 1000); // 1s, 2s, 4s | |
| 166 | + } | |
| 167 | + } | |
| 168 | +} | |
| 169 | +``` | |
| 170 | + | |
| 171 | +### Rate Limit (429) | |
| 172 | +```javascript | |
| 173 | +if (error.code === 429) { | |
| 174 | + // Wait and retry with longer delay | |
| 175 | + await sleep(60000); // 1 minute | |
| 176 | + return await fetch(...); | |
| 177 | +} | |
| 178 | +``` | |
| 179 | + | |
| 180 | +## Quota Management | |
| 181 | + | |
| 182 | +- Use `videos?chart=mostPopular` endpoint (1 unit) | |
| 183 | +- NEVER use `search` endpoint (100 units) | |
| 184 | +- Batch video IDs (max 50 per call when extending) | |
| 185 | +- Cache category names locally | |
| 186 | +- Rate limit: min 1000ms between requests | |
| 187 | + | |
| 188 | +## Category Mapping | |
| 189 | + | |
| 190 | +```javascript | |
| 191 | +function getCategoryName(categoryId) { | |
| 192 | + const map = { | |
| 193 | + '1': 'Film & Animation', | |
| 194 | + '2': 'Autos & Vehicles', | |
| 195 | + '10': 'Music', | |
| 196 | + '15': 'Pets & Animals', | |
| 197 | + '17': 'Sports', | |
| 198 | + '20': 'Gaming', | |
| 199 | + '22': 'People & Blogs', | |
| 200 | + '23': 'Comedy', | |
| 201 | + '24': 'Entertainment', | |
| 202 | + '25': 'News & Politics', | |
| 203 | + '27': 'Education', | |
| 204 | + '28': 'Science & Technology' | |
| 205 | + }; | |
| 206 | + return map[categoryId] || 'Unknown'; | |
| 207 | +} | |
| 208 | +``` | ... | ... |
system/templates/claude-youtube-skills/agent.md
system/templates/claude-youtube-skills/config.json
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | "id": "claude-youtube-skills", |
| 3 | 3 | "type": "skill", |
| 4 | 4 | "name": "claude-youtube-skills", |
| 5 | - "parent_id": null, | |
| 5 | + "parent_id": "ceo", | |
| 6 | 6 | "goal_id": null, |
| 7 | - "status": "ready", | |
| 7 | + "status": "active", | |
| 8 | 8 | "cli": { |
| 9 | 9 | "toolPolicy": {} |
| 10 | 10 | }, |
| ... | ... | @@ -21,5 +21,9 @@ |
| 21 | 21 | "maxMemoryMB": 512, |
| 22 | 22 | "maxDiskMB": 1024, |
| 23 | 23 | "maxProcesses": 5 |
| 24 | + }, | |
| 25 | + "heartbeat": { | |
| 26 | + "intervalMinutes": 15, | |
| 27 | + "enabled": false | |
| 24 | 28 | } |
| 25 | 29 | } |
| 26 | 30 | \ No newline at end of file | ... | ... |
system/templates/claude-youtube-skills/plan.md
| 1 | -# Plan | |
| 1 | +# claude-youtube-skills 训练计划 | |
| 2 | 2 | |
| 3 | -> 将大任务分解为子任务,分配给下级 Agent,并定期检查进度。 | |
| 3 | +> FDE 流水线训练状态追踪 | |
| 4 | 4 | |
| 5 | -| # | 子任务 | 责任人 | 状态 | 上次检查 | 备注 | | |
| 6 | -|---|--------|--------|------|----------|------| | |
| 7 | -| | (暂无计划) | | | | | | |
| 5 | +## 目标 | |
| 6 | +通过 YouTube Data API v3 抓取最热最新视频列表,输出 JSON 格式。 | |
| 7 | + | |
| 8 | +## 流水线状态 | |
| 9 | + | |
| 10 | +| Phase | 状态 | Agent | 版本 | 备注 | | |
| 11 | +|-------|------|-------|------|------| | |
| 12 | +| Hunt | ✅ 完成 | Hunter | v2 | knowhow_v2.md + crawl_config.json | | |
| 13 | +| Digest | ✅ 完成 | Digester | v2 | benchmark_v2.md + train/test | | |
| 14 | +| Evolve | ✅ 完成 (100分) | Evolver | v2 | 弱维度已优化 | | |
| 15 | +| Deploy | ✅ 已部署 | Innovator | v2 | SKILL.md 已部署到 skills/ | | |
| 16 | + | |
| 17 | +## 训练历史 | |
| 18 | +- v1: youtube-competitor-analyzer (频道竞品分析) | |
| 19 | +- v2: youtube-trending-crawler (趋势视频爬取) - **已完成 ✅** | |
| 20 | + | |
| 21 | +## 行业基线 | |
| 22 | +- target_score: ≥ 90分 | |
| 23 | +- **最终得分: 100分** ✅ | |
| 24 | + | |
| 25 | +## 任务 ID | |
| 26 | +- Hunt: T-mnj3emdx | |
| 27 | +- Digest: T-mnj3nimu | |
| 28 | +- Evolve: T-mnj3s7bi | |
| 29 | + | |
| 30 | +## 启动时间 | |
| 31 | +2026-04-04 | |
| 32 | + | |
| 33 | +## 完成时间 | |
| 34 | +2026-04-04 | |
| 8 | 35 | \ No newline at end of file | ... | ... |
system/templates/claude-youtube-skills/user.md