@acedatacloud/skills 2026.606.0 → 2026.613.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acedatacloud/skills",
3
- "version": "2026.606.0",
3
+ "version": "2026.613.0",
4
4
  "description": "Agent Skills for AceDataCloud AI services — music, image, video generation, LLM chat, web search. Compatible with Claude Code, GitHub Copilot, Gemini CLI, OpenAI Codex, and 30+ AI coding agents.",
5
5
  "keywords": [
6
6
  "agent-skills",
@@ -21,7 +21,16 @@ Using `"callback_url": "https://api.acedata.cloud/health"` as a placeholder forc
21
21
  curl -X POST https://api.acedata.cloud/<service>/tasks \
22
22
  -H "Authorization: Bearer $ACEDATACLOUD_API_TOKEN" \
23
23
  -H "Content-Type: application/json" \
24
- -d '{"task_id": "<task_id from step 1>"}'
24
+ -d '{"id": "<task_id from step 1>"}'
25
+ ```
26
+
27
+ For batch polling, use:
28
+
29
+ ```bash
30
+ curl -X POST https://api.acedata.cloud/<service>/tasks \
31
+ -H "Authorization: Bearer $ACEDATACLOUD_API_TOKEN" \
32
+ -H "Content-Type: application/json" \
33
+ -d '{"action": "retrieve_batch", "ids": ["<task_id_1>", "<task_id_2>"]}'
25
34
  ```
26
35
 
27
36
  ## Important Notes
@@ -29,4 +38,4 @@ curl -X POST https://api.acedata.cloud/<service>/tasks \
29
38
  - Always use `callback_url` to avoid long-running HTTP connections that time out
30
39
  - Poll every 3-5 seconds for music, every 5 seconds for images/video
31
40
  - Terminal states vary by service (e.g., `succeeded`, `succeed`, `completed`, `failed`) — check each skill's Gotchas section
32
- - Some services use `id` instead of `task_id` in the poll request (e.g., Veo, Seedream, NanoBanana)
41
+ - Task polling uses `id` (single) or `ids` (batch). `action` defaults to `retrieve`; set `action: "retrieve_batch"` for `ids`.
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/fish/audios \
23
23
  -d '{"prompt": "Hello, this is a demonstration of AI voice synthesis."}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /fish/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /fish/tasks` with `{"id": "..."}`.
27
27
 
28
28
  ## Endpoints
29
29
 
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/hailuo/videos \
23
23
  -d '{"action": "generate", "prompt": "a dolphin jumping through ocean waves at golden hour", "model": "minimax-t2v"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /hailuo/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /hailuo/tasks` with `{"id": "..."}`.
27
27
  ## Models
28
28
 
29
29
  | Model | Type | Best For |
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/kling/videos \
23
23
  -d '{"action": "text2video", "prompt": "a cat playing piano on a rooftop at sunset", "model": "kling-v3", "mode": "std", "duration": 5}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /kling/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /kling/tasks` with `{"id": "..."}`.
27
27
  ## Models
28
28
 
29
29
  | Model | Quality | Best For |
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/luma/videos \
23
23
  -d '{"prompt": "a drone flying over a mountain lake at sunrise", "action": "generate", "callback_url": "https://api.acedata.cloud/health"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /luma/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /luma/tasks` with `{"id": "..."}`.
27
27
 
28
28
  ## Workflows
29
29
 
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/midjourney/imagine \
23
23
  -d '{"prompt": "a futuristic city at sunset, cyberpunk style --ar 16:9", "callback_url": "https://api.acedata.cloud/health"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /midjourney/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /midjourney/tasks` with `{"id": "..."}`.
27
27
 
28
28
  ## Generation Modes
29
29
 
@@ -23,14 +23,14 @@ curl -X POST https://api.acedata.cloud/seedance/videos \
23
23
  -d '{"model": "doubao-seedance-1-0-pro-250528", "content": [{"type": "text", "text": "a dancer performing contemporary ballet in a misty forest"}], "callback_url": "https://api.acedata.cloud/health"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /seedance/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /seedance/tasks` with `{"id": "..."}`.
27
27
  This returns a task ID immediately. Poll for the result:
28
28
 
29
29
  ```bash
30
30
  curl -X POST https://api.acedata.cloud/seedance/tasks \
31
31
  -H "Authorization: Bearer $ACEDATACLOUD_API_TOKEN" \
32
32
  -H "Content-Type: application/json" \
33
- -d '{"task_id": "<task_id from above>"}'
33
+ -d '{"id": "<task_id from above>"}'
34
34
  ```
35
35
 
36
36
  ## Models
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/sora/videos \
23
23
  -d '{"prompt": "a golden retriever running on a beach at sunset", "model": "sora-2", "callback_url": "https://api.acedata.cloud/health"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /sora/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /sora/tasks` with `{"id": "..."}`.
27
27
 
28
28
  ## Models
29
29
 
@@ -23,7 +23,7 @@ curl -X POST https://api.acedata.cloud/wan/videos \
23
23
  -d '{"action": "text2video", "prompt": "a dolphin jumping through ocean waves at golden hour", "model": "wan2.6-t2v"}'
24
24
  ```
25
25
 
26
- > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /wan/tasks` with `{"task_id": "..."}`.
26
+ > **Async:** See [async task polling](../_shared/async-tasks.md). Poll via `POST /wan/tasks` with `{"id": "..."}`.
27
27
  ## Models
28
28
 
29
29
  | Model | Type | Best For |
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: youtube
3
+ description: Search YouTube, read your own channel and uploaded videos (stats, comments), and upload new videos via the YouTube Data API v3. Use when the user mentions YouTube, "my channel", "my videos", searching YouTube, video views / likes / stats, uploading a video to YouTube, or checking how a published video is doing.
4
+ when_to_use: |
5
+ Trigger when the user wants to search YouTube, inspect their own
6
+ channel / uploaded videos (views, likes, comments), look up a
7
+ video's stats, or upload a new video to their channel. The
8
+ installed connector always grants `youtube.readonly` (search + read
9
+ your channel and videos); the user opts in to `youtube.upload` at
10
+ install time to publish videos — confirm before uploading and
11
+ re-prompt to re-install if the upload scope is missing.
12
+ connections: [google/youtube]
13
+ allowed_tools: [Bash]
14
+ license: Apache-2.0
15
+ metadata:
16
+ author: acedatacloud
17
+ version: "1.0"
18
+ ---
19
+
20
+ Call the **YouTube Data API v3** with `curl + jq`. The user's OAuth bearer
21
+ token is in `$GOOGLE_YOUTUBE_TOKEN`; every call needs it as
22
+ `Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN`. Base URL:
23
+ `https://www.googleapis.com/youtube/v3`.
24
+
25
+ The token always carries `youtube.readonly` plus identity scopes
26
+ (`openid email profile`); if the user opted in at install it also
27
+ carries `youtube.upload` (publish videos).
28
+
29
+ Responses are standard JSON; failures surface as
30
+ `{"error": {"code": 401|403|..., "message": "..."}}` — show that error
31
+ verbatim. `401` → token expired, the user must re-connect the YouTube
32
+ connector. `403 insufficientPermissions` on an upload → the user did
33
+ not grant `youtube.upload`; ask them to re-connect with the upload box
34
+ checked.
35
+
36
+ **Always start with the channel check** to confirm the connection works
37
+ and learn which channel you're operating against.
38
+
39
+ ```bash
40
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
41
+ "https://www.googleapis.com/youtube/v3/channels?part=snippet,statistics,contentDetails&mine=true" \
42
+ | jq '.items[0] | {title: .snippet.title, subs: .statistics.subscriberCount, views: .statistics.viewCount, uploads: .contentDetails.relatedPlaylists.uploads}'
43
+ ```
44
+
45
+ ## Search YouTube
46
+
47
+ ```bash
48
+ # Public search (any video). type can be video|channel|playlist.
49
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
50
+ --data-urlencode "q=ai video automation" \
51
+ --data-urlencode "part=snippet" \
52
+ --data-urlencode "type=video" \
53
+ --data-urlencode "maxResults=10" \
54
+ -G "https://www.googleapis.com/youtube/v3/search" \
55
+ | jq '.items[] | {videoId: .id.videoId, title: .snippet.title, channel: .snippet.channelTitle, published: .snippet.publishedAt}'
56
+ ```
57
+
58
+ Add `--data-urlencode "order=date|viewCount|rating|relevance"` to sort,
59
+ or `--data-urlencode "publishedAfter=2026-01-01T00:00:00Z"` to window.
60
+
61
+ ## See my uploaded videos
62
+
63
+ YouTube has no "list my videos" call directly — read the channel's
64
+ **uploads playlist**, then page its items.
65
+
66
+ ```bash
67
+ # 1. Get the uploads playlist id (UU... ) — same as channels call above.
68
+ UPLOADS=$(curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
69
+ "https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true" \
70
+ | jq -r '.items[0].contentDetails.relatedPlaylists.uploads')
71
+
72
+ # 2. List recent uploads (50/page; follow .nextPageToken for more).
73
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
74
+ -G "https://www.googleapis.com/youtube/v3/playlistItems" \
75
+ --data-urlencode "part=snippet,contentDetails" \
76
+ --data-urlencode "playlistId=$UPLOADS" \
77
+ --data-urlencode "maxResults=50" \
78
+ | jq '.items[] | {videoId: .contentDetails.videoId, title: .snippet.title, published: .snippet.publishedAt}'
79
+ ```
80
+
81
+ Paginate by passing `--data-urlencode "pageToken=$PAGE_TOKEN"` with the
82
+ `.nextPageToken` from the previous response.
83
+
84
+ ## Video stats (views / likes / comments)
85
+
86
+ ```bash
87
+ # Accepts a comma-separated id list.
88
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
89
+ -G "https://www.googleapis.com/youtube/v3/videos" \
90
+ --data-urlencode "part=snippet,statistics,status" \
91
+ --data-urlencode "id=VIDEO_ID_1,VIDEO_ID_2" \
92
+ | jq '.items[] | {title: .snippet.title, views: .statistics.viewCount, likes: .statistics.likeCount, comments: .statistics.commentCount, privacy: .status.privacyStatus}'
93
+ ```
94
+
95
+ ## Read comments on a video
96
+
97
+ ```bash
98
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
99
+ -G "https://www.googleapis.com/youtube/v3/commentThreads" \
100
+ --data-urlencode "part=snippet" \
101
+ --data-urlencode "videoId=VIDEO_ID" \
102
+ --data-urlencode "maxResults=20" \
103
+ --data-urlencode "order=relevance" \
104
+ | jq '.items[] | .snippet.topLevelComment.snippet | {author: .authorDisplayName, text: .textDisplay, likes: .likeCount}'
105
+ ```
106
+
107
+ ## Upload a video (needs `youtube.upload`)
108
+
109
+ **Confirm with the user before publishing** — show the title, privacy and
110
+ file you're about to upload. Uploads are a two-step *resumable* flow:
111
+ init with metadata → PUT the bytes.
112
+
113
+ ```bash
114
+ FILE="/path/to/video.mp4"
115
+ TITLE="My title"
116
+ DESC="My description"
117
+ # privacyStatus: public | unlisted | private
118
+ read -r -d '' META <<JSON
119
+ {"snippet":{"title":"$TITLE","description":"$DESC","categoryId":"22"},
120
+ "status":{"privacyStatus":"unlisted","selfDeclaredMadeForKids":false}}
121
+ JSON
122
+
123
+ # 1. Init resumable session -> capture the upload URL from the Location header.
124
+ UPLOAD_URL=$(curl -sS -D - -o /dev/null \
125
+ -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
126
+ -H "Content-Type: application/json; charset=UTF-8" \
127
+ -H "X-Upload-Content-Type: video/*" \
128
+ -X POST "https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status" \
129
+ -d "$META" | tr -d '\r' | awk '/^[Ll]ocation:/{print $2}')
130
+
131
+ # 2. Upload the bytes -> returns the created video resource (has .id).
132
+ curl -sS -H "Authorization: Bearer $GOOGLE_YOUTUBE_TOKEN" \
133
+ -H "Content-Type: video/*" \
134
+ -X PUT --upload-file "$FILE" "$UPLOAD_URL" \
135
+ | jq '{id: .id, url: ("https://www.youtube.com/watch?v=" + .id), privacy: .status.privacyStatus}'
136
+ ```
137
+
138
+ `categoryId` `22` = "People & Blogs" (a safe default). To set a custom
139
+ thumbnail (needs the file to be processed first), call
140
+ `POST /upload/youtube/v3/thumbnails/set?videoId=VIDEO_ID` with the image.
141
+
142
+ ## Gotchas
143
+
144
+ - **Quota:** the Data API is quota-metered (default 10,000 units/day). A
145
+ `search` costs 100 units; an `upload` costs ~1,600. A burst of searches
146
+ can exhaust the daily quota → `403 quotaExceeded`; surface it plainly.
147
+ - **No "my videos" endpoint** — always go via the uploads playlist.
148
+ - **`search` results are eventually-consistent** — a freshly uploaded
149
+ video may not appear in `search` for minutes/hours; read it via the
150
+ uploads playlist or by id instead.
151
+ - Uploaded videos start in `uploaded`/`processing` state; stats are `0`
152
+ until processing completes.