socialdatax-skills 0.2.31 → 0.2.33

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/README.md CHANGED
@@ -86,7 +86,7 @@ Common search phrases for this skill package:
86
86
  - Sensitive Words Check MCP server name: `sensitive-check`
87
87
  - Sensitive Words Check future MCP registry name: `com.socialdatax/sensitive-check`
88
88
  - Unified MCP registry name: none; this package installs skills and calls explicit platform services.
89
- - Current public capability version: `0.2.31`
89
+ - Current public capability version: `0.2.33`
90
90
 
91
91
  ## Direct CLI
92
92
 
@@ -172,8 +172,8 @@ npx -y socialdatax-skills@latest wechat comments --object-id "<object_id>" --obj
172
172
  npx -y socialdatax-skills@latest wechat comments --object-id "<object_id>" --object-nonce-id "<object_nonce_id>" --all --include-replies --pretty
173
173
  npx -y socialdatax-skills@latest wechat comments --url "<wechat_video_url_or_share_text>" --pretty
174
174
  npx -y socialdatax-skills@latest wechat replies --object-id "<object_id>" --object-nonce-id "<object_nonce_id>" --comment-id "<comment_id>" --pretty
175
- npx -y socialdatax-skills@latest wechat user-info --user-id "<finder_user_id>" --pretty
176
- npx -y socialdatax-skills@latest wechat user-posts --user-id "<finder_user_id>" --pretty
175
+ npx -y socialdatax-skills@latest wechat user-info --user-id "<v2_finder_user_id>" --pretty
176
+ npx -y socialdatax-skills@latest wechat user-posts --user-id "<v2_finder_user_id>" --pretty
177
177
  npx -y socialdatax-skills@latest wechat user-posts --url "<wechat_video_url_or_share_text>" --pretty
178
178
  npx -y socialdatax-skills@latest wechat transcript --url "<wechat_video_url_or_share_text>" --pretty
179
179
  npx -y socialdatax-skills@latest wechat transcript --encrypted-object-id "<encrypted_object_id>" --pretty
@@ -183,7 +183,7 @@ npx -y socialdatax-skills@latest sensitive-check text --text "<content>" --platf
183
183
 
184
184
  Most direct CLI commands print a JSON envelope with `platform`, `tool`, `arguments`, and `data`. `sensitive-check` prints `platform`, `tool`, and `data` only; it does not echo the original text in CLI output. `wechat decrypt-media` is a local save command: pass the `video.video_url` returned by WeChat detail and an `--output` file path. It saves the media locally, decrypts when needed, and does not require `SOCIALDATAX_API_KEY`. `xhs/douyin/kuaishou/weibo download-media` is also local: pass one media URL returned by detail and either `--output <file>` or `--output-dir <directory>`. It writes through a `.part` file, resumes partial downloads when the server supports range requests, skips an already existing output file, and infers common image/video/audio extensions in `--output-dir` mode.
185
185
 
186
- For transcript commands, the direct CLI tries to deliver the final result in one run: submit may wait up to 210 seconds, and if `data.is_terminal` is not `true`, the CLI automatically continues matching get-job requests for up to 1200 seconds by default, with each get-job request waiting up to 240 seconds. Use positive `--max-wait-seconds <seconds>` to tune that follow-up window. Do not submit a duplicate transcript job just to poll status.
186
+ For transcript commands, the direct CLI tries to deliver the final result in one run: submit may wait up to 240 seconds, and if `data.is_terminal` is not `true`, the CLI automatically continues matching get-job requests for up to 1200 seconds by default, with each get-job request waiting up to 240 seconds. Use positive `--max-wait-seconds <seconds>` to tune that follow-up window. Do not submit a duplicate transcript job just to poll status.
187
187
 
188
188
  `bilibili download` calls SocialDataX once to fetch short-lived download links, then downloads video and audio tracks on the local machine and merges them with local `ffmpeg`. Set `SOCIALDATAX_API_KEY`, install `ffmpeg`, and pass either `--output <file>` or `--output-dir <directory>`. The download-links request consumes 10 credits; the local track download and merge do not consume additional SocialDataX credits. Use `--ffmpeg-path <path>` when `ffmpeg` is not on `PATH`, and `--keep-tracks` to retain the separate track files after merge.
189
189
 
@@ -369,7 +369,7 @@ Current XHS workflows include:
369
369
  - Fetch paginated replies under a first-level comment.
370
370
  - Read creator profile data from a profile link, short link, share text, or user ID.
371
371
  - Fetch paginated creator note lists from a user ID, profile link, short link, or share text for content style and account research.
372
- - Submit and check video note 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 210 秒,未完成时继续查询同一个 job_id 直到终态.
372
+ - Submit and check video note 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 240 秒,未完成时继续查询同一个 job_id 直到终态.
373
373
  - Save returned `image_items[].image_url`, `image_items[].live_photo.video_url`, or `video.video_url` media links locally with `xhs download-media`.
374
374
 
375
375
  Current Kuaishou workflows include:
@@ -383,7 +383,7 @@ Current Kuaishou workflows include:
383
383
  - Continue Kuaishou list pagination only when `next_page_token` is non-empty; an empty string means there are no more results to request.
384
384
  - Read creator profile data from a non-empty user_id, profile link, short link, or share text. Live/fw-user profile shares are supported for profile data; successful results return a reusable non-empty user_id.
385
385
  - Fetch paginated creator work lists from a non-empty user_id, or from a profile link, short link, or share text that resolves directly to a non-empty user_id. For live/fw-user profile shares, call creator profile first and use the returned non-empty user_id.
386
- - Submit and check video work 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 210 秒,未完成时继续查询同一个 job_id 直到终态.
386
+ - Submit and check video work 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 240 秒,未完成时继续查询同一个 job_id 直到终态.
387
387
  - Save returned `images[].url`, `video.play_url`, or `cover_image_url` media links locally with `kuaishou download-media`.
388
388
 
389
389
  Current Bilibili workflows include:
@@ -403,7 +403,7 @@ Current Douyin workflows include:
403
403
  - Read creator profile data from a profile link, short link, share text, or sec_user_id.
404
404
  - Fetch paginated creator work lists from a sec_user_id, profile link, short link, or share text.
405
405
  - Fetch paginated creator short-drama series lists from a sec_user_id, profile link, short link, or share text.
406
- - Submit and check video work 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 210 秒,未完成时继续查询同一个 job_id 直到终态.
406
+ - Submit and check video work 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 240 秒,未完成时继续查询同一个 job_id 直到终态.
407
407
  - Save returned `images[].url`, `images[].live_photo.play_url`, `video.play_url`, `music.play_url`, or `cover_image_url` media links locally with `douyin download-media`.
408
408
 
409
409
  Current Weibo workflows include:
@@ -416,7 +416,7 @@ Current Weibo workflows include:
416
416
  - Continue Weibo list pagination only when `next_page_token` is non-empty; an empty string means there are no more results to request.
417
417
  - Read creator profile data from a profile link, short link, share text, or user_id.
418
418
  - Fetch paginated creator post lists from a user_id, profile link, short link, or share text.
419
- - Submit and check Weibo video 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 210 秒,未完成时继续查询同一个 job_id 直到终态.
419
+ - Submit and check Weibo video 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 240 秒,未完成时继续查询同一个 job_id 直到终态.
420
420
  - Save returned `image_urls[]` or `video.video_url` media links locally with `weibo download-media`.
421
421
 
422
422
  Current WeChat / 微信 workflows include:
@@ -429,9 +429,9 @@ Current WeChat / 微信 workflows include:
429
429
  - Fetch paginated first-level comments for comment analysis.
430
430
  - Fetch paginated replies under a first-level comment; pass `object_id`, `object_nonce_id`, and `comment_id`.
431
431
  - Continue WeChat Channels list pagination only when `next_page_token` is non-empty; an empty string means there are no more results to request.
432
- - Read creator profile data from a finder user_id.
433
- - Fetch paginated creator video lists from a finder user_id or a video link/share text.
434
- - Submit and check WeChat Channels / 视频号 video 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 210 秒,未完成时继续查询同一个 job_id 直到终态.
432
+ - Read creator profile data from a `v2_...@finder` user_id.
433
+ - Fetch paginated creator video lists from a `v2_...@finder` user_id or a video link/share text.
434
+ - Submit and check WeChat Channels / 视频号 video 口播转文字 / speech-to-text transcript jobs; submit tools 提交后最多等待 240 秒,未完成时继续查询同一个 job_id 直到终态.
435
435
 
436
436
  Current Sensitive Words Check workflows include:
437
437
 
@@ -455,9 +455,9 @@ Current Sensitive Words Check workflows include:
455
455
  | `xhs_get_user_info_by_profile_url` | Resolve a profile link, short link, or share text into creator profile data. |
456
456
  | `xhs_get_user_posted_notes_by_user_id` | Fetch a paginated list of notes published by a creator when the caller already has a user ID. |
457
457
  | `xhs_get_user_posted_notes_by_profile_url` | Fetch a paginated list of notes published by a creator from a profile link, short link, or share text. |
458
- | `xhs_submit_video_speech_text_by_note_url` | Submit an XHS video note speech-to-text transcript job from a note link, short link, or share text; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
459
- | `xhs_submit_video_speech_text_by_note_id` | Submit an XHS video note speech-to-text transcript job when the caller already has a note ID; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
460
- | `xhs_get_video_speech_text_job` | Check an XHS speech-to-text transcript job by job_id without creating a new task; optional wait_seconds 0-240 can long-poll the same job in one request. Continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
458
+ | `xhs_submit_video_speech_text_by_note_url` | Submit an XHS video note speech-to-text transcript job from a note link, short link, or share text; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
459
+ | `xhs_submit_video_speech_text_by_note_id` | Submit an XHS video note speech-to-text transcript job when the caller already has a note ID; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
460
+ | `xhs_get_video_speech_text_job` | Check an XHS speech-to-text transcript job by job_id without creating a new task. Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
461
461
 
462
462
  ## Douyin Tools
463
463
 
@@ -476,9 +476,9 @@ Current Sensitive Words Check workflows include:
476
476
  | `douyin_get_user_posted_videos_by_profile_url` | Fetch a paginated list of works published by a creator from a profile link, short link, or share text. |
477
477
  | `douyin_get_user_series_by_sec_user_id` | Fetch a paginated list of short-drama series by a creator when the caller already has a sec_user_id. |
478
478
  | `douyin_get_user_series_by_profile_url` | Fetch a paginated list of short-drama series by a creator from a profile link, short link, or share text. |
479
- | `douyin_submit_video_speech_text_by_video_url` | Submit a Douyin video speech-to-text transcript job from a content page link, short link, or share text; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
480
- | `douyin_submit_video_speech_text_by_aweme_id` | Submit a Douyin video speech-to-text transcript job when the caller already has an aweme_id; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
481
- | `douyin_get_video_speech_text_job` | Check a Douyin speech-to-text transcript job by job_id without creating a new task; optional wait_seconds 0-240 can long-poll the same job in one request. Continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
479
+ | `douyin_submit_video_speech_text_by_video_url` | Submit a Douyin video speech-to-text transcript job from a content page link, short link, or share text; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
480
+ | `douyin_submit_video_speech_text_by_aweme_id` | Submit a Douyin video speech-to-text transcript job when the caller already has an aweme_id; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
481
+ | `douyin_get_video_speech_text_job` | Check a Douyin speech-to-text transcript job by job_id without creating a new task. Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
482
482
 
483
483
  ## Kuaishou Tools
484
484
 
@@ -496,9 +496,9 @@ Current Sensitive Words Check workflows include:
496
496
  | `kuaishou_get_user_info_by_profile_url` | Resolve a Kuaishou profile link, including live/fw-user profile shares, short link, or share text into creator profile data; successful results return a reusable non-empty user_id. |
497
497
  | `kuaishou_get_user_posted_videos_by_user_id` | Fetch a paginated list of works published by a creator when the caller already has a non-empty user_id. |
498
498
  | `kuaishou_get_user_posted_videos_by_profile_url` | Fetch a paginated list of works published by a creator from a profile link, short link, or share text that resolves directly to a non-empty user_id; for live/fw-user profile shares, call creator profile first and use the returned non-empty user_id. |
499
- | `kuaishou_submit_video_speech_text_by_video_url` | Submit a Kuaishou video speech-to-text transcript job from a work page link, short link, or share text; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
500
- | `kuaishou_submit_video_speech_text_by_photo_id` | Submit a Kuaishou video speech-to-text transcript job when the caller already has a photo_id; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
501
- | `kuaishou_get_video_speech_text_job` | Check a Kuaishou speech-to-text transcript job by job_id without creating a new task; optional wait_seconds 0-240 can long-poll the same job in one request. Continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
499
+ | `kuaishou_submit_video_speech_text_by_video_url` | Submit a Kuaishou video speech-to-text transcript job from a work page link, short link, or share text; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
500
+ | `kuaishou_submit_video_speech_text_by_photo_id` | Submit a Kuaishou video speech-to-text transcript job when the caller already has a photo_id; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
501
+ | `kuaishou_get_video_speech_text_job` | Check a Kuaishou speech-to-text transcript job by job_id without creating a new task. Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
502
502
 
503
503
  ## Bilibili Tools
504
504
 
@@ -521,9 +521,9 @@ Current Sensitive Words Check workflows include:
521
521
  | `weibo_get_user_info_by_profile_url` | Resolve a Weibo profile link, short link, or share text into creator profile data. |
522
522
  | `weibo_get_user_posts_by_user_id` | Fetch a paginated list of posts published by a creator when the caller already has a user_id. |
523
523
  | `weibo_get_user_posts_by_profile_url` | Fetch a paginated list of posts published by a creator from a profile link, short link, or share text. |
524
- | `weibo_submit_video_speech_text_by_post_url` | Submit a Weibo video speech-to-text transcript job from a post URL, short link, or share text; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
525
- | `weibo_submit_video_speech_text_by_post_id` | Submit a Weibo video speech-to-text transcript job when the caller already has a post_id; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
526
- | `weibo_get_video_speech_text_job` | Check a Weibo speech-to-text transcript job by job_id without creating a new task; optional wait_seconds 0-240 can long-poll the same job in one request. Continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
524
+ | `weibo_submit_video_speech_text_by_post_url` | Submit a Weibo video speech-to-text transcript job from a post URL, short link, or share text; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
525
+ | `weibo_submit_video_speech_text_by_post_id` | Submit a Weibo video speech-to-text transcript job when the caller already has a post_id; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
526
+ | `weibo_get_video_speech_text_job` | Check a Weibo speech-to-text transcript job by job_id without creating a new task. Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
527
527
 
528
528
  ## WeChat Tools
529
529
 
@@ -537,12 +537,12 @@ Current Sensitive Words Check workflows include:
537
537
  | `wechat_get_video_comments_by_object_id` | Fetch paginated first-level comments when object_id and object_nonce_id are known. |
538
538
  | `wechat_get_video_comments_by_url` | Fetch paginated first-level comments directly from a WeChat Channels / 视频号 video link or share text. |
539
539
  | `wechat_get_video_comment_replies_by_comment_id` | Fetch paginated replies under a first-level comment by object_id, object_nonce_id, and comment_id. |
540
- | `wechat_get_user_info_by_user_id` | Fetch creator profile data when the finder user_id is already known. |
541
- | `wechat_get_user_posted_videos_by_user_id` | Fetch a paginated list of videos published by a creator when the finder user_id is already known. |
540
+ | `wechat_get_user_info_by_user_id` | Fetch creator profile data when the `v2_...@finder` user_id is already known. |
541
+ | `wechat_get_user_posted_videos_by_user_id` | Fetch a paginated list of videos published by a creator when the `v2_...@finder` user_id is already known. |
542
542
  | `wechat_get_user_posted_videos_by_url` | Fetch a paginated list of videos published by a creator from a video link or share text. |
543
- | `wechat_submit_video_speech_text_by_video_url` | Submit a WeChat Channels / 视频号 video speech-to-text transcript job from a video link or share text; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
544
- | `wechat_submit_video_speech_text_by_encrypted_object_id` | Submit a WeChat Channels / 视频号 video speech-to-text transcript job when encrypted_object_id is already known; submit waits up to 210 seconds. If unfinished, continue checking the same job_id with get-job wait_seconds up to 240 until is_terminal is true. |
545
- | `wechat_get_video_speech_text_job` | Check a WeChat Channels / 视频号 speech-to-text transcript job by job_id without creating a new task; optional wait_seconds 0-240 can long-poll the same job in one request. Continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
543
+ | `wechat_submit_video_speech_text_by_video_url` | Submit a WeChat Channels / 视频号 video speech-to-text transcript job from a video link or share text; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
544
+ | `wechat_submit_video_speech_text_by_encrypted_object_id` | Submit a WeChat Channels / 视频号 video speech-to-text transcript job when encrypted_object_id is already known; submit waits up to 240 seconds. If unfinished, continue checking the same job_id until is_terminal is true. |
545
+ | `wechat_get_video_speech_text_job` | Check a WeChat Channels / 视频号 speech-to-text transcript job by job_id without creating a new task. Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true. Returns transcript plus content context, not summary. |
546
546
 
547
547
  ## Sensitive Words Check Tools
548
548
 
package/cli.mjs CHANGED
@@ -22,7 +22,7 @@ import { decryptWechatMediaCommand } from "./lib/media/wechat-decrypt.mjs";
22
22
  export { decryptWechatMediaCommand };
23
23
 
24
24
  const PACKAGE_NAME = "socialdatax-skills";
25
- const PACKAGE_VERSION = "0.2.31";
25
+ const PACKAGE_VERSION = "0.2.33";
26
26
  const PACKAGE_SPEC = `${PACKAGE_NAME}@latest`;
27
27
  const LOG_PREFIX = `[${PACKAGE_NAME}]`;
28
28
  const MIN_NODE_VERSION = "20.18.1";
@@ -43,15 +43,16 @@ const SOURCE_ATTRIBUTION_PATTERN = /^[a-z0-9][a-z0-9-]{0,99}$/;
43
43
  export const TRANSCRIPT_JOB_DESCRIPTION_SUFFIX =
44
44
  "Returns transcript plus content context, not summary.";
45
45
  const TRANSCRIPT_SUBMIT_WAIT_DESCRIPTION =
46
- "提交后最多等待 210 秒;未完成时继续用对应 get-job 查询同一个 job_id 直到终态,不要重复提交.";
46
+ "提交后最多等待 240 秒;未完成时继续用对应 get-job 查询同一个 job_id 直到终态,不要重复提交.";
47
47
  const TRANSCRIPT_GET_JOB_WAIT_DESCRIPTION =
48
- "Optional wait_seconds 0-240 can long-poll the same job in one request.";
48
+ "Each call waits up to 240 seconds for the same job. If unfinished, continue querying the same job_id until is_terminal is true.";
49
49
  const TRANSCRIPT_DEFAULT_MAX_WAIT_SECONDS = 1200;
50
- const TRANSCRIPT_GET_JOB_WAIT_SECONDS = 240;
51
50
  const TRANSCRIPT_FALLBACK_POLL_SECONDS = 2;
51
+ const TRANSCRIPT_MCP_CALL_TIMEOUT_MS = 330_000;
52
+ const MCP_REQUEST_TIMEOUT_ERROR_CODE = -32001;
52
53
 
53
54
  export function buildTranscriptJobDescription(subject) {
54
- return `Check ${subject} by job_id without starting a new task. ${TRANSCRIPT_GET_JOB_WAIT_DESCRIPTION} Continue querying the same job_id until is_terminal is true. ${TRANSCRIPT_JOB_DESCRIPTION_SUFFIX}`;
55
+ return `Check ${subject} by job_id without starting a new task. ${TRANSCRIPT_GET_JOB_WAIT_DESCRIPTION} ${TRANSCRIPT_JOB_DESCRIPTION_SUFFIX}`;
55
56
  }
56
57
 
57
58
  const AVAILABLE_SKILLS = [
@@ -926,11 +927,11 @@ const PLATFORMS = {
926
927
  },
927
928
  {
928
929
  name: "wechat_get_user_info_by_user_id",
929
- description: "Fetch creator profile data when the finder user_id is already known.",
930
+ description: "Fetch creator profile data when the v2_...@finder user_id is already known.",
930
931
  },
931
932
  {
932
933
  name: "wechat_get_user_posted_videos_by_user_id",
933
- description: "Fetch a paginated list of videos published by a creator when the finder user_id is already known.",
934
+ description: "Fetch a paginated list of videos published by a creator when the v2_...@finder user_id is already known.",
934
935
  },
935
936
  {
936
937
  name: "wechat_get_user_posted_videos_by_url",
@@ -2129,11 +2130,11 @@ function printHelp() {
2129
2130
  );
2130
2131
  console.log(" Call the WeChat Channels / 视频号 comment replies tool directly and print JSON.");
2131
2132
  console.log("");
2132
- console.log(` npx -y ${PACKAGE_SPEC} wechat user-info --user-id "<finder_user_id>" --pretty`);
2133
- console.log(" Call the WeChat Channels / 视频号 creator profile tool directly and print JSON.");
2133
+ console.log(` npx -y ${PACKAGE_SPEC} wechat user-info --user-id "<v2_finder_user_id>" --pretty`);
2134
+ console.log(" Call the WeChat Channels / 视频号 creator profile tool with a v2_...@finder user_id.");
2134
2135
  console.log("");
2135
- console.log(` npx -y ${PACKAGE_SPEC} wechat user-posts --user-id "<finder_user_id>" --pretty`);
2136
- console.log(" Call the WeChat Channels / 视频号 creator videos tool directly and print JSON.");
2136
+ console.log(` npx -y ${PACKAGE_SPEC} wechat user-posts --user-id "<v2_finder_user_id>" --pretty`);
2137
+ console.log(" Call the WeChat Channels / 视频号 creator videos tool with a v2_...@finder user_id.");
2137
2138
  console.log("");
2138
2139
  console.log(` npx -y ${PACKAGE_SPEC} wechat user-posts --url "<wechat_video_url_or_share_text>" --pretty`);
2139
2140
  console.log(" Call the WeChat Channels / 视频号 creator videos tool from a video link or share text.");
@@ -3764,10 +3765,10 @@ function buildXhsSubCommentsCall(options) {
3764
3765
  };
3765
3766
  }
3766
3767
 
3767
- async function callDirectOperation(operation) {
3768
+ async function callDirectOperation(operation, requestOptions) {
3768
3769
  switch (operation.backend) {
3769
3770
  case "mcp":
3770
- return callMcpBackend(operation);
3771
+ return callMcpBackend(operation, requestOptions);
3771
3772
  default:
3772
3773
  throw new Error(`Unsupported direct CLI backend: ${operation.backend}.`);
3773
3774
  }
@@ -3785,7 +3786,7 @@ async function callDirectOperationWithOptions(operation, options) {
3785
3786
 
3786
3787
  async function callTranscriptDirectOperation(operation, options) {
3787
3788
  const maxWaitSeconds = parseTranscriptMaxWaitSeconds(options);
3788
- let currentOperation = transcriptInitialOperation(operation, maxWaitSeconds);
3789
+ let currentOperation = transcriptInitialOperation(operation);
3789
3790
  let data = await callDirectOperation(currentOperation);
3790
3791
  if (maxWaitSeconds <= 0 || isTerminalTranscriptData(data)) {
3791
3792
  return data;
@@ -3822,12 +3823,18 @@ async function callTranscriptDirectOperation(operation, options) {
3822
3823
  break;
3823
3824
  }
3824
3825
 
3825
- currentOperation = transcriptGetJobOperation(
3826
- operation,
3827
- jobId,
3828
- transcriptWaitSecondsForCall(remainingSeconds)
3829
- );
3830
- data = await callDirectOperation(currentOperation);
3826
+ currentOperation = transcriptGetJobOperation(operation, jobId);
3827
+ try {
3828
+ data = await callDirectOperation(currentOperation, {
3829
+ requestDeadlineMs: Date.now() + remainingSeconds * 1000,
3830
+ preserveRequestTimeout: true,
3831
+ });
3832
+ } catch (error) {
3833
+ if (isMcpRequestTimeoutError(error)) {
3834
+ break;
3835
+ }
3836
+ throw error;
3837
+ }
3831
3838
  jobId = readTranscriptJobId(data, operation) || jobId;
3832
3839
  }
3833
3840
 
@@ -3844,38 +3851,21 @@ function parseTranscriptMaxWaitSeconds(options) {
3844
3851
  return TRANSCRIPT_DEFAULT_MAX_WAIT_SECONDS;
3845
3852
  }
3846
3853
 
3847
- function transcriptInitialOperation(operation, maxWaitSeconds) {
3848
- const initialOperation = cloneDirectOperation(operation);
3849
- const isJobLookup =
3850
- operation.transcriptIsJobLookup ||
3851
- operation.tool === operation.transcriptJobTool ||
3852
- Object.hasOwn(operation.arguments, "job_id");
3853
- if (isJobLookup && maxWaitSeconds > 0) {
3854
- initialOperation.arguments.wait_seconds =
3855
- transcriptWaitSecondsForCall(maxWaitSeconds);
3856
- }
3857
- return initialOperation;
3854
+ function transcriptInitialOperation(operation) {
3855
+ return cloneDirectOperation(operation);
3858
3856
  }
3859
3857
 
3860
- function transcriptGetJobOperation(operation, jobId, waitSeconds) {
3858
+ function transcriptGetJobOperation(operation, jobId) {
3861
3859
  const jobArgument = operation.transcriptJobArgument || "job_id";
3862
3860
  return {
3863
3861
  ...operation,
3864
3862
  tool: operation.transcriptJobTool,
3865
3863
  arguments: {
3866
3864
  [jobArgument]: jobId,
3867
- wait_seconds: waitSeconds,
3868
3865
  },
3869
3866
  };
3870
3867
  }
3871
3868
 
3872
- function transcriptWaitSecondsForCall(remainingSeconds) {
3873
- return Math.min(
3874
- TRANSCRIPT_GET_JOB_WAIT_SECONDS,
3875
- Math.max(1, Math.ceil(remainingSeconds))
3876
- );
3877
- }
3878
-
3879
3869
  function transcriptRemainingWaitSeconds(startedAtMs, maxWaitSeconds) {
3880
3870
  return maxWaitSeconds - (Date.now() - startedAtMs) / 1000;
3881
3871
  }
@@ -4490,7 +4480,10 @@ function buildRepliesOperationForComment(platform, comment, parentArguments, par
4490
4480
  }
4491
4481
  }
4492
4482
 
4493
- async function callMcpBackend(operation) {
4483
+ async function callMcpBackend(
4484
+ operation,
4485
+ { requestDeadlineMs, requestTimeoutMs, preserveRequestTimeout = false } = {}
4486
+ ) {
4494
4487
  ensureSupportedNodeVersion();
4495
4488
  const { platform, tool } = operation;
4496
4489
  const apiKey = readDirectApiKey(platform);
@@ -4520,11 +4513,22 @@ async function callMcpBackend(operation) {
4520
4513
  });
4521
4514
 
4522
4515
  try {
4523
- await client.connect(transport);
4524
- const result = await client.callTool({
4525
- name: tool,
4526
- arguments: operation.arguments,
4516
+ const transcriptConnectOptions = transcriptMcpRequestOptions(operation, {
4517
+ requestDeadlineMs,
4518
+ requestTimeoutMs,
4527
4519
  });
4520
+ await connectMcpClient(client, transport, transcriptConnectOptions);
4521
+ const result = await client.callTool(
4522
+ {
4523
+ name: tool,
4524
+ arguments: operation.arguments,
4525
+ },
4526
+ undefined,
4527
+ transcriptMcpRequestOptions(operation, {
4528
+ requestDeadlineMs,
4529
+ requestTimeoutMs,
4530
+ })
4531
+ );
4528
4532
  if (result.isError) {
4529
4533
  const errorMessage =
4530
4534
  result.structuredContent?.message ||
@@ -4536,12 +4540,70 @@ async function callMcpBackend(operation) {
4536
4540
  }
4537
4541
  return result.structuredContent ?? result;
4538
4542
  } catch (error) {
4543
+ if (preserveRequestTimeout && isMcpRequestTimeoutError(error)) {
4544
+ throw error;
4545
+ }
4539
4546
  throw formatDirectCallError({ error, operation, upstreamUrl });
4540
4547
  } finally {
4541
4548
  await client.close().catch(() => {});
4542
4549
  }
4543
4550
  }
4544
4551
 
4552
+ function isMcpRequestTimeoutError(error) {
4553
+ return error?.code === MCP_REQUEST_TIMEOUT_ERROR_CODE;
4554
+ }
4555
+
4556
+ async function connectMcpClient(client, transport, requestOptions) {
4557
+ if (requestOptions?.timeout === undefined) {
4558
+ await client.connect(transport, requestOptions);
4559
+ return;
4560
+ }
4561
+ await withMcpRequestTimeout(
4562
+ client.connect(transport, requestOptions),
4563
+ requestOptions.timeout,
4564
+ () => client.close().catch(() => {})
4565
+ );
4566
+ }
4567
+
4568
+ function transcriptMcpRequestOptions(
4569
+ operation,
4570
+ { requestDeadlineMs, requestTimeoutMs }
4571
+ ) {
4572
+ if (operation.operation !== "transcript") {
4573
+ return undefined;
4574
+ }
4575
+ if (requestDeadlineMs !== undefined) {
4576
+ return {
4577
+ timeout: Math.max(Math.ceil(requestDeadlineMs - Date.now()), 1),
4578
+ };
4579
+ }
4580
+ return {
4581
+ timeout: requestTimeoutMs ?? TRANSCRIPT_MCP_CALL_TIMEOUT_MS,
4582
+ };
4583
+ }
4584
+
4585
+ async function withMcpRequestTimeout(promise, timeoutMs, onTimeout) {
4586
+ let timeoutId;
4587
+ const timeoutPromise = new Promise((_, reject) => {
4588
+ timeoutId = setTimeout(() => {
4589
+ reject(mcpRequestTimeoutError(timeoutMs));
4590
+ Promise.resolve(onTimeout?.()).catch(() => {});
4591
+ }, timeoutMs);
4592
+ });
4593
+ try {
4594
+ return await Promise.race([promise, timeoutPromise]);
4595
+ } finally {
4596
+ clearTimeout(timeoutId);
4597
+ }
4598
+ }
4599
+
4600
+ function mcpRequestTimeoutError(timeoutMs) {
4601
+ const error = new Error("Request timed out");
4602
+ error.code = MCP_REQUEST_TIMEOUT_ERROR_CODE;
4603
+ error.data = { timeout: timeoutMs };
4604
+ return error;
4605
+ }
4606
+
4545
4607
  function readDirectApiKey(platform) {
4546
4608
  const apiKey = readFirstEnv(platform.apiKeyEnv);
4547
4609
  if (!apiKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socialdatax-skills",
3
- "version": "0.2.31",
3
+ "version": "0.2.33",
4
4
  "description": "SocialDataX / 社媒数据助手 skill installer and direct CLI helper for hosted platform social media MCP services.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -122,7 +122,7 @@ Optional arguments:
122
122
  - `--source-client socialdatax-skills --source-platform npm --source-skill media-transcript`: usage attribution for this Agent Skill; keep these values unchanged when running examples from this Skill.
123
123
 
124
124
  Use the direct CLI first when the agent can run shell commands. These video speech-to-text transcript / 口播转文字 workflows submit a bounded analysis job or check an existing job.
125
- Direct CLI transcript commands try to deliver the final result in one run: submit waits server-side up to 210 seconds, then the CLI keeps querying the same `job_id` with get-job long polling of up to 240 seconds per request for a bounded follow-up window. Do not start a second submit job just to poll status.
125
+ Direct CLI transcript commands try to deliver the final result in one run: submit waits server-side up to 240 seconds, then the CLI keeps querying the same `job_id`; each get-job call also waits up to 240 seconds for that job. Do not start a second submit job just to poll status.
126
126
  If the direct CLI returns a non-terminal job because the command was interrupted or reached `--max-wait-seconds`, keep the returned `job_id` and continue with the matching `transcript --job-id <job_id>` command.
127
127
 
128
128
  ## Safety Boundary
@@ -155,7 +155,7 @@ If MCP tools are already available in the current agent, choose the platform-spe
155
155
  - Kuaishou: `kuaishou_submit_video_speech_text_by_video_url`, `kuaishou_submit_video_speech_text_by_photo_id`, `kuaishou_get_video_speech_text_job`.
156
156
  - Weibo: `weibo_submit_video_speech_text_by_post_url`, `weibo_submit_video_speech_text_by_post_id`, `weibo_get_video_speech_text_job`.
157
157
  - WeChat Channels / 视频号: `wechat_submit_video_speech_text_by_video_url`, `wechat_submit_video_speech_text_by_encrypted_object_id`, `wechat_get_video_speech_text_job`.
158
- Do not start a duplicate transcript job only to poll status. If an MCP response is non-terminal, call `data.next_action.tool_name` with `data.next_action.arguments` exactly as returned; those arguments include the same `job_id` and a bounded `wait_seconds` value. Continue until `is_terminal` is `true`.
158
+ Do not start a duplicate transcript job only to poll status. If an MCP response is non-terminal, you must call `data.next_action.tool_name` with `data.next_action.arguments` exactly as returned; those arguments include the same `job_id`. The next response may still be non-terminal. Continue until `is_terminal` is `true`.
159
159
 
160
160
  ## Output Guidance
161
161
 
@@ -33,7 +33,7 @@ Current platform support:
33
33
  - Kuaishou / 快手 creators through the `kuaishou_get_user_info_by_*` tools.
34
34
  - Kuaishou / 快手 creator discovery through `kuaishou_search_users` before profile lookup when only an account keyword or niche is known.
35
35
  - Weibo / 微博 creators through the `weibo_get_user_info_by_*` tools.
36
- - WeChat Channels / 视频号 creators through `wechat_get_user_info_by_user_id`.
36
+ - WeChat Channels / 视频号 creators through `wechat_get_user_info_by_user_id` when a `v2_...@finder` user_id is already known.
37
37
 
38
38
  ## API Key
39
39
 
@@ -86,7 +86,7 @@ npx -y socialdatax-skills@latest weibo user-info \
86
86
  --source-skill media-user-info
87
87
 
88
88
  npx -y socialdatax-skills@latest wechat user-info \
89
- --user-id "<finder_user_id>" --pretty --source-client socialdatax-skills \
89
+ --user-id "<v2_finder_user_id>" --pretty --source-client socialdatax-skills \
90
90
  --source-platform npm --source-skill media-user-info
91
91
  ```
92
92
 
@@ -104,7 +104,7 @@ Optional arguments:
104
104
  - Kuaishou `--profile-url <profile_url_or_share_text>`: use for a profile URL, short link, or profile share text. Live/fw-user profile shares are supported; successful profile results return a reusable non-empty user_id.
105
105
  - Weibo `--user-id <user_id>`: preferred when the creator user_id is already known.
106
106
  - Weibo `--profile-url <profile_url_or_share_text>`: use for a profile URL, short link, or profile share text.
107
- - WeChat Channels / 视频号 `--user-id <finder_user_id>`: use when the creator user_id ending with `@finder` is already known.
107
+ - WeChat Channels / 视频号 `--user-id <v2_finder_user_id>`: use when the creator `v2_...@finder` user_id is already known.
108
108
  - `--source-client socialdatax-skills --source-platform npm --source-skill media-user-info`: usage attribution for this Agent Skill; keep these values unchanged when running examples from this Skill.
109
109
 
110
110
  Use either the ID option or the profile URL option for a single command, not both.
@@ -140,7 +140,7 @@ If MCP tools are already available in the current agent, use one of these tools:
140
140
  - `kuaishou_get_user_info_by_profile_url`: use for profile URLs, short links, or profile share text, including live/fw-user profile shares; successful results return a reusable non-empty `user_id`.
141
141
  - `weibo_get_user_info_by_user_id`: preferred when `user_id` is already known.
142
142
  - `weibo_get_user_info_by_profile_url`: use for profile URLs, short links, or profile share text.
143
- - `wechat_get_user_info_by_user_id`: use when the WeChat Channels / 视频号 creator user_id ending with `@finder` is already known.
143
+ - `wechat_get_user_info_by_user_id`: use when the WeChat Channels / 视频号 creator `v2_...@finder` user_id is already known.
144
144
 
145
145
  ## Output Guidance
146
146
 
@@ -33,7 +33,7 @@ Current platform support:
33
33
  - Douyin / 抖音 creator short-drama series through the `douyin_get_user_series_by_*` tools.
34
34
  - Kuaishou / 快手 creator works through the `kuaishou_get_user_posted_videos_by_*` tools.
35
35
  - Weibo / 微博 creator posts through the `weibo_get_user_posts_by_*` tools.
36
- - WeChat Channels / 视频号 creator videos through the `wechat_get_user_posted_videos_by_*` tools.
36
+ - WeChat Channels / 视频号 creator videos through the `wechat_get_user_posted_videos_by_*` tools; the user_id entrypoint requires a `v2_...@finder` user_id.
37
37
 
38
38
  ## API Key
39
39
 
@@ -111,11 +111,11 @@ npx -y socialdatax-skills@latest weibo user-posts \
111
111
  --source-skill media-user-posts
112
112
 
113
113
  npx -y socialdatax-skills@latest wechat user-posts \
114
- --user-id "<finder_user_id>" --pretty --source-client socialdatax-skills \
114
+ --user-id "<v2_finder_user_id>" --pretty --source-client socialdatax-skills \
115
115
  --source-platform npm --source-skill media-user-posts
116
116
 
117
117
  npx -y socialdatax-skills@latest wechat user-posts \
118
- --user-id "<finder_user_id>" --all --pretty --source-client socialdatax-skills \
118
+ --user-id "<v2_finder_user_id>" --all --pretty --source-client socialdatax-skills \
119
119
  --source-platform npm --source-skill media-user-posts
120
120
 
121
121
  npx -y socialdatax-skills@latest wechat user-posts \
@@ -140,7 +140,7 @@ Optional arguments:
140
140
  - Kuaishou `--profile-url <profile_url_or_share_text>`: use only for a profile URL, short link, or profile share text that resolves directly to a non-empty user_id. For live/fw-user profile shares, call Kuaishou creator profile first and use the returned non-empty user_id.
141
141
  - Weibo `--user-id <user_id>`: preferred when the creator user_id is already known.
142
142
  - Weibo `--profile-url <profile_url_or_share_text>`: use for a profile URL, short link, or profile share text.
143
- - WeChat Channels / 视频号 `--user-id <finder_user_id>`: preferred when the creator user_id ending with `@finder` is already known.
143
+ - WeChat Channels / 视频号 `--user-id <v2_finder_user_id>`: preferred when the creator `v2_...@finder` user_id is already known.
144
144
  - WeChat Channels / 视频号 `--url <wechat_video_url_or_share_text>`: use a video link or share text to resolve the author and list that creator's videos.
145
145
  - `--source-client socialdatax-skills --source-platform npm --source-skill media-user-posts`: usage attribution for this Agent Skill; keep these values unchanged when running examples from this Skill.
146
146
 
@@ -185,7 +185,7 @@ Kuaishou creator work pagination uses opaque `page_token` values; pass the compl
185
185
  - `weibo_get_user_posts_by_user_id`: preferred when `user_id` is already known.
186
186
  - `weibo_get_user_posts_by_profile_url`: use for profile URLs, short links, or profile share text.
187
187
  Weibo creator post pagination uses opaque `page_token` values; pass the complete returned `next_page_token` back unchanged for the same user. Do not modify, truncate, redact, mask, omit, normalize, rebuild, generate, or replace the middle with ellipses.
188
- - `wechat_get_user_posted_videos_by_user_id`: preferred when the WeChat Channels / 视频号 `@finder` user_id is already known.
188
+ - `wechat_get_user_posted_videos_by_user_id`: preferred when the WeChat Channels / 视频号 `v2_...@finder` user_id is already known.
189
189
  - `wechat_get_user_posted_videos_by_url`: use a WeChat Channels / 视频号 video link or share text to resolve the author and list that creator's videos.
190
190
  WeChat Channels / 视频号 creator video pagination uses opaque `page_token` values; pass the complete returned `next_page_token` back unchanged for the same user. Do not modify, truncate, redact, mask, omit, normalize, rebuild, generate, or replace the middle with ellipses.
191
191
  `--since-days` uses CLI-side filtering only and is not an MCP tool argument; for MCP-only calls, continue pages as needed and filter returned `publish_time` values in your analysis.
@@ -54,13 +54,13 @@ Current platform support:
54
54
  - Kuaishou / 快手 creators through the `kuaishou_get_user_info_by_*` tools.
55
55
  - Kuaishou / 快手 creator discovery through `kuaishou_search_users` before profile lookup when only an account keyword or niche is known.
56
56
  - Weibo / 微博 creators through the `weibo_get_user_info_by_*` tools.
57
- - WeChat Channels / 视频号 creators through `wechat_get_user_info_by_user_id`.
57
+ - WeChat Channels / 视频号 creators through `wechat_get_user_info_by_user_id` when a `v2_...@finder` user_id is already known.
58
58
  - Xiaohongshu / XHS / RedNote creator notes through the `xhs_get_user_posted_notes_by_*` tools.
59
59
  - Douyin / 抖音 creator works, including video and image/text posts, through the `douyin_get_user_posted_videos_by_*` tools.
60
60
  - Douyin / 抖音 creator short-drama series through the `douyin_get_user_series_by_*` tools.
61
61
  - Kuaishou / 快手 creator works through the `kuaishou_get_user_posted_videos_by_*` tools.
62
62
  - Weibo / 微博 creator posts through the `weibo_get_user_posts_by_*` tools.
63
- - WeChat Channels / 视频号 creator videos through the `wechat_get_user_posted_videos_by_*` tools.
63
+ - WeChat Channels / 视频号 creator videos through the `wechat_get_user_posted_videos_by_*` tools; the user_id entrypoint requires a `v2_...@finder` user_id.
64
64
 
65
65
  ## API Key
66
66
 
@@ -252,15 +252,15 @@ npx -y socialdatax-skills@latest wechat comments \
252
252
  --source-skill socialdatax-content-research-assistant
253
253
 
254
254
  npx -y socialdatax-skills@latest wechat user-info \
255
- --user-id "<finder_user_id>" --pretty --source-client socialdatax-skills \
255
+ --user-id "<v2_finder_user_id>" --pretty --source-client socialdatax-skills \
256
256
  --source-platform npm --source-skill socialdatax-content-research-assistant
257
257
 
258
258
  npx -y socialdatax-skills@latest wechat user-posts \
259
- --user-id "<finder_user_id>" --pretty --source-client socialdatax-skills \
259
+ --user-id "<v2_finder_user_id>" --pretty --source-client socialdatax-skills \
260
260
  --source-platform npm --source-skill socialdatax-content-research-assistant
261
261
 
262
262
  npx -y socialdatax-skills@latest wechat user-posts \
263
- --user-id "<finder_user_id>" --all --pretty --source-client socialdatax-skills \
263
+ --user-id "<v2_finder_user_id>" --all --pretty --source-client socialdatax-skills \
264
264
  --source-platform npm --source-skill socialdatax-content-research-assistant
265
265
  ```
266
266