diff --git a/.gitignore b/.gitignore index 39de8de..d65e6cd 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,15 @@ tmp/ # === 运行时文件 (不提交) === .claude/ +!system/templates/*/.claude/ +system/templates/*/.claude/* +!system/templates/*/.claude/skills/ +!system/templates/*/.claude/skills/** +!system/templates/*/.claude/*.lock +!system/agents/*/.claude/ +system/agents/*/.claude/* +!system/agents/*/.claude/skills/ +!system/agents/*/.claude/skills/** .pylibs/ nohup.out data/agents/ diff --git a/system/agents/master/.claude/scheduled_tasks.json b/system/agents/master/.claude/scheduled_tasks.json index 4681743..3e12acd 100644 --- a/system/agents/master/.claude/scheduled_tasks.json +++ b/system/agents/master/.claude/scheduled_tasks.json @@ -5,6 +5,7 @@ "cron": "*/5 * * * *", "prompt": "执行系统巡检:读取 plan.md 和 todo.md,检查所有任务状态。已完成的更新标记,卡住的分析原因后自主处理(重新分发或修复),未开始的按优先级立即分发。不要请示用户,直接行动。", "createdAt": 1775231859266, + "lastFiredAt": 1775235913481, "recurring": true }, { @@ -12,6 +13,22 @@ "cron": "*/30 * * * *", "prompt": "生成系统状态日报,统计所有 Agent 任务完成率和异常情况,写入 memory/daily/ 今日文件。", "createdAt": 1775231859272, + "lastFiredAt": 1775235574165, + "recurring": true + }, + { + "id": "7868eeb3", + "cron": "*/5 * * * *", + "prompt": "执行系统巡检:读取 plan.md 和 todo.md,检查所有任务状态。已完成的更新标记,卡住的分析原因后自主处理(重新分发或修复),未开始的按优先级立即分发。不要请示用户,直接行动。", + "createdAt": 1775235820776, + "recurring": true, + "lastFiredAt": 1775235971536 + }, + { + "id": "695f0a30", + "cron": "*/30 * * * *", + "prompt": "生成系统状态日报,统计所有 Agent 任务完成率和异常情况,写入 memory/daily/ 今日文件。", + "createdAt": 1775235825837, "recurring": true } ] diff --git a/system/templates/claude-youtube-skills/.claude/skills/skills.md b/system/templates/claude-youtube-skills/.claude/skills/skills.md new file mode 100644 index 0000000..09c90d3 --- /dev/null +++ b/system/templates/claude-youtube-skills/.claude/skills/skills.md @@ -0,0 +1,8 @@ +# 我的技能 + +## 技能清单 +(尚未添加技能) + +## 说明 +- 每个技能是 skills/ 目录下的一个子文件夹 +- 每个技能文件夹内必须包含 SKILL.md 定义文件 diff --git a/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/SKILL.md b/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/SKILL.md new file mode 100644 index 0000000..0da4311 --- /dev/null +++ b/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/SKILL.md @@ -0,0 +1,138 @@ +--- +name: youtube-competitor-analyzer +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." +--- + +# YouTube Competitor Analyzer + +Find and analyze competitor channels using YouTube Data API v3. + +## Setup + +1. **API Key**: Get from [Google Cloud Console](https://console.cloud.google.com/apis/credentials) - enable YouTube Data API v3 +2. **Input**: User's channel (for context) OR list of competitor channels to analyze directly + +## API Endpoints + +``` +BASE_URL = https://www.googleapis.com/youtube/v3 + +# Search channels +GET /search?part=snippet&q={query}&type=channel&maxResults={n}&key={API_KEY} + +# Channel details +GET /channels?part=snippet,statistics,contentDetails,brandingSettings&id={ids}&key={API_KEY} + +# Channel videos +GET /search?part=snippet&channelId={id}&order=date&type=video&maxResults=50&key={API_KEY} + +# Video details +GET /videos?part=snippet,statistics,contentDetails&id={ids}&key={API_KEY} +``` + +## Competitor Discovery Methods + +### 1. Keyword Search +Extract keywords from user's channel (description, title, brandingSettings.keywords), search for channels: +``` +GET /search?q={keyword}&type=channel&maxResults=10 +``` + +### 2. Content Similarity +Get user's recent video titles, extract frequent words (>4 chars), search channels with those terms. + +### 3. Category Search +Search within same YouTube category as user's channel. + +### 4. Related Discovery +Search using user's video titles/descriptions to find channels creating similar content. + +### 5. Direct Input +User provides specific channels to analyze: @handles, channel IDs, or URLs. + +## Competitor Ranking + +```javascript +// Size similarity (log scale) +sizeSimilarity = 1 - Math.abs(Math.log10(compSubs+1) - Math.log10(targetSubs+1)) / 10; + +// Engagement per video +engagementRate = viewCount / (videoCount || 1); + +// Overall score +overallScore = sizeSimilarity * 0.3 + relevanceScore * 0.7; +``` + +Sort by overallScore, return top 10-15. + +## Comparative Analysis + +For each competitor, extract: +| Metric | Description | +|--------|-------------| +| Subscribers | Direct count | +| Total Views | Channel lifetime views | +| Video Count | Total videos published | +| Views/Video | Average performance | +| Upload Frequency | Videos per month | +| Channel Age | Days since creation | + +Compare user channel vs competitor averages: +- Above/below average positioning +- Growth rate comparison +- Content volume gaps + +## Content Gap Analysis + +Compare across competitors: +- Content types they cover vs user doesn't +- Duration preferences +- Upload schedules +- Title/thumbnail patterns +- High-performing topics + +## Output Report Structure + +```markdown +# Competitive Analysis Report +## Executive Summary +- Competitors found, key positioning insights +## Competitor Table +| Channel | Subs | Videos | Views | Views/Video | Score | +## Competitive Positioning +- User vs competitor averages +- Market position assessment +## Content Strategy Comparison +- What competitors do differently +- Common patterns among top performers +## Opportunities +- Content gaps to fill +- Underserved niches +- Schedule optimization +## Recommendations +- Strategic actions based on analysis +``` + +## Niche-Specific Search Terms + +For spiritual/wellness channels: +``` +meditation, mindfulness, yoga, spiritual, consciousness, wellness, self-help, awakening +``` + +For tech channels: +``` +tech review, unboxing, tutorial, how to, comparison, tips, gadget +``` + +For gaming: +``` +gameplay, let's play, walkthrough, gaming, stream, esports +``` + +## Quota Optimization + +- Limit discovery to 20-30 initial channels +- Detailed analysis for top 10-15 only +- Batch video IDs (max 50 per call) +- Cache results when comparing multiple times diff --git a/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/references/api_reference.md b/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/references/api_reference.md new file mode 100644 index 0000000..6bcf5ea --- /dev/null +++ b/system/templates/claude-youtube-skills/.claude/skills/youtube-competitor-analyzer/references/api_reference.md @@ -0,0 +1,175 @@ +# YouTube Data API v3 Reference + +## Authentication + +All requests require `key={API_KEY}` parameter. + +Get API key: [Google Cloud Console](https://console.cloud.google.com/apis/credentials) +1. Create project → Enable YouTube Data API v3 → Create credentials → API Key + +## Channels Endpoint + +``` +GET https://www.googleapis.com/youtube/v3/channels +``` + +### Parameters +| Param | Required | Description | +|-------|----------|-------------| +| part | Yes | snippet,statistics,contentDetails,brandingSettings | +| id | One of | Channel ID (UC...) - can be comma-separated for multiple | +| forUsername | One of | Legacy username | +| key | Yes | API key | + +### Response Fields +```json +{ + "items": [{ + "id": "UC...", + "snippet": { + "title": "Channel Name", + "description": "...", + "customUrl": "@handle", + "publishedAt": "2020-01-01T00:00:00Z", + "country": "US", + "thumbnails": { "default": {}, "medium": {}, "high": {} } + }, + "statistics": { + "viewCount": "1000000", + "subscriberCount": "50000", + "hiddenSubscriberCount": false, + "videoCount": "200" + }, + "contentDetails": { + "relatedPlaylists": { + "uploads": "UU..." + } + }, + "brandingSettings": { + "channel": { + "keywords": "keyword1 keyword2" + } + } + }] +} +``` + +## Search Endpoint (Channel Discovery) + +``` +GET https://www.googleapis.com/youtube/v3/search +``` + +### Parameters +| Param | Required | Description | +|-------|----------|-------------| +| part | Yes | snippet | +| q | Yes | Search query (keywords, channel names) | +| type | Yes | channel (for competitor discovery) | +| order | No | relevance (default), viewCount | +| maxResults | No | 1-50 (default 5) | +| pageToken | No | For pagination | +| key | Yes | API key | + +### Response +```json +{ + "nextPageToken": "...", + "items": [{ + "id": { + "kind": "youtube#channel", + "channelId": "UC..." + }, + "snippet": { + "channelId": "UC...", + "title": "Channel Name", + "description": "...", + "thumbnails": {} + } + }] +} +``` + +## Videos Endpoint + +``` +GET https://www.googleapis.com/youtube/v3/videos +``` + +### Parameters +| Param | Required | Description | +|-------|----------|-------------| +| part | Yes | snippet,statistics,contentDetails | +| id | Yes | Comma-separated video IDs (max 50) | +| key | Yes | API key | + +### Response Fields +```json +{ + "items": [{ + "id": "videoId", + "snippet": { + "publishedAt": "...", + "channelId": "...", + "title": "...", + "description": "...", + "tags": ["tag1", "tag2"], + "categoryId": "22" + }, + "statistics": { + "viewCount": "10000", + "likeCount": "500", + "commentCount": "50" + }, + "contentDetails": { + "duration": "PT10M30S", + "definition": "hd" + } + }] +} +``` + +## Quota Costs + +| Operation | Cost | +|-----------|------| +| search.list | 100 | +| channels.list | 1 | +| videos.list | 1 | +| playlistItems.list | 1 | + +**Daily quota**: 10,000 units (default) + +**Optimization for competitor analysis**: +- Batch channel IDs (comma-separated) to reduce calls +- Limit initial discovery searches to essential keywords +- Get detailed video data only for top-ranked competitors + +## Error Codes + +| Code | Meaning | +|------|---------| +| 400 | Bad request (invalid params) | +| 403 | Forbidden (quota exceeded, API not enabled) | +| 404 | Not found | +| 429 | Too many requests | + +## Channel ID Formats + +| Format | Example | Resolution | +|--------|---------|------------| +| Direct ID | UC... | Use directly | +| @handle | @channelname | Search API with handle as query | +| /channel/ URL | youtube.com/channel/UC... | Extract ID from URL | +| /c/ URL | youtube.com/c/name | forUsername parameter | +| /user/ URL | youtube.com/user/name | forUsername parameter | + +## Duration Format (ISO 8601) + +Format: `PT{hours}H{minutes}M{seconds}S` + +Examples: +- `PT1H30M` = 1 hour 30 minutes +- `PT10M30S` = 10 minutes 30 seconds + +Parse: `/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/` diff --git a/system/templates/claude-youtube-skills/.claude/skills/youtube-trending-crawler/SKILL.md b/system/templates/claude-youtube-skills/.claude/skills/youtube-trending-crawler/SKILL.md new file mode 100644 index 0000000..3f2fbb7 --- /dev/null +++ b/system/templates/claude-youtube-skills/.claude/skills/youtube-trending-crawler/SKILL.md @@ -0,0 +1,208 @@ +--- +name: youtube-trending-crawler +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." +--- + +# YouTube Trending Crawler + +Fetch YouTube trending/popular videos using YouTube Data API v3. + +## Setup + +1. **API Key**: Get from [Google Cloud Console](https://console.cloud.google.com/apis/credentials) - enable YouTube Data API v3 +2. **Regions**: ISO 3166-1 alpha-2 codes (US, JP, KR, GB, DE, FR, IN, BR, etc.) +3. **Categories**: Video category IDs (1=Film, 2=Autos, 10=Music, 17=Sports, 20=Gaming, 24=Entertainment, 28=Tech, etc.) + +## Core API + +### Primary: videos endpoint (1 quota unit) + +```bash +# Most Popular Videos (CHART endpoint - 1 unit) +curl "https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics,contentDetails&chart=mostPopular®ionCode=US&videoCategoryId=10&maxResults=10&key=API_KEY" + +# Batch video IDs (max 50 per call) +curl "https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics,contentDetails&id=VIDEO_IDS&key=API_KEY" +``` + +### Fallback: yt-dlp (when API fails) + +```bash +# Get trending page +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" + +# Get specific video details +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" +``` + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| regionCode | string | No | ISO 3166-1 alpha-2 (default: US) | +| videoCategoryId | int | No | 1-44 category ID | +| maxResults | int | No | 1-50 (default: 10) | +| pageToken | string | No | Pagination token | + +## Supported Regions + +```javascript +const SUPPORTED_REGIONS = [ + 'US', 'JP', 'KR', 'GB', 'DE', 'FR', 'IN', 'BR', // Primary + 'CA', 'AU', 'RU', 'MX', 'ES', 'IT', 'NL', 'SE' // Extended +]; +``` + +## Supported Categories + +```javascript +const CATEGORIES = { + 1: 'Film & Animation', + 2: 'Autos & Vehicles', + 10: 'Music', + 15: 'Pets & Animals', + 17: 'Sports', + 20: 'Gaming', + 22: 'People & Blogs', + 23: 'Comedy', + 24: 'Entertainment', + 25: 'News & Politics', + 27: 'Education', + 28: 'Science & Technology' +}; +``` + +## Output Fields (18 fields) + +| Field | Source | Type | +|-------|--------|------| +| rank | generated (1-N) | int | +| videoId | id | string | +| title | snippet.title | string | +| url | https://youtube.com/watch?v={id} | string | +| channelTitle | snippet.channelTitle | string | +| channelId | snippet.channelId | string | +| subscriberCount | channels.list (separate call) | int | +| viewCount | statistics.viewCount | int | +| likeCount | statistics.likeCount | int | +| commentCount | statistics.commentCount | int | +| publishedAt | snippet.publishedAt | ISO8601 | +| description | snippet.description (truncated 500 chars) | string | +| thumbnail | snippet.thumbnails.default.url | string | +| categoryId | snippet.categoryId | string | +| categoryName | mapped from CATEGORIES | string | +| duration | contentDetails.duration (ISO 8601) | string | +| crawlTime | generated | ISO8601 | +| regionCode | from request | string | + +## Output File + +Save to: `data/companies/test/workspace/{date}-youtube-trending-{region}-{category}.json` + +Example: `2026-04-04-youtube-trending-us-politics.json` + +```json +{ + "videos": [ + { + "rank": 1, + "videoId": "dQw4w9WgXcQ", + "title": "Video Title", + "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", + "channelTitle": "Channel Name", + "channelId": "UCxxxx", + "subscriberCount": 1000000, + "viewCount": 5000000, + "likeCount": 250000, + "commentCount": 50000, + "publishedAt": "2024-01-15T10:00:00Z", + "description": "Video description...", + "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg", + "categoryId": "25", + "categoryName": "News & Politics", + "duration": "PT21M4S", + "crawlTime": "2026-04-04T00:00:00Z", + "regionCode": "US" + } + ], + "metadata": { + "regionCode": "US", + "videoCategoryId": "25", + "categoryName": "News & Politics", + "totalResults": 20, + "crawlTime": "2026-04-04T00:00:00Z" + } +} +``` + +## Error Handling + +### 403 Quota Exceeded +```javascript +if (error.code === 403 && error.message.includes('quota')) { + // Fallback to yt-dlp + return await fetchWithYtDlp(params); +} +``` + +### 404 Video Not Found +```javascript +if (error.code === 404) { + console.log(`Video ${videoId} not found, skipping`); + return null; +} +``` + +### 500 Server Error +```javascript +// Exponential backoff retry +const maxRetries = 3; +for (let i = 0; i < maxRetries; i++) { + try { + return await fetch(...); + } catch (e) { + if (e.code === 500 && i < maxRetries - 1) { + await sleep(Math.pow(2, i) * 1000); // 1s, 2s, 4s + } + } +} +``` + +### Rate Limit (429) +```javascript +if (error.code === 429) { + // Wait and retry with longer delay + await sleep(60000); // 1 minute + return await fetch(...); +} +``` + +## Quota Management + +- Use `videos?chart=mostPopular` endpoint (1 unit) +- NEVER use `search` endpoint (100 units) +- Batch video IDs (max 50 per call when extending) +- Cache category names locally +- Rate limit: min 1000ms between requests + +## Category Mapping + +```javascript +function getCategoryName(categoryId) { + const map = { + '1': 'Film & Animation', + '2': 'Autos & Vehicles', + '10': 'Music', + '15': 'Pets & Animals', + '17': 'Sports', + '20': 'Gaming', + '22': 'People & Blogs', + '23': 'Comedy', + '24': 'Entertainment', + '25': 'News & Politics', + '27': 'Education', + '28': 'Science & Technology' + }; + return map[categoryId] || 'Unknown'; +} +``` diff --git a/system/templates/claude-youtube-skills/agent.md b/system/templates/claude-youtube-skills/agent.md index cfcc8a0..5a72d11 100644 --- a/system/templates/claude-youtube-skills/agent.md +++ b/system/templates/claude-youtube-skills/agent.md @@ -14,3 +14,12 @@ ## 可用工具 # 无管理工具 — Skill 只负责执行, 不管理其他 Agent + +--- + +## 所属公司 +- **公司ID**: test +- **公司名称**: test +- **公司使命**: 待定义 + +> 你是 **test** 的员工。你的所有工作都应围绕公司的使命和目标展开。 diff --git a/system/templates/claude-youtube-skills/config.json b/system/templates/claude-youtube-skills/config.json index c13a480..9a0cfe4 100644 --- a/system/templates/claude-youtube-skills/config.json +++ b/system/templates/claude-youtube-skills/config.json @@ -2,9 +2,9 @@ "id": "claude-youtube-skills", "type": "skill", "name": "claude-youtube-skills", - "parent_id": null, + "parent_id": "ceo", "goal_id": null, - "status": "ready", + "status": "active", "cli": { "toolPolicy": {} }, @@ -21,5 +21,9 @@ "maxMemoryMB": 512, "maxDiskMB": 1024, "maxProcesses": 5 + }, + "heartbeat": { + "intervalMinutes": 15, + "enabled": false } } \ No newline at end of file diff --git a/system/templates/claude-youtube-skills/plan.md b/system/templates/claude-youtube-skills/plan.md index a04f402..f3237e8 100644 --- a/system/templates/claude-youtube-skills/plan.md +++ b/system/templates/claude-youtube-skills/plan.md @@ -1,7 +1,34 @@ -# Plan +# claude-youtube-skills 训练计划 -> 将大任务分解为子任务,分配给下级 Agent,并定期检查进度。 +> FDE 流水线训练状态追踪 -| # | 子任务 | 责任人 | 状态 | 上次检查 | 备注 | -|---|--------|--------|------|----------|------| -| | (暂无计划) | | | | | +## 目标 +通过 YouTube Data API v3 抓取最热最新视频列表,输出 JSON 格式。 + +## 流水线状态 + +| Phase | 状态 | Agent | 版本 | 备注 | +|-------|------|-------|------|------| +| Hunt | ✅ 完成 | Hunter | v2 | knowhow_v2.md + crawl_config.json | +| Digest | ✅ 完成 | Digester | v2 | benchmark_v2.md + train/test | +| Evolve | ✅ 完成 (100分) | Evolver | v2 | 弱维度已优化 | +| Deploy | ✅ 已部署 | Innovator | v2 | SKILL.md 已部署到 skills/ | + +## 训练历史 +- v1: youtube-competitor-analyzer (频道竞品分析) +- v2: youtube-trending-crawler (趋势视频爬取) - **已完成 ✅** + +## 行业基线 +- target_score: ≥ 90分 +- **最终得分: 100分** ✅ + +## 任务 ID +- Hunt: T-mnj3emdx +- Digest: T-mnj3nimu +- Evolve: T-mnj3s7bi + +## 启动时间 +2026-04-04 + +## 完成时间 +2026-04-04 \ No newline at end of file diff --git a/system/templates/claude-youtube-skills/user.md b/system/templates/claude-youtube-skills/user.md index 0c86229..e8390ad 100644 --- a/system/templates/claude-youtube-skills/user.md +++ b/system/templates/claude-youtube-skills/user.md @@ -1,7 +1,13 @@ -# 上层上下文 +# 与上级的关系 -## 我的上级 -- 直接向用户汇报 (无上级 Agent) +## 所属公司 +- **公司**: test (test) -## 用户偏好 -(待用户定义) +## 汇报对象 +- **直接汇报**: CEO (公司 CEO) +- **协同**: 公司内其他同事 + +## 沟通规则 +1. 完成任务后主动向上级汇报结果 +2. 遇到阻碍时及时上报,附带解决建议 +3. 保持透明,坏消息更要及时同步