@acedatacloud/skills 2026.704.4 → 2026.705.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 +1 -1
- package/skills/instagram/SKILL.md +11 -3
- package/skills/zhihu/SKILL.md +61 -37
- package/skills/zhihu/scripts/blog.py +12 -6
- package/skills/zhihu/scripts/search.py +14 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acedatacloud/skills",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.705.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",
|
|
@@ -24,14 +24,22 @@ Instagram publishes only **images / videos / reels** to a **professional**
|
|
|
24
24
|
|
|
25
25
|
### Resolve the Instagram account id
|
|
26
26
|
|
|
27
|
-
If `$INSTAGRAM_IG_USER_ID` is set, use it. Otherwise derive it from the
|
|
27
|
+
If `$INSTAGRAM_IG_USER_ID` is set, use it. Otherwise derive it from the token —
|
|
28
|
+
try the **Page-token** path first (`/me` is the Page), then fall back to the
|
|
29
|
+
**user-token** path (`/me/accounts` → linked Page → IG account), so either token
|
|
30
|
+
type the connector accepts resolves cleanly:
|
|
28
31
|
|
|
29
32
|
```bash
|
|
30
33
|
if [ -n "$INSTAGRAM_IG_USER_ID" ]; then
|
|
31
34
|
IGID="$INSTAGRAM_IG_USER_ID"
|
|
32
35
|
else
|
|
33
|
-
|
|
34
|
-
IGID=$(curl -sS "https://graph.facebook.com/v21.0
|
|
36
|
+
# Page access token: /me IS the Page, read its linked IG account directly
|
|
37
|
+
IGID=$(curl -sS "https://graph.facebook.com/v21.0/me?fields=instagram_business_account&access_token=$INSTAGRAM_ACCESS_TOKEN" | jq -r '.instagram_business_account.id // empty')
|
|
38
|
+
if [ -z "$IGID" ]; then
|
|
39
|
+
# User access token: list the managed Page, then its linked IG account
|
|
40
|
+
PAGE=$(curl -sS "https://graph.facebook.com/v21.0/me/accounts?access_token=$INSTAGRAM_ACCESS_TOKEN" | jq -r '.data[0].id // empty')
|
|
41
|
+
IGID=$(curl -sS "https://graph.facebook.com/v21.0/$PAGE?fields=instagram_business_account&access_token=$INSTAGRAM_ACCESS_TOKEN" | jq -r '.instagram_business_account.id // empty')
|
|
42
|
+
fi
|
|
35
43
|
fi
|
|
36
44
|
echo "ig_user_id=$IGID"
|
|
37
45
|
```
|
package/skills/zhihu/SKILL.md
CHANGED
|
@@ -35,43 +35,64 @@ The connector injects credentials as env vars:
|
|
|
35
35
|
- `ZHIHU_COOKIES` — a JSON array of `{name, value, domain, path, ...}` cookies.
|
|
36
36
|
Used for reading/writing the user's own content. **Secret — never echo or print it.**
|
|
37
37
|
|
|
38
|
+
## Locate the scripts first (every Bash block)
|
|
39
|
+
|
|
40
|
+
The connector sets `$SKILL_DIR` to this skill's directory, so the scripts live at
|
|
41
|
+
`$SKILL_DIR/scripts/`. **Do NOT hard-code `python3 $SKILL_DIR/scripts/…` directly.**
|
|
42
|
+
If more than one skill was loaded in the same turn, `$SKILL_DIR` can point at the
|
|
43
|
+
*other* skill and the call fails with `No such file or directory` (this is the #1
|
|
44
|
+
cause of a Zhihu run silently not finishing). Resolve the path defensively at the
|
|
45
|
+
top of **every** Bash block — each Bash call is a fresh shell, so the variable does
|
|
46
|
+
not carry over:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
# blog.py is unique to this skill, so it anchors zhihu's dir even if $SKILL_DIR is wrong.
|
|
50
|
+
ZDIR="$SKILL_DIR"; [ -f "$ZDIR/scripts/blog.py" ] || ZDIR=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/blog.py' 2>/dev/null | head -1 | sed 's#/scripts/blog.py##')
|
|
51
|
+
[ -f "$ZDIR/scripts/blog.py" ] || { echo "zhihu scripts not found (SKILL_DIR=$SKILL_DIR) — is the skill loaded?" >&2; exit 1; }
|
|
52
|
+
SEARCH="$ZDIR/scripts/search.py"; BLOG="$ZDIR/scripts/blog.py"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then use `"$SEARCH"` / `"$BLOG"` (always quoted) as shown below.
|
|
56
|
+
|
|
38
57
|
## Search CLI (search.py)
|
|
39
58
|
|
|
40
59
|
[`scripts/search.py`](scripts/search.py) — search Zhihu and the web. Requires
|
|
41
60
|
only `ZHIHU_DEVELOPER_TOKEN` (no cookies needed).
|
|
42
61
|
|
|
43
62
|
```sh
|
|
44
|
-
|
|
63
|
+
# Resolve the scripts first (see "Locate the scripts first" above) — robust to $SKILL_DIR.
|
|
64
|
+
ZDIR="$SKILL_DIR"; [ -f "$ZDIR/scripts/blog.py" ] || ZDIR=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/blog.py' 2>/dev/null | head -1 | sed 's#/scripts/blog.py##')
|
|
65
|
+
SEARCH="$ZDIR/scripts/search.py"
|
|
45
66
|
|
|
46
67
|
# Search Zhihu content (站内搜索) — questions, answers, articles
|
|
47
|
-
python3 $SEARCH search "Python 爬虫"
|
|
48
|
-
python3 $SEARCH search "Python 爬虫" --count 5
|
|
68
|
+
python3 "$SEARCH" search "Python 爬虫"
|
|
69
|
+
python3 "$SEARCH" search "Python 爬虫" --count 5
|
|
49
70
|
|
|
50
71
|
# Search the entire web (全网搜索) — all indexed sites
|
|
51
|
-
python3 $SEARCH global "AI Agent"
|
|
52
|
-
python3 $SEARCH global "AI Agent" --count 15
|
|
72
|
+
python3 "$SEARCH" global "AI Agent"
|
|
73
|
+
python3 "$SEARCH" global "AI Agent" --count 15
|
|
53
74
|
|
|
54
75
|
# Filter by site or time
|
|
55
|
-
python3 $SEARCH global "React" --filter 'host=="github.com"'
|
|
56
|
-
python3 $SEARCH global "新闻" --filter 'publish_time>=1720000000'
|
|
57
|
-
python3 $SEARCH global "技术" --filter 'host=="github.com" AND publish_time>=1720000000'
|
|
58
|
-
python3 $SEARCH global "实时新闻" --db realtime
|
|
76
|
+
python3 "$SEARCH" global "React" --filter 'host=="github.com"'
|
|
77
|
+
python3 "$SEARCH" global "新闻" --filter 'publish_time>=1720000000'
|
|
78
|
+
python3 "$SEARCH" global "技术" --filter 'host=="github.com" AND publish_time>=1720000000'
|
|
79
|
+
python3 "$SEARCH" global "实时新闻" --db realtime
|
|
59
80
|
|
|
60
81
|
# Get Zhihu trending topics (热榜)
|
|
61
|
-
python3 $SEARCH hot
|
|
62
|
-
python3 $SEARCH hot --limit 10
|
|
82
|
+
python3 "$SEARCH" hot
|
|
83
|
+
python3 "$SEARCH" hot --limit 10
|
|
63
84
|
```
|
|
64
85
|
|
|
65
86
|
### Search commands
|
|
66
87
|
|
|
67
88
|
| Goal | Command |
|
|
68
89
|
|---|---|
|
|
69
|
-
| Search Zhihu (max 10 results) | `python3 $SEARCH search "<query>" --count N` |
|
|
70
|
-
| Search entire web (max 20) | `python3 $SEARCH global "<query>" --count N` |
|
|
90
|
+
| Search Zhihu (max 10 results) | `python3 "$SEARCH" search "<query>" --count N` |
|
|
91
|
+
| Search entire web (max 20) | `python3 "$SEARCH" global "<query>" --count N` |
|
|
71
92
|
| Filter by site | `--filter 'host=="example.com"'` |
|
|
72
93
|
| Filter by time | `--filter 'publish_time>=<unix_ts>'` |
|
|
73
94
|
| Search only realtime/static index | `--db realtime` or `--db static` |
|
|
74
|
-
| Zhihu trending topics (max 30) | `python3 $SEARCH hot --limit N` |
|
|
95
|
+
| Zhihu trending topics (max 30) | `python3 "$SEARCH" hot --limit N` |
|
|
75
96
|
|
|
76
97
|
### Search result fields
|
|
77
98
|
|
|
@@ -99,22 +120,25 @@ The skill ships [`scripts/blog.py`](scripts/blog.py) — self-contained, stdlib
|
|
|
99
120
|
Requires `ZHIHU_COOKIES` (login cookie).
|
|
100
121
|
|
|
101
122
|
```sh
|
|
102
|
-
|
|
123
|
+
# Resolve the scripts first (see "Locate the scripts first" above) — robust to $SKILL_DIR.
|
|
124
|
+
ZDIR="$SKILL_DIR"; [ -f "$ZDIR/scripts/blog.py" ] || ZDIR=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/blog.py' 2>/dev/null | head -1 | sed 's#/scripts/blog.py##')
|
|
125
|
+
BLOG="$ZDIR/scripts/blog.py"
|
|
103
126
|
|
|
104
127
|
# Read (run directly)
|
|
105
|
-
python3 $BLOG whoami
|
|
106
|
-
python3 $BLOG articles --limit 20
|
|
107
|
-
python3 $BLOG article <article-id>
|
|
108
|
-
python3 $BLOG answers --limit 20
|
|
109
|
-
python3 $BLOG answer <answer-id>
|
|
110
|
-
python3 $BLOG question <question-id>
|
|
128
|
+
python3 "$BLOG" whoami # who is logged in
|
|
129
|
+
python3 "$BLOG" articles --limit 20 # my published articles + stats
|
|
130
|
+
python3 "$BLOG" article <article-id> # one article's details + stats
|
|
131
|
+
python3 "$BLOG" answers --limit 20 # my published answers + stats
|
|
132
|
+
python3 "$BLOG" answer <answer-id> # one answer's details + stats
|
|
133
|
+
python3 "$BLOG" question <question-id> # a question's info + whether I answered it
|
|
111
134
|
```
|
|
112
135
|
|
|
113
136
|
## Verify the connection first
|
|
114
137
|
|
|
115
138
|
```sh
|
|
116
|
-
|
|
117
|
-
|
|
139
|
+
ZDIR="$SKILL_DIR"; [ -f "$ZDIR/scripts/blog.py" ] || ZDIR=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/blog.py' 2>/dev/null | head -1 | sed 's#/scripts/blog.py##')
|
|
140
|
+
python3 "$ZDIR/scripts/blog.py" whoami
|
|
141
|
+
# → {"id": "...", "name": "崔庆才丨静觅", "url_token": "Germey", ...}
|
|
118
142
|
```
|
|
119
143
|
|
|
120
144
|
On a `401`/`403` the cookie is expired — tell the user to reconnect at
|
|
@@ -125,13 +149,13 @@ extension). Do **not** retry in a loop.
|
|
|
125
149
|
|
|
126
150
|
| Goal | Command |
|
|
127
151
|
|---|---|
|
|
128
|
-
| Who am I | `python3 $BLOG whoami` |
|
|
129
|
-
| My latest articles + vote/comment counts | `python3 $BLOG articles --limit 20` |
|
|
130
|
-
| My latest answers + like/favorite/comment counts | `python3 $BLOG answers --limit 20` |
|
|
152
|
+
| Who am I | `python3 "$BLOG" whoami` |
|
|
153
|
+
| My latest articles + vote/comment counts | `python3 "$BLOG" articles --limit 20` |
|
|
154
|
+
| My latest answers + like/favorite/comment counts | `python3 "$BLOG" answers --limit 20` |
|
|
131
155
|
| Next page (any list) | add `--offset 20` |
|
|
132
|
-
| One article's stats | `python3 $BLOG article <id>` |
|
|
133
|
-
| One answer's stats (incl. 赞同 voteup) | `python3 $BLOG answer <id>` |
|
|
134
|
-
| A question's info + my answer id (if any) | `python3 $BLOG question <id>` |
|
|
156
|
+
| One article's stats | `python3 "$BLOG" article <id>` |
|
|
157
|
+
| One answer's stats (incl. 赞同 voteup) | `python3 "$BLOG" answer <id>` |
|
|
158
|
+
| A question's info + my answer id (if any) | `python3 "$BLOG" question <id>` |
|
|
135
159
|
|
|
136
160
|
Article stats: `voteup_count` (赞同), `comment_count` (评论). Zhihu does not
|
|
137
161
|
expose per-article read counts on these endpoints.
|
|
@@ -153,9 +177,9 @@ never silently go live. Always show the dry-run to the user, get an explicit
|
|
|
153
177
|
|
|
154
178
|
```sh
|
|
155
179
|
# Content is HTML. For Markdown, convert to HTML first (e.g. `pandoc -f gfm -t html`).
|
|
156
|
-
python3 $BLOG publish --title "标题" --content-file article.html # dry-run
|
|
157
|
-
python3 $BLOG publish --title "标题" --content-file article.html --draft-only --confirm # save a private draft
|
|
158
|
-
python3 $BLOG publish --title "标题" --content-file article.html --confirm # PUBLIC, goes live
|
|
180
|
+
python3 "$BLOG" publish --title "标题" --content-file article.html # dry-run
|
|
181
|
+
python3 "$BLOG" publish --title "标题" --content-file article.html --draft-only --confirm # save a private draft
|
|
182
|
+
python3 "$BLOG" publish --title "标题" --content-file article.html --confirm # PUBLIC, goes live
|
|
159
183
|
```
|
|
160
184
|
|
|
161
185
|
- `--draft-only` stops after saving a private draft (safe — nothing public).
|
|
@@ -180,13 +204,13 @@ re-run with `--confirm` last.
|
|
|
180
204
|
# Content is HTML (same as articles). For Markdown, convert to HTML first.
|
|
181
205
|
|
|
182
206
|
# Post a NEW answer to a question
|
|
183
|
-
python3 $BLOG answer-question --question <qid> --content-file ans.html # dry-run
|
|
184
|
-
python3 $BLOG answer-question --question <qid> --content-file ans.html --draft-only --confirm # PRIVATE draft (safe)
|
|
185
|
-
python3 $BLOG answer-question --question <qid> --content-file ans.html --confirm # PUBLIC, goes live
|
|
207
|
+
python3 "$BLOG" answer-question --question <qid> --content-file ans.html # dry-run
|
|
208
|
+
python3 "$BLOG" answer-question --question <qid> --content-file ans.html --draft-only --confirm # PRIVATE draft (safe)
|
|
209
|
+
python3 "$BLOG" answer-question --question <qid> --content-file ans.html --confirm # PUBLIC, goes live
|
|
186
210
|
|
|
187
211
|
# Edit an EXISTING answer (replaces its live, public content)
|
|
188
|
-
python3 $BLOG edit-answer --id <answer-id> --content-file ans.html # dry-run
|
|
189
|
-
python3 $BLOG edit-answer --id <answer-id> --content-file ans.html --confirm # overwrites live answer
|
|
212
|
+
python3 "$BLOG" edit-answer --id <answer-id> --content-file ans.html # dry-run
|
|
213
|
+
python3 "$BLOG" edit-answer --id <answer-id> --content-file ans.html --confirm # overwrites live answer
|
|
190
214
|
```
|
|
191
215
|
|
|
192
216
|
- **One answer per question.** Zhihu allows a single answer per user per
|
|
@@ -13,12 +13,18 @@ Read commands run directly. ``publish`` is GATED: without a trailing
|
|
|
13
13
|
``--confirm`` is honored ONLY as the last argument, so a title/content that
|
|
14
14
|
merely contains "--confirm" can never silently go live.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
Invocation: resolve this script's path robustly first (see SKILL.md "Locate the
|
|
17
|
+
scripts first"), then call it via $BLOG. Do NOT hard-code
|
|
18
|
+
``python3 $SKILL_DIR/scripts/blog.py`` — $SKILL_DIR points at the LAST skill
|
|
19
|
+
loaded in the turn, so if another skill was loaded too it breaks with
|
|
20
|
+
"No such file or directory".
|
|
21
|
+
|
|
22
|
+
Quick examples (after ``BLOG=<resolved-dir>/blog.py``):
|
|
23
|
+
python3 "$BLOG" whoami
|
|
24
|
+
python3 "$BLOG" articles --limit 20
|
|
25
|
+
python3 "$BLOG" article <article-id>
|
|
26
|
+
python3 "$BLOG" question <question-id>
|
|
27
|
+
python3 "$BLOG" publish --title "T" --content-file a.html --draft-only --confirm
|
|
22
28
|
"""
|
|
23
29
|
|
|
24
30
|
from __future__ import annotations
|
|
@@ -11,14 +11,20 @@ Endpoints:
|
|
|
11
11
|
global_search — search the entire web with optional filters
|
|
12
12
|
hot_list — current Zhihu trending topics
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
python3 $
|
|
14
|
+
Invocation: resolve this script's path robustly first (see SKILL.md "Locate the
|
|
15
|
+
scripts first"), then call it via $SEARCH. Do NOT hard-code
|
|
16
|
+
``python3 $SKILL_DIR/scripts/search.py`` — $SKILL_DIR points at the LAST skill
|
|
17
|
+
loaded in the turn, so if another skill was loaded too it breaks with
|
|
18
|
+
"No such file or directory".
|
|
19
|
+
|
|
20
|
+
Quick examples (after ``SEARCH=<resolved-dir>/search.py``):
|
|
21
|
+
python3 "$SEARCH" search "Python 爬虫"
|
|
22
|
+
python3 "$SEARCH" search "Python 爬虫" --count 5
|
|
23
|
+
python3 "$SEARCH" global "AI Agent" --count 10
|
|
24
|
+
python3 "$SEARCH" global "React" --filter 'host=="github.com"'
|
|
25
|
+
python3 "$SEARCH" global "新闻" --db realtime
|
|
26
|
+
python3 "$SEARCH" hot
|
|
27
|
+
python3 "$SEARCH" hot --limit 10
|
|
22
28
|
"""
|
|
23
29
|
|
|
24
30
|
from __future__ import annotations
|