@gecho-ai/gecho-bridge 1.1.37 → 1.1.38-beta.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.
Files changed (99) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/README.md +50 -6
  3. package/README.zh.md +55 -6
  4. package/action-result.js +53 -0
  5. package/dist/mcp-client.cjs +139 -12
  6. package/dist/server.cjs +136 -23
  7. package/distribution-skills/amazon/publish.json +11 -0
  8. package/distribution-skills/amazon-product/publish.json +11 -0
  9. package/distribution-skills/amazon-reviews/publish.json +11 -0
  10. package/distribution-skills/amazon-search/publish.json +11 -0
  11. package/distribution-skills/facebook-reels-search/SKILL.md +289 -0
  12. package/distribution-skills/facebook-reels-search/_meta.json +5 -0
  13. package/distribution-skills/facebook-reels-search/publish.json +31 -0
  14. package/distribution-skills/tiktok-influencer/publish.json +11 -0
  15. package/distribution-skills/tiktok-insight/publish.json +11 -0
  16. package/distribution-skills/tiktok-product/publish.json +11 -0
  17. package/distribution-skills/tiktok-search/publish.json +11 -0
  18. package/distribution-skills/tiktok-shop/publish.json +11 -0
  19. package/distribution-skills/tiktok-shop-search/publish.json +11 -0
  20. package/distribution-skills/tiktok-video/publish.json +11 -0
  21. package/distribution-skills/tiktok-video-search/publish.json +11 -0
  22. package/distribution-skills/x/publish.json +11 -0
  23. package/distribution-skills/x-post-detail/publish.json +11 -0
  24. package/distribution-skills/x-search/publish.json +11 -0
  25. package/distribution-skills/youtube-shorts-search/SKILL.md +289 -0
  26. package/distribution-skills/youtube-shorts-search/_meta.json +5 -0
  27. package/distribution-skills/youtube-shorts-search/publish.json +31 -0
  28. package/distribution-skills-zh-CN/amazon/SKILL.md +398 -0
  29. package/distribution-skills-zh-CN/amazon/_meta.json +5 -0
  30. package/distribution-skills-zh-CN/amazon/publish.json +31 -0
  31. package/distribution-skills-zh-CN/amazon/skillhub-publish.json +1 -0
  32. package/distribution-skills-zh-CN/amazon-product/SKILL.md +299 -0
  33. package/distribution-skills-zh-CN/amazon-product/_meta.json +5 -0
  34. package/distribution-skills-zh-CN/amazon-product/publish.json +31 -0
  35. package/distribution-skills-zh-CN/amazon-product/skillhub-publish.json +1 -0
  36. package/distribution-skills-zh-CN/amazon-reviews/SKILL.md +300 -0
  37. package/distribution-skills-zh-CN/amazon-reviews/_meta.json +5 -0
  38. package/distribution-skills-zh-CN/amazon-reviews/publish.json +31 -0
  39. package/distribution-skills-zh-CN/amazon-reviews/skillhub-publish.json +1 -0
  40. package/distribution-skills-zh-CN/amazon-search/SKILL.md +300 -0
  41. package/distribution-skills-zh-CN/amazon-search/_meta.json +5 -0
  42. package/distribution-skills-zh-CN/amazon-search/publish.json +31 -0
  43. package/distribution-skills-zh-CN/amazon-search/skillhub-publish.json +1 -0
  44. package/distribution-skills-zh-CN/facebook-reels-search/SKILL.md +289 -0
  45. package/distribution-skills-zh-CN/facebook-reels-search/_meta.json +5 -0
  46. package/distribution-skills-zh-CN/facebook-reels-search/publish.json +31 -0
  47. package/distribution-skills-zh-CN/facebook-reels-search/skillhub-publish.json +1 -0
  48. package/distribution-skills-zh-CN/tiktok-influencer/SKILL.md +308 -0
  49. package/distribution-skills-zh-CN/tiktok-influencer/_meta.json +5 -0
  50. package/distribution-skills-zh-CN/tiktok-influencer/publish.json +31 -0
  51. package/distribution-skills-zh-CN/tiktok-influencer/skillhub-publish.json +1 -0
  52. package/distribution-skills-zh-CN/tiktok-insight/SKILL.md +362 -0
  53. package/distribution-skills-zh-CN/tiktok-insight/_meta.json +5 -0
  54. package/distribution-skills-zh-CN/tiktok-insight/publish.json +31 -0
  55. package/distribution-skills-zh-CN/tiktok-insight/skillhub-publish.json +6 -0
  56. package/distribution-skills-zh-CN/tiktok-product/SKILL.md +298 -0
  57. package/distribution-skills-zh-CN/tiktok-product/_meta.json +5 -0
  58. package/distribution-skills-zh-CN/tiktok-product/publish.json +31 -0
  59. package/distribution-skills-zh-CN/tiktok-product/skillhub-publish.json +1 -0
  60. package/distribution-skills-zh-CN/tiktok-search/SKILL.md +470 -0
  61. package/distribution-skills-zh-CN/tiktok-search/_meta.json +5 -0
  62. package/distribution-skills-zh-CN/tiktok-search/publish.json +31 -0
  63. package/distribution-skills-zh-CN/tiktok-search/skillhub-publish.json +1 -0
  64. package/distribution-skills-zh-CN/tiktok-shop/SKILL.md +359 -0
  65. package/distribution-skills-zh-CN/tiktok-shop/_meta.json +5 -0
  66. package/distribution-skills-zh-CN/tiktok-shop/publish.json +31 -0
  67. package/distribution-skills-zh-CN/tiktok-shop/skillhub-publish.json +1 -0
  68. package/distribution-skills-zh-CN/tiktok-shop-search/SKILL.md +299 -0
  69. package/distribution-skills-zh-CN/tiktok-shop-search/_meta.json +5 -0
  70. package/distribution-skills-zh-CN/tiktok-shop-search/publish.json +31 -0
  71. package/distribution-skills-zh-CN/tiktok-shop-search/skillhub-publish.json +1 -0
  72. package/distribution-skills-zh-CN/tiktok-video/SKILL.md +380 -0
  73. package/distribution-skills-zh-CN/tiktok-video/_meta.json +5 -0
  74. package/distribution-skills-zh-CN/tiktok-video/publish.json +31 -0
  75. package/distribution-skills-zh-CN/tiktok-video/skillhub-publish.json +1 -0
  76. package/distribution-skills-zh-CN/tiktok-video-search/SKILL.md +306 -0
  77. package/distribution-skills-zh-CN/tiktok-video-search/_meta.json +5 -0
  78. package/distribution-skills-zh-CN/tiktok-video-search/publish.json +31 -0
  79. package/distribution-skills-zh-CN/tiktok-video-search/skillhub-publish.json +1 -0
  80. package/distribution-skills-zh-CN/x/SKILL.md +360 -0
  81. package/distribution-skills-zh-CN/x/_meta.json +5 -0
  82. package/distribution-skills-zh-CN/x/publish.json +31 -0
  83. package/distribution-skills-zh-CN/x/skillhub-publish.json +1 -0
  84. package/distribution-skills-zh-CN/x-post-detail/SKILL.md +299 -0
  85. package/distribution-skills-zh-CN/x-post-detail/_meta.json +5 -0
  86. package/distribution-skills-zh-CN/x-post-detail/publish.json +31 -0
  87. package/distribution-skills-zh-CN/x-post-detail/skillhub-publish.json +1 -0
  88. package/distribution-skills-zh-CN/x-search/SKILL.md +299 -0
  89. package/distribution-skills-zh-CN/x-search/_meta.json +5 -0
  90. package/distribution-skills-zh-CN/x-search/publish.json +31 -0
  91. package/distribution-skills-zh-CN/x-search/skillhub-publish.json +1 -0
  92. package/distribution-skills-zh-CN/youtube-shorts-search/SKILL.md +289 -0
  93. package/distribution-skills-zh-CN/youtube-shorts-search/_meta.json +5 -0
  94. package/distribution-skills-zh-CN/youtube-shorts-search/publish.json +31 -0
  95. package/distribution-skills-zh-CN/youtube-shorts-search/skillhub-publish.json +1 -0
  96. package/mcp-client.js +79 -7
  97. package/openclaw.plugin.json +2 -2
  98. package/package.json +17 -4
  99. package/server.js +73 -19
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@gecho-ai/gecho-bridge",
3
- "version": "1.1.37",
4
- "description": "TikTok Search Tool for OpenClaw"
3
+ "version": "1.1.38-beta.0",
4
+ "description": "Browser research tools for OpenClaw via the Gecho Chrome Extension"
5
5
  }
package/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # Gecho Bridge 🚀
2
2
 
3
- **Gecho Bridge connects AI clients such as OpenClaw, Hermes, Trae, and Claude Code to a live Chrome browser through MCP and the Gecho Chrome extension.** Use it to search TikTok videos, collect structured metadata, save JSON results, and run async product, trend, competitor, and content insight workflows.
3
+ **Gecho Bridge connects AI clients such as OpenClaw, Hermes, Trae, and Claude Code to a live Chrome browser through MCP and the Gecho Chrome extension.** Use it to search TikTok videos, YouTube Shorts, Facebook Reels, X posts, and Amazon products, collect structured metadata, save JSON results, and run async product, trend, competitor, and content insight workflows.
4
4
 
5
5
  ## ⚠️ Critical Prerequisite: Read Before Use
6
6
 
7
- Gecho Bridge cannot work from the README, Skill page, or MCP config alone. Before the first TikTok search or insight job, all 3 items below are required:
7
+ Gecho Bridge cannot work from the README, Skill page, or MCP config alone. Before the first platform search or insight job, all 3 items below are required:
8
8
 
9
9
  1. **Configure Gecho Bridge MCP** in your AI client.
10
10
  2. **Install the Gecho Chrome extension** and log in to your Gecho account.
11
- 3. **Log in to TikTok web in Chrome** and keep the logged-in TikTok tab open.
11
+ 3. **Log in to the target platform in Chrome** and keep the logged-in platform tab open.
12
12
 
13
- If any of these are missing, TikTok search and insight tools may fail even if the Skill or plugin is installed.
13
+ If any of these are missing, the selected platform tool may fail even if the Skill or plugin is installed.
14
14
 
15
15
  ## 🚀 3-Step Quick Start
16
16
 
@@ -125,6 +125,49 @@ A new team Skill also requires at least one team category ID. For an existing Sk
125
125
 
126
126
  Official documentation: [CLI installation](https://skillhub.cn/install/skillhub.md), [community publishing](https://skillhub.cn/ai/release.md), [enterprise publishing](https://skillhub.cn/enterprise/dashboard/publish), and [enterprise API keys](https://skillhub.cn/enterprise/dashboard/keys).
127
127
 
128
+ ### WorkBuddy Skill Packaging
129
+
130
+ WorkBuddy uses a separate Skill package format, so a Tencent SkillHub staging copy must not be uploaded directly.
131
+ The repository creates Git-ignored copies under `tmp/workbuddy-publish/`, adds
132
+ `display_name`, `display_name_en`, `description_zh`, `description_en`, `version`, and `author`, and packages
133
+ each Skill using WorkBuddy's official `skills/<skill-name>/SKILL.md` layout.
134
+
135
+ ```bash
136
+ # Create WorkBuddy-only staging copies
137
+ npm run skillhub:workbuddy:stage
138
+
139
+ # Build all English and Chinese ZIPs and validate their structure
140
+ npm run skillhub:workbuddy:dry-run
141
+
142
+ # Prepare one Chinese Skill
143
+ npm run skillhub:workbuddy:dry-run -- \
144
+ --skill tiktok-video-search --locale zh-CN
145
+ ```
146
+
147
+ ZIP files are written to `tmp/workbuddy-publish/archives/` (each must be no larger than 3MB) for manual upload to the
148
+ [WorkBuddy Open Platform](https://open.workbuddy.cn/). The script has no login or submit command and never uses
149
+ Tencent SkillHub `skh_...` or `sk-ent-...` credentials. See the official [WorkBuddy Skill documentation](https://open.workbuddy.cn/docs/skill).
150
+
151
+ ### WorkBuddy Open Platform Connector
152
+
153
+ WorkBuddy's open platform Connector publication is separate from Skill publication. The Connector ZIP contains the
154
+ platform metadata and the MCP startup configuration; it is not one of the Skill ZIPs above.
155
+
156
+ ```bash
157
+ # Build and validate the Connector ZIP for the current package version
158
+ npm run skillhub:workbuddy:connector:dry-run
159
+ ```
160
+
161
+ The uploadable file is generated at:
162
+
163
+ ```text
164
+ tmp/workbuddy-connector/gecho-bridge-workbuddy-v1.1.37.zip
165
+ ```
166
+
167
+ It uses the public `@gecho-ai/gecho-bridge@1.1.37` npm package as a local Stdio MCP server. The generated ZIP contains
168
+ `connector-meta.json`, `mcp.json`, `icon.svg`, and a concise Connector Skill. It is only staged locally; this command
169
+ does not upload or submit a review request. See the official [WorkBuddy Connector documentation](https://open.workbuddy.cn/docs/connector).
170
+
128
171
  ### Option 2: One-Click Setup in Hermes (Hermes Skill Hub)
129
172
  You can quickly add the service to Hermes and restart it with the following commands:
130
173
  ```bash
@@ -167,7 +210,7 @@ After the environment is configured and your AI client has restarted, you can di
167
210
  ### ✅ Self-Check Before First Use
168
211
  1. `gecho-bridge` MCP is configured, or the `@gecho-ai/gecho-bridge-bundle` plugin is installed.
169
212
  2. The [Gecho browser extension](https://chromewebstore.google.com/detail/pjkaeenpekolahdbccjfenjcmanemlbj?utm_source=item-share-cb) is installed.
170
- 3. TikTok is open in Chrome and the account is logged in.
213
+ 3. The target platform is open in Chrome and the account is logged in (TikTok, YouTube, Facebook, X, or Amazon as applicable).
171
214
  4. The Gecho extension is logged in to a Gecho account and online.
172
215
  5. The TikTok page is not stuck or left on a CAPTCHA page.
173
216
 
@@ -185,8 +228,9 @@ Focused single-tool Skills are also available:
185
228
  - **Amazon**: `amazon-search`, `amazon-product`, `amazon-reviews`.
186
229
  - **TikTok**: `tiktok-video-search` for keyword-based video search; `tiktok-video` for a specific video’s detail, comments, and replies; `tiktok-influencer`, `tiktok-insight`, `tiktok-product`, and `tiktok-shop-search` for focused workflows.
187
230
  - **X**: `x-search` and `x-post-detail`.
231
+ - **Short-form video**: `youtube-shorts-search` for YouTube Shorts and `facebook-reels-search` for Facebook Reels.
188
232
 
189
- Use `tiktok-video-search` when you want to discover videos by keyword. Use `tiktok-video` when you already have a video URL and need its detail data. If you want the full TikTok research workflow, use `tiktok-search`.
233
+ Use `tiktok-video-search`, `youtube-shorts-search`, or `facebook-reels-search` when you want to discover short-form videos by keyword. Use `tiktok-video` when you already have a video URL and need its detail data. If you want the full TikTok research workflow, use `tiktok-search`.
190
234
 
191
235
  ### 🔍 Basic Search (`tiktok_search`)
192
236
  Suitable for quickly retrieving and collecting video data.
package/README.zh.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # Gecho Bridge 🚀
2
2
 
3
- **Gecho Bridge 通过 MCP 和 Gecho Chrome 扩展,把 OpenClaw、Hermes、Trae、Claude Code 等 AI 客户端连接到真实 Chrome 浏览器。** 你可以用它搜索 TikTok 视频、采集结构化元数据、保存 JSON 结果,并运行异步的产品、趋势、竞品和内容洞察工作流。
3
+ **Gecho Bridge 通过 MCP 和 Gecho Chrome 扩展,把 OpenClaw、Hermes、Trae、Claude Code 等 AI 客户端连接到真实 Chrome 浏览器。** 你可以用它搜索 TikTok 视频、YouTube Shorts、Facebook Reels、X 帖子和 Amazon 商品,采集结构化元数据、保存 JSON 结果,并运行异步的产品、趋势、竞品和内容洞察工作流。
4
4
 
5
5
  ## ⚠️ 重要前置:使用前必看
6
6
 
7
- Gecho Bridge 不能只靠 README、Skill 页面或 MCP 配置单独运行。首次搜索 TikTok 或运行洞察任务前,必须同时满足下面 3 个条件:
7
+ Gecho Bridge 不能只靠 README、Skill 页面或 MCP 配置单独运行。首次搜索平台内容或运行洞察任务前,必须同时满足下面 3 个条件:
8
8
 
9
9
  1. **在 AI 客户端中配置 Gecho Bridge MCP**。
10
10
  2. **安装 Gecho Chrome 扩展**,并在扩展中登录 Gecho 账号。
11
- 3. **在 Chrome 中登录 TikTok 网页版**,并保持已登录的 TikTok 标签页打开。
11
+ 3. **在 Chrome 中登录目标平台**,并保持已登录的平台标签页打开。
12
12
 
13
- 如果任一条件缺失,即使 Skill 或 Plugin 已安装,TikTok 搜索和洞察功能也可能无法正常运行。
13
+ 如果任一条件缺失,即使 Skill 或 Plugin 已安装,所选平台的搜索功能也可能无法正常运行。
14
14
 
15
15
  ## 🚀 3 步快速上手
16
16
 
@@ -125,6 +125,54 @@ npm run skillhub:tencent:publish -- \
125
125
 
126
126
  官方文档:[CLI 安装](https://skillhub.cn/install/skillhub.md)、[公共发布](https://skillhub.cn/ai/release.md)、[企业发布控制台](https://skillhub.cn/enterprise/dashboard/publish)、[企业 API Key](https://skillhub.cn/enterprise/dashboard/keys)。
127
127
 
128
+ ### WorkBuddy Skill 发布准备
129
+
130
+ WorkBuddy 使用独立的 Skill 包格式,不能直接上传腾讯 SkillHub 副本。项目会从源 Skill 创建被 Git 忽略的
131
+ `tmp/workbuddy-publish/` 副本,补齐 `display_name`、`display_name_en`、`description_zh`、
132
+ `description_en`、`version` 和 `author`,并按 WorkBuddy 官方要求使用
133
+ `skills/<skill-name>/SKILL.md` 目录结构打包。
134
+
135
+ ```bash
136
+ # 只生成 WorkBuddy 临时副本
137
+ npm run skillhub:workbuddy:stage
138
+
139
+ # 生成全部中英文 ZIP,并进行本地结构校验
140
+ npm run skillhub:workbuddy:dry-run
141
+
142
+ # 只准备一个中文 Skill
143
+ npm run skillhub:workbuddy:dry-run -- \
144
+ --skill tiktok-video-search --locale zh-CN
145
+ ```
146
+
147
+ 输出的 ZIP 位于 `tmp/workbuddy-publish/archives/`(单个不超过 3MB),可在 [WorkBuddy 开放平台](https://open.workbuddy.cn/)
148
+ 手动上传。脚本没有登录或自动提交功能,不会使用腾讯 SkillHub 的 `skh_...` 或 `sk-ent-...` Key。
149
+ WorkBuddy 官方格式参考:[Skill 文档](https://open.workbuddy.cn/docs/skill)。
150
+
151
+ ### Aily SkillHub 发布
152
+
153
+ Aily 当前通过网页上传 Skill 压缩包。项目提供了浏览器自动化脚本,复用已登录的 Edge,
154
+ 从 `tmp/manual-skill-packages/manifest.tsv` 读取压缩包,并使用每个 Skill 的
155
+ `publish.json` 中 `platforms.aily-skillhub.displayName` 自动填写展示名称。
156
+
157
+ 首次使用需要完全退出 Edge 后,以远程调试端口启动,再在该窗口登录 Aily:
158
+
159
+ ```bash
160
+ /Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge \
161
+ --remote-debugging-port=9222
162
+ ```
163
+
164
+ 然后执行:
165
+
166
+ ```bash
167
+ npm run skill:package:manual
168
+ npm run skillhub:aily:dry-run -- --skill tiktok-shop-search --locale zh-CN
169
+ npm run skillhub:aily:publish -- --skill tiktok-shop-search --locale zh-CN
170
+ ```
171
+
172
+ 脚本只修改网页表单,不修改源 Skill,也不保存浏览器凭证;发布结果写入
173
+ `tmp/aily-browser-publish/results.json`。完整参数和批量发布方式见
174
+ [`scripts/README.md`](scripts/README.md)。
175
+
128
176
  ### 方式二:在 Hermes 中一键配置 (Hermes Skill Hub)
129
177
  你可以通过以下命令将服务快捷添加到 Hermes 并重启:
130
178
  ```bash
@@ -167,7 +215,7 @@ claude mcp add gecho-bridge -- npx -y @gecho-ai/gecho-bridge@latest
167
215
  ### ✅ 首次使用前自检
168
216
  1. 已配置 `gecho-bridge` MCP,或已安装 `@gecho-ai/gecho-bridge-bundle` Plugin。
169
217
  2. 已安装 [Gecho 浏览器扩展](https://chromewebstore.google.com/detail/pjkaeenpekolahdbccjfenjcmanemlbj?utm_source=item-share-cb)。
170
- 3. Chrome 中已打开 TikTok 并登录账号。
218
+ 3. Chrome 中已打开目标平台并登录账号(按任务选择 TikTok、YouTube、Facebook、X 或 Amazon)。
171
219
  4. Gecho 扩展已登录 Gecho 账号并处于在线状态。
172
220
  5. TikTok 页面未卡住或未停在验证码页面。
173
221
 
@@ -185,8 +233,9 @@ Gecho 提供四个聚合 Skill:
185
233
  - **Amazon**:`amazon-search`、`amazon-product`、`amazon-reviews`。
186
234
  - **TikTok**:`tiktok-video-search` 用于按关键词搜索视频;`tiktok-video` 用于指定视频的详情、评论和回复;另有 `tiktok-influencer`、`tiktok-insight`、`tiktok-product` 和 `tiktok-shop-search`。
187
235
  - **X**:`x-search` 和 `x-post-detail`。
236
+ - **短视频**:`youtube-shorts-search` 用于 YouTube Shorts,`facebook-reels-search` 用于 Facebook Reels。
188
237
 
189
- 需要按关键词发现视频时使用 `tiktok-video-search`;已有视频 URL、需要获取视频详情时使用 `tiktok-video`。需要完整 TikTok 研究工作流时,使用 `tiktok-search`。
238
+ 需要按关键词发现短视频时使用 `tiktok-video-search`、`youtube-shorts-search` 或 `facebook-reels-search`;已有视频 URL、需要获取视频详情时使用 `tiktok-video`。需要完整 TikTok 研究工作流时,使用 `tiktok-search`。
190
239
 
191
240
  ### 🔍 基础搜索 (`tiktok_search`)
192
241
  适用于快速检索和收集视频数据。
@@ -0,0 +1,53 @@
1
+ const ACTION_RESULT_METADATA_FIELDS = ["meta", "errorCode", "errorMessage"];
2
+
3
+ function isRecord(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+
7
+ function hasOwn(value, key) {
8
+ return Object.prototype.hasOwnProperty.call(value, key);
9
+ }
10
+
11
+ function getActionResultMetadata(result) {
12
+ const metadata = {};
13
+ if (!isRecord(result)) return metadata;
14
+
15
+ for (const field of ACTION_RESULT_METADATA_FIELDS) {
16
+ if (hasOwn(result, field)) metadata[field] = result[field];
17
+ }
18
+ return metadata;
19
+ }
20
+
21
+ function createActionResultEnvelope(message) {
22
+ const source = isRecord(message) ? message : {};
23
+ return {
24
+ data: source.data,
25
+ ...getActionResultMetadata(source)
26
+ };
27
+ }
28
+
29
+ function normalizeActionResult(result) {
30
+ if (!isRecord(result) || !hasOwn(result, "data")) return { data: result };
31
+ return {
32
+ data: result.data,
33
+ ...getActionResultMetadata(result)
34
+ };
35
+ }
36
+
37
+ function isHardActionResultFailure(result) {
38
+ if (!isRecord(result)) return false;
39
+
40
+ const hasFailure = ["errorCode", "errorMessage"].some((field) => {
41
+ return hasOwn(result, field) && result[field] !== undefined && result[field] !== null && result[field] !== "";
42
+ });
43
+ if (!hasFailure) return false;
44
+
45
+ return String(result.meta?.status || "").toLowerCase() !== "partial";
46
+ }
47
+
48
+ module.exports = {
49
+ createActionResultEnvelope,
50
+ getActionResultMetadata,
51
+ isHardActionResultFailure,
52
+ normalizeActionResult
53
+ };
@@ -33854,8 +33854,8 @@ var require_package = __commonJS({
33854
33854
  "package.json"(exports2, module2) {
33855
33855
  module2.exports = {
33856
33856
  name: "@gecho-ai/gecho-bridge",
33857
- version: "1.1.37",
33858
- description: "TikTok Search and Insight tools for OpenClaw, connecting LLMs to TikTok via Chrome Extension.",
33857
+ version: "1.1.38-beta.0",
33858
+ description: "Browser research tools for OpenClaw, connecting LLMs to TikTok, YouTube Shorts, Facebook Reels, X, and Amazon via the Gecho Chrome Extension.",
33859
33859
  main: "mcp-client.js",
33860
33860
  bin: {
33861
33861
  "gecho-bridge": "mcp-client.js"
@@ -33869,6 +33869,7 @@ var require_package = __commonJS({
33869
33869
  "openclaw.plugin.json",
33870
33870
  "skills",
33871
33871
  "distribution-skills",
33872
+ "distribution-skills-zh-CN",
33872
33873
  "README.md",
33873
33874
  "README.zh.md",
33874
33875
  "qywx.jpg"
@@ -33884,15 +33885,25 @@ var require_package = __commonJS({
33884
33885
  "bundle:stage:dist": "bash ./scripts/publish-bundle-dist.sh stage",
33885
33886
  "bundle:publish:dist": "bash ./scripts/publish-bundle-dist.sh publish",
33886
33887
  "skill:validate": "node ./scripts/validate-skills.js",
33888
+ "skill:package:manual": "bash ./scripts/package-manual-skills.sh",
33887
33889
  "skill:stage": "bash ./scripts/publish-clawhub-skills.sh stage",
33888
33890
  "skill:dry-run": "bash ./scripts/publish-clawhub-skills.sh dry-run",
33889
33891
  "skill:publish": "bash ./scripts/publish-clawhub-skills.sh publish",
33890
33892
  "skill:legacy:stage": "bash ./scripts/publish-skills.sh stage",
33891
33893
  "skill:legacy:dry-run": "bash ./scripts/publish-skills.sh dry-run",
33892
33894
  "skill:legacy:publish": "bash ./scripts/publish-skills.sh publish",
33895
+ "skill:skills-sh:dry-run": "bash ./scripts/publish-skills-sh.sh dry-run",
33896
+ "skill:skills-sh:publish": "bash ./scripts/publish-skills-sh.sh publish",
33893
33897
  "skillhub:tencent:stage": "bash ./scripts/publish-tencent-skillhub.sh stage",
33894
33898
  "skillhub:tencent:dry-run": "bash ./scripts/publish-tencent-skillhub.sh dry-run",
33895
33899
  "skillhub:tencent:publish": "bash ./scripts/publish-tencent-skillhub.sh publish",
33900
+ "skillhub:aily:dry-run": "bash ./scripts/publish-aily-browser.sh dry-run",
33901
+ "skillhub:aily:publish": "bash ./scripts/publish-aily-browser.sh publish",
33902
+ "skillhub:workbuddy:stage": "node ./scripts/publish-workbuddy-skills.js stage",
33903
+ "skillhub:workbuddy:package": "node ./scripts/publish-workbuddy-skills.js package",
33904
+ "skillhub:workbuddy:dry-run": "node ./scripts/publish-workbuddy-skills.js dry-run",
33905
+ "skillhub:workbuddy:connector": "node ./scripts/package-workbuddy-connector.js",
33906
+ "skillhub:workbuddy:connector:dry-run": "node ./scripts/package-workbuddy-connector.js dry-run",
33896
33907
  "skillhub:modelscope:stage": "bash ./scripts/publish-modelscope-skills.sh stage",
33897
33908
  "skillhub:modelscope:dry-run": "bash ./scripts/publish-modelscope-skills.sh dry-run",
33898
33909
  "skillhub:modelscope:publish": "bash ./scripts/publish-modelscope-skills.sh publish",
@@ -33900,6 +33911,7 @@ var require_package = __commonJS({
33900
33911
  "publish:config:generate": "node ./scripts/generate-publish-configs.js",
33901
33912
  "publish:config:check": "node ./scripts/generate-publish-configs.js --check",
33902
33913
  "test:skillhub:tencent": "node --test ./test/publish-config.test.js ./test/tencent-skillhub-publish.test.js",
33914
+ "test:workbuddy": "node --test ./test/publish-config.test.js ./test/workbuddy-publish.test.js",
33903
33915
  "test:skillhub:modelscope": "node --test ./test/modelscope-publish.test.js"
33904
33916
  },
33905
33917
  keywords: [
@@ -33915,10 +33927,11 @@ var require_package = __commonJS({
33915
33927
  type: "commonjs",
33916
33928
  dependencies: {
33917
33929
  "@modelcontextprotocol/sdk": "^1.27.1",
33918
- ws: "^8.19.0"
33930
+ ws: "^8.21.3"
33919
33931
  },
33920
33932
  devDependencies: {
33921
- esbuild: "^0.25.4"
33933
+ esbuild: "^0.25.4",
33934
+ "playwright-core": "^1.62.1"
33922
33935
  },
33923
33936
  publishConfig: {
33924
33937
  access: "public"
@@ -33947,6 +33960,55 @@ var require_data_dir = __commonJS({
33947
33960
  }
33948
33961
  });
33949
33962
 
33963
+ // action-result.js
33964
+ var require_action_result = __commonJS({
33965
+ "action-result.js"(exports2, module2) {
33966
+ var ACTION_RESULT_METADATA_FIELDS = ["meta", "errorCode", "errorMessage"];
33967
+ function isRecord(value) {
33968
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33969
+ }
33970
+ function hasOwn(value, key) {
33971
+ return Object.prototype.hasOwnProperty.call(value, key);
33972
+ }
33973
+ function getActionResultMetadata(result) {
33974
+ const metadata = {};
33975
+ if (!isRecord(result)) return metadata;
33976
+ for (const field of ACTION_RESULT_METADATA_FIELDS) {
33977
+ if (hasOwn(result, field)) metadata[field] = result[field];
33978
+ }
33979
+ return metadata;
33980
+ }
33981
+ function createActionResultEnvelope(message) {
33982
+ const source = isRecord(message) ? message : {};
33983
+ return {
33984
+ data: source.data,
33985
+ ...getActionResultMetadata(source)
33986
+ };
33987
+ }
33988
+ function normalizeActionResult2(result) {
33989
+ if (!isRecord(result) || !hasOwn(result, "data")) return { data: result };
33990
+ return {
33991
+ data: result.data,
33992
+ ...getActionResultMetadata(result)
33993
+ };
33994
+ }
33995
+ function isHardActionResultFailure2(result) {
33996
+ if (!isRecord(result)) return false;
33997
+ const hasFailure = ["errorCode", "errorMessage"].some((field) => {
33998
+ return hasOwn(result, field) && result[field] !== void 0 && result[field] !== null && result[field] !== "";
33999
+ });
34000
+ if (!hasFailure) return false;
34001
+ return String(result.meta?.status || "").toLowerCase() !== "partial";
34002
+ }
34003
+ module2.exports = {
34004
+ createActionResultEnvelope,
34005
+ getActionResultMetadata,
34006
+ isHardActionResultFailure: isHardActionResultFailure2,
34007
+ normalizeActionResult: normalizeActionResult2
34008
+ };
34009
+ }
34010
+ });
34011
+
33950
34012
  // mcp-client.js
33951
34013
  var fs = require("fs");
33952
34014
  var { Server } = require_server2();
@@ -33961,6 +34023,7 @@ var { spawn } = require(cpModule);
33961
34023
  var path = require("path");
33962
34024
  var packageJson = require_package();
33963
34025
  var { getDefaultDataDir } = require_data_dir();
34026
+ var { isHardActionResultFailure, normalizeActionResult } = require_action_result();
33964
34027
  var SERVICE_BASE_URL = "http://127.0.0.1:18793";
33965
34028
  var HTTP_SERVICE_URL = `${SERVICE_BASE_URL}/search`;
33966
34029
  var PING_URL = `${SERVICE_BASE_URL}/ping`;
@@ -33979,6 +34042,8 @@ var SUPPORTED_TOOL_NAMES = /* @__PURE__ */ new Set([
33979
34042
  "tiktok_video",
33980
34043
  "x_search",
33981
34044
  "x_post_detail",
34045
+ "youtube_shorts_search",
34046
+ "facebook_reels_search",
33982
34047
  "amazon_search",
33983
34048
  "amazon_product",
33984
34049
  "amazon_reviews"
@@ -34244,6 +34309,32 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
34244
34309
  required: ["url"]
34245
34310
  }
34246
34311
  },
34312
+ {
34313
+ name: "youtube_shorts_search",
34314
+ description: "\u5728 YouTube Shorts \u4E0A\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u91C7\u96C6\u5019\u9009\u89C6\u9891\u5E76\u6309\u70B9\u8D5E\u6570\u8FD4\u56DE\u524D 20 \u6761\uFF0C\u540C\u65F6\u8865\u5145\u89C6\u9891\u8BE6\u60C5\u548C\u8BC4\u8BBA\u3002\u9700\u8981\u5728\u6D4F\u89C8\u5668\u4E2D\u767B\u5F55 YouTube\u3002",
34315
+ inputSchema: {
34316
+ type: "object",
34317
+ properties: {
34318
+ query: { type: "string", description: "\u641C\u7D22\u5173\u952E\u8BCD (\u4F8B\u5982: 'portable blender')" },
34319
+ targetCount: { type: "number", description: "\u5019\u9009\u91C7\u96C6\u6570\u91CF\uFF0C\u9ED8\u8BA4 200\uFF0C\u8303\u56F4 20-200", default: 200, minimum: 20, maximum: 200 },
34320
+ save_dir: { type: "string", description: "\u53EF\u9009\u7684\u4FDD\u5B58\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84" }
34321
+ },
34322
+ required: ["query"]
34323
+ }
34324
+ },
34325
+ {
34326
+ name: "facebook_reels_search",
34327
+ description: "\u5728 Facebook Reels \u4E0A\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u91C7\u96C6\u5019\u9009\u89C6\u9891\u5E76\u6309\u70B9\u8D5E\u6570\u8FD4\u56DE\u524D 20 \u6761\uFF0C\u540C\u65F6\u8865\u5145\u89C6\u9891\u8BE6\u60C5\u548C\u8BC4\u8BBA\u3002\u9700\u8981\u5728\u6D4F\u89C8\u5668\u4E2D\u767B\u5F55 Facebook\u3002",
34328
+ inputSchema: {
34329
+ type: "object",
34330
+ properties: {
34331
+ query: { type: "string", description: "\u641C\u7D22\u5173\u952E\u8BCD (\u4F8B\u5982: 'portable blender')" },
34332
+ targetCount: { type: "number", description: "\u5019\u9009\u91C7\u96C6\u6570\u91CF\uFF0C\u9ED8\u8BA4 200\uFF0C\u8303\u56F4 20-200", default: 200, minimum: 20, maximum: 200 },
34333
+ save_dir: { type: "string", description: "\u53EF\u9009\u7684\u4FDD\u5B58\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84" }
34334
+ },
34335
+ required: ["query"]
34336
+ }
34337
+ },
34247
34338
  {
34248
34339
  name: "amazon_search",
34249
34340
  description: "\u5728 Amazon \u4E0A\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u81EA\u52A8\u91C7\u96C6\u591A\u9875\u5546\u54C1\u4FE1\u606F\uFF08\u652F\u6301\u81EA\u52A8\u7FFB\u9875\uFF09\u3002marketplace \u53EF\u9009\uFF0C\u672A\u4F20\u65F6\u9ED8\u8BA4 US\u3002",
@@ -34362,15 +34453,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34362
34453
  if (statusResponse.status === "error") {
34363
34454
  const stage = statusResponse.stage ? ` (stage=${statusResponse.stage})` : "";
34364
34455
  const retries = typeof statusResponse.retryCount === "number" ? `, retries=${statusResponse.retryCount}` : "";
34456
+ const errorCode = statusResponse.errorCode ? ` [${statusResponse.errorCode}]` : "";
34365
34457
  return {
34366
34458
  content: [{
34367
34459
  type: "text",
34368
- text: `\u274C \u4EFB\u52A1 [${jobId}] \u6267\u884C\u5931\u8D25${stage}${retries}: ${statusResponse.error}`
34460
+ text: `\u274C \u4EFB\u52A1 [${jobId}] \u6267\u884C\u5931\u8D25${stage}${retries}${errorCode}: ${statusResponse.error || statusResponse.errorMessage || "\u672A\u77E5\u9519\u8BEF"}`
34461
+ }],
34462
+ isError: true
34463
+ };
34464
+ }
34465
+ const statusResult = normalizeActionResult(statusResponse);
34466
+ const result = statusResult.data;
34467
+ if (isHardActionResultFailure(statusResult)) {
34468
+ const errorCode = statusResult.errorCode ? ` [${statusResult.errorCode}]` : "";
34469
+ return {
34470
+ content: [{
34471
+ type: "text",
34472
+ text: `\u274C \u4EFB\u52A1 [${jobId}] \u6267\u884C\u5931\u8D25${errorCode}: ${statusResult.errorMessage || "\u672A\u77E5\u9519\u8BEF"}`
34369
34473
  }],
34370
34474
  isError: true
34371
34475
  };
34372
34476
  }
34373
- const result = statusResponse.data;
34374
34477
  if (typeof result === "object" && result !== null && result.error) {
34375
34478
  return { content: [{ type: "text", text: `\u274C \u4E1A\u52A1\u9519\u8BEF: ${result.error}` }], isError: true };
34376
34479
  }
@@ -34380,6 +34483,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34380
34483
  const savePath = statusResponse.savePath || "";
34381
34484
  const saveLine = savePath ? `\u{1F4C2} \u6570\u636E\u5DF2\u5B58: ${savePath}
34382
34485
 
34486
+ ` : "";
34487
+ const statusMetaLine = statusResult.meta ? `\u{1F4CA} \u91C7\u96C6\u72B6\u6001: ${statusResult.meta.status || "unknown"}${statusResult.meta.reason ? ` (${statusResult.meta.reason})` : ""}
34383
34488
  ` : "";
34384
34489
  const top20 = result.slice(0, 20);
34385
34490
  return {
@@ -34387,7 +34492,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34387
34492
  {
34388
34493
  type: "text",
34389
34494
  text: `\u2705 \u4EFB\u52A1 [${jobId}] \u6267\u884C\u6210\u529F\uFF01\u5171\u83B7\u53D6 ${result.length} \u6761\u6570\u636E\u3002
34390
- ` + saveLine + `\u4EE5\u4E0B\u662F\u90E8\u5206\u7ED3\u679C\u5C55\u793A\uFF1A
34495
+ ` + saveLine + statusMetaLine + `\u4EE5\u4E0B\u662F\u90E8\u5206\u7ED3\u679C\u5C55\u793A\uFF1A
34391
34496
  ` + JSON.stringify(top20, null, 2)
34392
34497
  }
34393
34498
  ]
@@ -34481,8 +34586,30 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34481
34586
  throw firstError;
34482
34587
  }
34483
34588
  }
34589
+ const actionResult = normalizeActionResult(serviceResponse);
34590
+ const actionResultMeta = actionResult.meta || {};
34591
+ const actionResultMetaLine = actionResult.meta ? `
34592
+ \u{1F4CA} \u91C7\u96C6\u72B6\u6001: ${actionResultMeta.status || "unknown"}${actionResultMeta.reason ? ` (${actionResultMeta.reason})` : ""}
34593
+ ` : "";
34484
34594
  if (serviceResponse.error) {
34485
- return { content: [{ type: "text", text: `\u274C \u9519\u8BEF: ${serviceResponse.error}` }], isError: true };
34595
+ const errorCode = serviceResponse.errorCode ? ` [${serviceResponse.errorCode}]` : "";
34596
+ return {
34597
+ content: [{
34598
+ type: "text",
34599
+ text: `\u274C \u9519\u8BEF${errorCode}: ${serviceResponse.error}${actionResultMetaLine}`
34600
+ }],
34601
+ isError: true
34602
+ };
34603
+ }
34604
+ if (isHardActionResultFailure(actionResult) || serviceResponse.success === false) {
34605
+ const errorCode = actionResult.errorCode ? ` [${actionResult.errorCode}]` : "";
34606
+ return {
34607
+ content: [{
34608
+ type: "text",
34609
+ text: `\u274C \u4E1A\u52A1\u9519\u8BEF${errorCode}: ${actionResult.errorMessage || "Bridge \u672A\u5B8C\u6210\u8BE5\u4EFB\u52A1"}${actionResultMetaLine}`
34610
+ }],
34611
+ isError: true
34612
+ };
34486
34613
  }
34487
34614
  if (serviceResponse.jobId) {
34488
34615
  const anticipatedPath = serviceResponse.savePath || "";
@@ -34504,7 +34631,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34504
34631
  ]
34505
34632
  };
34506
34633
  }
34507
- const result = serviceResponse.data;
34634
+ const result = actionResult.data;
34508
34635
  if (serviceResponse.success && result === void 0) {
34509
34636
  return { content: [{ type: "text", text: "\u2705 \u64CD\u4F5C\u6267\u884C\u6210\u529F\u3002" }] };
34510
34637
  }
@@ -34540,7 +34667,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34540
34667
  {
34541
34668
  type: "text",
34542
34669
  text: `\u2705 [${toolName}] \u89C6\u9891\u8BE6\u60C5\u4E0E\u8BC4\u8BBA\u83B7\u53D6\u6210\u529F\uFF0C\u5171\u91C7\u96C6 ${comments.length} \u6761\u8BC4\u8BBA\u53CA\u56DE\u590D\u3002
34543
- ` + saveLine + `\u4EE5\u4E0B\u4EC5\u5C55\u793A\u524D ${preview.commentsPreviewed} \u6761\u8BC4\u8BBA\uFF0C\u5B8C\u6574\u6570\u636E\u8BF7\u67E5\u770B\u4FDD\u5B58\u6587\u4EF6\uFF1A
34670
+ ` + saveLine + actionResultMetaLine + `\u4EE5\u4E0B\u4EC5\u5C55\u793A\u524D ${preview.commentsPreviewed} \u6761\u8BC4\u8BBA\uFF0C\u5B8C\u6574\u6570\u636E\u8BF7\u67E5\u770B\u4FDD\u5B58\u6587\u4EF6\uFF1A
34544
34671
  ` + JSON.stringify(preview, null, 2)
34545
34672
  }
34546
34673
  ]
@@ -34552,7 +34679,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34552
34679
  {
34553
34680
  type: "text",
34554
34681
  text: `\u2705 [${toolName}] \u5546\u54C1\u8BE6\u60C5\u83B7\u53D6\u6210\u529F\uFF01
34555
- ` + saveLine + JSON.stringify(result[0], null, 2)
34682
+ ` + saveLine + actionResultMetaLine + JSON.stringify(result[0], null, 2)
34556
34683
  }
34557
34684
  ]
34558
34685
  };
@@ -34563,7 +34690,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34563
34690
  {
34564
34691
  type: "text",
34565
34692
  text: `\u2705 [${toolName}] \u6267\u884C\u6210\u529F\uFF0C\u5171 ${result.length} \u6761\u6570\u636E\u3002
34566
- ` + saveLine + `\u4EE5\u4E0B\u662F\u90E8\u5206\u7ED3\u679C\u5C55\u793A\uFF1A
34693
+ ` + saveLine + actionResultMetaLine + `\u4EE5\u4E0B\u662F\u90E8\u5206\u7ED3\u679C\u5C55\u793A\uFF1A
34567
34694
  ` + JSON.stringify(top20, null, 2)
34568
34695
  }
34569
34696
  ]