socialdatax-skills 0.2.35 → 0.2.36

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  This public package provides the unified skill installer and direct CLI helper for SocialDataX services.
4
4
 
5
- The current public tools support 小红书 / Xiaohongshu / XHS / RedNote, 抖音 / Douyin, 快手 / Kuaishou / Kwai, Bilibili / 哔哩哔哩 / B站, 微博 / Weibo, 视频号 / WeChat Channels, 知乎 / Zhihu, Instagram, X / Twitter, YouTube, and TikTok content research and analysis workflows, plus WeChat Official Account / 微信公众号 article details, XHS / Douyin / Kuaishou / Weibo local media download, WeChat Channels local media decrypt/save, Bilibili local video download, and 敏感词检测 / 违禁词检查 text checks. The public skill layer is intentionally named by capability so supported services can evolve without changing the installation model.
5
+ The current public tools support 小红书 / Xiaohongshu / XHS / RedNote, 抖音 / Douyin, 快手 / Kuaishou / Kwai, Bilibili / 哔哩哔哩 / B站, 微博 / Weibo, 视频号 / WeChat Channels, 知乎 / Zhihu, Instagram, X / Twitter, YouTube, and TikTok content research and analysis workflows, plus WeChat Official Account / 微信公众号 article details, XHS / Douyin / Kuaishou / Weibo / X / Twitter local media download, WeChat Channels local media decrypt/save, Bilibili local video download, and 敏感词检测 / 违禁词检查 text checks. The public skill layer is intentionally named by capability so supported services can evolve without changing the installation model.
6
6
 
7
7
  - direct `npx` JSON commands for agents that can run shell commands
8
8
  - AgentSkills-compatible installers split by capability for OpenClaw, Hermes Agent, Codex, Claude Code, and general agent skill directories
@@ -89,7 +89,7 @@ Common search phrases for this skill package:
89
89
  - Reserved future SocialDataX namespace names for existing platform listings without draft files yet: `com.socialdatax/kuaishou-insights`, `com.socialdatax/weibo-insights`, `com.socialdatax/wechat-channels-insights`, and `com.socialdatax/instagram-insights`.
90
90
  - Hosted endpoints without repo-tracked standalone listing materials yet: Bilibili, Zhihu, X / Twitter, YouTube, TikTok, and Sensitive Words Check.
91
91
  - Unified MCP registry name: none; this package installs skills and calls explicit hosted MCP entries.
92
- - Current public capability version: `0.2.35`
92
+ - Current public capability version: `0.2.36`
93
93
 
94
94
  ## Direct CLI
95
95
 
@@ -226,6 +226,7 @@ npx -y socialdatax-skills@latest x user-info --profile-url "<profile_url_or_shar
226
226
  npx -y socialdatax-skills@latest x user-posts --user-id "<user_id>" --pretty
227
227
  npx -y socialdatax-skills@latest x user-posts --username "<username>" --pretty
228
228
  npx -y socialdatax-skills@latest x user-posts --profile-url "<profile_url_or_share_text>" --pretty
229
+ npx -y socialdatax-skills@latest x download-media --url "<x_media_url>" --output-dir ./downloads --pretty
229
230
  npx -y socialdatax-skills@latest youtube search --keyword "camping" --pretty
230
231
  npx -y socialdatax-skills@latest youtube detail --url "<youtube_video_url>" --pretty
231
232
  npx -y socialdatax-skills@latest youtube comments --url "<youtube_video_url>" --pretty
@@ -244,7 +245,7 @@ npx -y socialdatax-skills@latest tiktok user-posts --profile-url "<profile_url_o
244
245
  npx -y socialdatax-skills@latest sensitive-check text --text "<content>" --platform xhs --pretty
245
246
  ```
246
247
 
247
- 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.
248
+ 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>`. `x download-media` accepts one X media URL returned by search or detail. These local commands write through a `.part` file, resume partial downloads when the server supports range requests, skip an already existing output file, and infer common image/video/audio extensions in `--output-dir` mode. X / Twitter media URLs are served from overseas CDN domains such as `pbs.twimg.com` and `video.twimg.com`; if the local download times out, enable a global/TUN/VPN proxy for the download process, then retry.
248
249
 
249
250
  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.
250
251
 
@@ -428,6 +429,7 @@ npx -y socialdatax-skills@latest wechat transcript --encrypted-object-id "<encry
428
429
  npx -y socialdatax-skills@latest zhihu search --keyword "露营" --pretty
429
430
  npx -y socialdatax-skills@latest instagram search --keyword "camping" --pretty
430
431
  npx -y socialdatax-skills@latest x search --keyword "camping" --pretty
432
+ npx -y socialdatax-skills@latest x download-media --url "<x_media_url>" --output-dir ./downloads --pretty
431
433
  npx -y socialdatax-skills@latest youtube search --keyword "camping" --pretty
432
434
  npx -y socialdatax-skills@latest tiktok search --keyword "camping" --pretty
433
435
  npx -y socialdatax-skills@latest sensitive-check text --text "<content>" --platform xhs --pretty
@@ -570,6 +572,7 @@ Current X / Twitter workflows include:
570
572
  - Fetch paginated replies under a first-level comment by post_id and comment_id.
571
573
  - Read creator profile data by user_id, username, or profile URL/share text.
572
574
  - Fetch paginated public posts by creator user_id, username, or profile URL/share text.
575
+ - Save returned `media_items[].cover_image_url` or `media_items[].video_url` media links locally with `x download-media`. Search results may already include these URLs; use detail as a fallback when search media fields are absent. If X CDN downloads time out, enable a global/TUN/VPN proxy for the download process and retry.
573
576
 
574
577
  Current YouTube workflows include:
575
578
 
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.35";
25
+ const PACKAGE_VERSION = "0.2.36";
26
26
  const PACKAGE_SPEC = `${PACKAGE_NAME}@latest`;
27
27
  const LOG_PREFIX = `[${PACKAGE_NAME}]`;
28
28
  const MIN_NODE_VERSION = "20.18.1";
@@ -578,6 +578,7 @@ const X_DIRECT_ACTION_OPTIONS = {
578
578
  "maxItems",
579
579
  "pretty",
580
580
  ],
581
+ "download-media": ["url", "output", "outputDir", "pretty"],
581
582
  };
582
583
  const X_DIRECT_ACTION_NAMES = Object.keys(X_DIRECT_ACTION_OPTIONS).join(", ");
583
584
  const X_OPTION_DISPLAY_NAMES = {
@@ -593,6 +594,9 @@ const X_OPTION_DISPLAY_NAMES = {
593
594
  userId: "--user-id",
594
595
  username: "--username",
595
596
  profileUrl: "--profile-url",
597
+ url: "--url",
598
+ output: "--output",
599
+ outputDir: "--output-dir",
596
600
  };
597
601
  const X_SEARCH_SORT_TYPES = ["hot", "time_descending"];
598
602
  const YOUTUBE_DIRECT_ACTION_OPTIONS = {
@@ -2072,6 +2076,21 @@ function validateInstagramDirectActionOptions(action, options) {
2072
2076
  }
2073
2077
 
2074
2078
  function validateXDirectActionOptions(action, options) {
2079
+ const allowedOptions = X_DIRECT_ACTION_OPTIONS[action];
2080
+ if (!allowedOptions) {
2081
+ return;
2082
+ }
2083
+
2084
+ if (action === "download-media") {
2085
+ validateDownloadMediaDirectActionOptions(
2086
+ "x",
2087
+ options,
2088
+ allowedOptions,
2089
+ X_OPTION_DISPLAY_NAMES
2090
+ );
2091
+ return;
2092
+ }
2093
+
2075
2094
  validateMcpDirectActionOptions(
2076
2095
  "x",
2077
2096
  action,
@@ -3023,6 +3042,9 @@ function printHelp() {
3023
3042
  console.log(` npx -y ${PACKAGE_SPEC} x user-posts --username "<username>" --pretty`);
3024
3043
  console.log(" Call the X creator posts tool by username.");
3025
3044
  console.log("");
3045
+ console.log(` npx -y ${PACKAGE_SPEC} x download-media --url "<x_media_url>" --output-dir ./downloads --pretty`);
3046
+ console.log(" Save one X image or video media URL returned by search or detail to a local file.");
3047
+ console.log("");
3026
3048
  console.log(` npx -y ${PACKAGE_SPEC} youtube search --keyword "camping" --pretty`);
3027
3049
  console.log(" Call the YouTube public video search tool directly and print JSON.");
3028
3050
  console.log("");
@@ -3130,6 +3152,7 @@ function printHelp() {
3130
3152
  console.log(" --url <url-or-share-text>");
3131
3153
  console.log(" Content link, short link, or share text for URL-based detail/comment/article commands.");
3132
3154
  console.log(" For xhs/douyin/kuaishou/weibo download-media, pass one media URL returned by detail.");
3155
+ console.log(" For x download-media, pass one media URL returned by search or detail.");
3133
3156
  console.log(" For Douyin detail/comments, pass a content page link, not video.play_url.");
3134
3157
  console.log(" --media-url <video.video_url>");
3135
3158
  console.log(" WeChat detail result media URL for local decrypt-media download.");
@@ -3644,12 +3667,37 @@ async function runInstagramDirectCommand(args) {
3644
3667
  }
3645
3668
 
3646
3669
  async function runXDirectCommand(args) {
3647
- await runMcpDirectCommand(args, {
3648
- displayName: "X",
3649
- actionNames: X_DIRECT_ACTION_NAMES,
3650
- validateActionOptions: validateXDirectActionOptions,
3651
- buildOperation: buildXOperation,
3652
- });
3670
+ const { options, positional } = parseCommandArgs(args);
3671
+ if (shouldPrintDirectHelp(options, positional)) {
3672
+ printHelp();
3673
+ return;
3674
+ }
3675
+ const action = positional[0];
3676
+ if (!action) {
3677
+ throw new Error(`Missing X command. Use ${X_DIRECT_ACTION_NAMES}.`);
3678
+ }
3679
+ if (positional.length > 1) {
3680
+ throw new Error(`Unexpected argument: ${positional[1]}`);
3681
+ }
3682
+ validateXDirectActionOptions(action, options);
3683
+
3684
+ if (action === "download-media") {
3685
+ const data = await downloadPlatformMediaFromUrl("x", options.url, options);
3686
+ process.stdout.write(JSON.stringify(data, null, options.pretty ? 2 : 0));
3687
+ process.stdout.write("\n");
3688
+ return;
3689
+ }
3690
+
3691
+ const operation = attachDirectMetadata(buildXOperation(action, options), options);
3692
+ const data = await callDirectOperationWithOptions(operation, options);
3693
+ const envelope = {
3694
+ platform: operation.platform.id,
3695
+ tool: operation.tool,
3696
+ arguments: operation.arguments,
3697
+ data,
3698
+ };
3699
+ process.stdout.write(JSON.stringify(envelope, null, options.pretty ? 2 : 0));
3700
+ process.stdout.write("\n");
3653
3701
  }
3654
3702
 
3655
3703
  async function runYoutubeDirectCommand(args) {
@@ -43,6 +43,11 @@ const PLATFORM_MEDIA_DOWNLOAD_CONFIGS = {
43
43
  displayName: "Weibo",
44
44
  referer: "https://weibo.com/",
45
45
  },
46
+ x: {
47
+ platform: "x",
48
+ displayName: "X / Twitter",
49
+ referer: "https://x.com/",
50
+ },
46
51
  };
47
52
  const MEDIA_DOWNLOAD_MAX_ATTEMPTS = 10;
48
53
  const MEDIA_DOWNLOAD_RETRY_DELAY_MS = 250;
@@ -221,7 +226,10 @@ async function downloadWithPartResume(
221
226
  }
222
227
 
223
228
  if (isAbortLikeError(lastError)) {
224
- throw new Error(`${config.displayName} media download timed out.`);
229
+ throw new Error(formatPlatformMediaTimeoutMessage(config));
230
+ }
231
+ if (isNetworkLikeError(lastError)) {
232
+ throw new Error(formatPlatformMediaNetworkFailureMessage(config));
225
233
  }
226
234
  throw new Error(`${config.displayName} media download failed before completion.`);
227
235
  }
@@ -658,6 +666,28 @@ function isNetworkLikeError(error) {
658
666
  );
659
667
  }
660
668
 
669
+ function formatPlatformMediaTimeoutMessage(config) {
670
+ if (config.platform === "x") {
671
+ return [
672
+ "X / Twitter media download timed out.",
673
+ "X media is served from overseas CDN domains such as pbs.twimg.com and video.twimg.com;",
674
+ "enable a global/TUN/VPN proxy for the download process, then retry.",
675
+ ].join(" ");
676
+ }
677
+ return `${config.displayName} media download timed out.`;
678
+ }
679
+
680
+ function formatPlatformMediaNetworkFailureMessage(config) {
681
+ if (config.platform === "x") {
682
+ return [
683
+ "X / Twitter media download could not reach the media CDN.",
684
+ "X media is served from overseas CDN domains such as pbs.twimg.com and video.twimg.com;",
685
+ "enable a global/TUN/VPN proxy for the download process, then retry.",
686
+ ].join(" ");
687
+ }
688
+ return `${config.displayName} media download failed before completion.`;
689
+ }
690
+
661
691
  function isDownloadTooLargeError(error) {
662
692
  return error?.message === "Media download is too large for local media processing.";
663
693
  }
@@ -704,10 +734,14 @@ function inferUrlFormatExtension(parsedUrl) {
704
734
  const matched = /(?:^|[/?&])format\/([a-z0-9]+)(?:[/?&#]|$)/i.exec(
705
735
  `${parsedUrl.pathname}${parsedUrl.search}`
706
736
  );
707
- if (!matched) {
708
- return "";
737
+ if (matched) {
738
+ return MEDIA_URL_FORMAT_EXTENSIONS.get(sanitizeFileExtension(matched[1])) || "";
709
739
  }
710
- return MEDIA_URL_FORMAT_EXTENSIONS.get(sanitizeFileExtension(matched[1])) || "";
740
+ return (
741
+ MEDIA_URL_FORMAT_EXTENSIONS.get(
742
+ sanitizeFileExtension(parsedUrl.searchParams.get("format"))
743
+ ) || ""
744
+ );
711
745
  }
712
746
 
713
747
  function isExistingOutputPathError(error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socialdatax-skills",
3
- "version": "0.2.35",
3
+ "version": "0.2.36",
4
4
  "description": "SocialDataX / 社媒数据助手 skill installer and direct CLI helper for hosted MCP services.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -163,7 +163,7 @@ The command prints JSON with `platform`, `tool`, `arguments`, and `data`.
163
163
 
164
164
  ## Safety Boundary
165
165
 
166
- Platform detail access is read-only. It uses `SOCIALDATAX_API_KEY` from the user's environment at runtime for SocialDataX detail requests. Generated Skill files do not contain API keys. It does not read local browser data or perform login, posting, liking, commenting, or account changes. The optional XHS, Douyin, Kuaishou, and Weibo local save commands write only to the requested local `--output` path or `--output-dir` directory and do not require `SOCIALDATAX_API_KEY`. The optional WeChat Channels / 视频号 local save command writes only to the user-provided `--output` file, decrypts when needed, and does not require `SOCIALDATAX_API_KEY`. Prefer the direct CLI; hosted MCP tools are optional when the current agent already supports authenticated streamable HTTP MCP.
166
+ Platform detail access is read-only. It uses `SOCIALDATAX_API_KEY` from the user's environment at runtime for SocialDataX detail requests. Generated Skill files do not contain API keys. It does not read local browser data or perform login, posting, liking, commenting, or account changes. The optional XHS, Douyin, Kuaishou, Weibo, and X / Twitter local save commands write only to the requested local `--output` path or `--output-dir` directory and do not require `SOCIALDATAX_API_KEY`. The optional WeChat Channels / 视频号 local save command writes only to the user-provided `--output` file, decrypts when needed, and does not require `SOCIALDATAX_API_KEY`. Prefer the direct CLI; hosted MCP tools are optional when the current agent already supports authenticated streamable HTTP MCP.
167
167
 
168
168
  ## MCP Tools
169
169
 
@@ -224,6 +224,8 @@ When the user wants to save Douyin media after detail, pass each returned `image
224
224
  When the user wants to save Kuaishou media after detail, pass each returned `images[].url`, `video.play_url`, or `cover_image_url` to `npx -y socialdatax-skills@latest kuaishou download-media --url "<media_url>" --output-dir <directory> --pretty`; this local save command does not require `SOCIALDATAX_API_KEY`.
225
225
  For Bilibili detail, preserve returned content IDs and URLs because comments, replies, and article/dynamic reactions may need them.
226
226
  For Zhihu, Instagram, X / Twitter, YouTube, and TikTok detail results, keep the returned URL and public content ID values exactly as returned for follow-up comments or creator lookups.
227
+ When the user wants to save X / Twitter media after search or detail, pass each returned `media_items[].cover_image_url` or `media_items[].video_url` to `npx -y socialdatax-skills@latest x download-media --url "<media_url>" --output-dir <directory> --pretty`; this local save command does not require `SOCIALDATAX_API_KEY`. Search results may already include these media URLs; use detail as a fallback when search media fields are absent.
228
+ If an X / Twitter local media download times out, explain that X media is served from overseas CDN domains such as `pbs.twimg.com` and `video.twimg.com`; ask the user to enable a global/TUN/VPN proxy for the download process, then retry the same `x download-media` command.
227
229
  Detail access is read-only and does not provide account actions.
228
230
  For Weibo detail, include `post_id`, content, author, media, interaction counts, publish time, and post URL when available.
229
231
  When the user wants to save Weibo media after detail, pass each returned `image_urls[]` or `video.video_url` to `npx -y socialdatax-skills@latest weibo download-media --url "<media_url>" --output-dir <directory> --pretty`; this local save command does not require `SOCIALDATAX_API_KEY`.
@@ -272,7 +272,7 @@ Weibo and WeChat Channels search pagination:
272
272
 
273
273
  ## Safety Boundary
274
274
 
275
- This skill is read-only. It uses `SOCIALDATAX_API_KEY` from the user's environment at runtime. Generated Skill files do not contain API keys. It does not read local browser data or perform login, posting, liking, commenting, or account changes. Prefer the direct CLI; hosted MCP tools are optional when the current agent already supports authenticated streamable HTTP MCP.
275
+ Search access is read-only. It uses `SOCIALDATAX_API_KEY` from the user's environment at runtime for SocialDataX search requests. Generated Skill files do not contain API keys. It does not read local browser data or perform login, posting, liking, commenting, or account changes. The optional X / Twitter local save command writes only to the requested local `--output` path or `--output-dir` directory and does not require `SOCIALDATAX_API_KEY`. Prefer the direct CLI; hosted MCP tools are optional when the current agent already supports authenticated streamable HTTP MCP.
276
276
 
277
277
  ## MCP Tools
278
278
 
@@ -351,6 +351,7 @@ For Kuaishou search results, include `photo_id`, `share_url`, author facts, and
351
351
  For Bilibili search results, include content IDs, URLs, titles or descriptions, creator facts, and visible interaction counts when the user needs traceability.
352
352
  For Zhihu search results, include content URLs, titles or summaries, creator facts, and visible interaction counts when the user needs traceability.
353
353
  For Instagram, X / Twitter, YouTube, and TikTok search results, include returned post or video URLs, public IDs, author facts, and visible interaction counts when the user needs traceability.
354
+ For X / Twitter search results, preserve returned `media_items[].cover_image_url` and `media_items[].video_url` values when present. When the user wants to save X media, pass one returned media URL at a time to `npx -y socialdatax-skills@latest x download-media --url "<media_url>" --output-dir <directory> --pretty`; this local save command does not require `SOCIALDATAX_API_KEY`. If search media fields are absent, use X detail as the fallback before downloading.
354
355
  For Weibo search results, include `post_id`, `post_url`, author facts, interaction counts, and publish time when the user needs traceability.
355
356
  For WeChat Channels / 视频号 search results, include `encrypted_object_id`, author facts, interaction counts, publish time, and duration when the user needs traceability.
356
357