@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acedatacloud/skills",
3
- "version": "2026.704.4",
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 linked Page:
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
- PAGE=$(curl -sS "https://graph.facebook.com/v21.0/me/accounts?access_token=$INSTAGRAM_ACCESS_TOKEN" | jq -r '.data[0].id')
34
- 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')
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
  ```
@@ -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
- SEARCH=$SKILL_DIR/scripts/search.py
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
- BLOG=$SKILL_DIR/scripts/blog.py
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 # who is logged in
106
- python3 $BLOG articles --limit 20 # my published articles + stats
107
- python3 $BLOG article <article-id> # one article's details + stats
108
- python3 $BLOG answers --limit 20 # my published answers + stats
109
- python3 $BLOG answer <answer-id> # one answer's details + stats
110
- python3 $BLOG question <question-id> # a question's info + whether I answered it
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
- python3 $BLOG whoami
117
- # → {"id": "...", "name": "崔庆才丨静觅", "url_token": "cui-qing-cai", ...}
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
- Quick examples:
17
- python3 $SKILL_DIR/scripts/blog.py whoami
18
- python3 $SKILL_DIR/scripts/blog.py articles --limit 20
19
- python3 $SKILL_DIR/scripts/blog.py article <article-id>
20
- python3 $SKILL_DIR/scripts/blog.py drafts
21
- python3 $SKILL_DIR/scripts/blog.py publish --title "T" --content-file a.html --draft-only --confirm
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
- Quick examples:
15
- python3 $SKILL_DIR/scripts/search.py search "Python 爬虫"
16
- python3 $SKILL_DIR/scripts/search.py search "Python 爬虫" --count 5
17
- python3 $SKILL_DIR/scripts/search.py global "AI Agent" --count 10
18
- python3 $SKILL_DIR/scripts/search.py global "React" --filter 'host=="github.com"'
19
- python3 $SKILL_DIR/scripts/search.py global "新闻" --db realtime
20
- python3 $SKILL_DIR/scripts/search.py hot
21
- python3 $SKILL_DIR/scripts/search.py hot --limit 10
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