diff --git a/README.md b/README.md
index 50b4b66..c31c13e 100644
--- a/README.md
+++ b/README.md
@@ -30,21 +30,22 @@ The market currently contains:
- `2` Agents: `desirecore`, `dingtalk-workspace`
- `1` Team: `contract-review-team`
-- `34` local built-in skills with `SKILL.md`
+- `40` local built-in skills with `SKILL.md`
- `29` external skill entries with `entry.json`
-- `63` publishable skills in total (`SKILL.md` + `entry.json`)
+- `69` publishable skills in total (`SKILL.md` + `entry.json`)
## Skill Sources
Local built-in skills are installable from this repository and must be listed in `builtin-skills.json`:
```text
-code-intelligence, configuring-compute, create-agent, dashscope-image-gen, delete-agent,
+baidu-poi-search, ccgp-gov-procurement, clone-agent, cnipa-patent-search, code-intelligence,
+configuring-compute, create-agent, creditchina-query, dashscope-image-gen, delete-agent,
dev-environment-setup, discover-agent, docx, frontend-design, guizang-ppt,
image-to-image, mail-operations, manage-skills, manage-teams, markdown,
-minimax-music-gen, minimax-video-gen, nodejs-runtime, pdf, pptx,
+minimax-music-gen, minimax-video-gen, multi-source-sentiment, nodejs-runtime, pdf, pptx,
presentation-forge, python-runtime, registering-services, s3-storage-operations, skill-creator,
-tech-diagram, update-agent, using-services, web-access, workflow, workforce-optimization,
+tech-diagram, tianyancha-risk, update-agent, using-services, web-access, workflow, workforce-optimization,
xiaomi-tts, xlsx
```
diff --git a/builtin-skills.json b/builtin-skills.json
index 8c89341..2d217c7 100644
--- a/builtin-skills.json
+++ b/builtin-skills.json
@@ -1,9 +1,13 @@
{
"skills": [
+ "baidu-poi-search",
+ "ccgp-gov-procurement",
"clone-agent",
+ "cnipa-patent-search",
"code-intelligence",
"configuring-compute",
"create-agent",
+ "creditchina-query",
"dashscope-image-gen",
"delete-agent",
"dev-environment-setup",
@@ -18,6 +22,7 @@
"markdown",
"minimax-music-gen",
"minimax-video-gen",
+ "multi-source-sentiment",
"nodejs-runtime",
"pdf",
"pptx",
@@ -27,6 +32,7 @@
"s3-storage-operations",
"skill-creator",
"tech-diagram",
+ "tianyancha-risk",
"update-agent",
"using-services",
"web-access",
diff --git a/manifest.json b/manifest.json
index 5e46687..6ec0c59 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,10 @@
"name": "DesireCore Official Market",
"version": "1.5.0",
"schemaVersion": "1.1.0",
- "supportedLocales": ["zh-CN", "en-US"],
+ "supportedLocales": [
+ "zh-CN",
+ "en-US"
+ ],
"defaultLocale": "en-US",
"i18n": {
"default_locale": "en-US",
@@ -28,8 +31,8 @@
"stats": {
"totalAgents": 2,
"totalTeams": 1,
- "totalSkills": 63,
- "lastUpdated": "2026-09-01"
+ "totalSkills": 69,
+ "lastUpdated": "2026-09-03"
},
"features": [
"curated-index",
diff --git a/skills/baidu-poi-search/SKILL.md b/skills/baidu-poi-search/SKILL.md
new file mode 100644
index 0000000..8b71656
--- /dev/null
+++ b/skills/baidu-poi-search/SKILL.md
@@ -0,0 +1,152 @@
+---
+name: baidu-poi-search
+description: >-
+ 百度地图企业 POI 搜索——输入企业名称,返回 POI 名称/地址/经纬度/分支机构。Use when 用户提到"查企业地址"、"查公司位置"、"POI搜索"、"企业地图"、"经纬度"、"查分支机构"、"百度地图"、"企业网点"、"周边企业"。
+version: 1.0.0
+type: procedural
+risk_level: low
+status: enabled
+tags:
+ - due-diligence
+ - baidu-map
+ - poi
+ - geolocation
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 百度地图POI搜索
+ short_desc: 输入企业名称,返回 POI 名称/地址/经纬度/分支机构
+ description: >-
+ 百度地图企业 POI 搜索——输入企业名称,返回 POI 名称/地址/经纬度/分支机构。Use when 用户提到"查企业地址"、"查公司位置"、"POI搜索"、"企业地图"、"经纬度"、"查分支机构"、"百度地图"、"企业网点"、"周边企业"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:24e98eab4d4e0f04
+ translated_by: human
+ en-US:
+ name: Baidu Map POI Search
+ short_desc: Enterprise POI lookup by company name — name, address, coordinates, branches
+ description: >-
+ Baidu Map enterprise POI search — input a company name and return POI name, address, latitude/longitude, and branch listings. Use when the user asks to look up a company address, location, POI, enterprise map, coordinates, branches, or nearby companies.
+ body: ./SKILL.md
+ source_hash: sha256:24e98eab4d4e0f04
+ translated_by: human
+market:
+ icon: >-
+
+ category: data
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# Baidu Map POI Search
+
+## L0: One-Sentence Summary
+
+Input a company name, call the Baidu Map Place Search API, and return normalized POI data (name / address / coordinates / province & city).
+
+## L1: Overview
+
+- **Data source**: Baidu Map Open Platform Place Search API v2
+- **Auth**: AK (free quota for individual developers)
+- **Invocation**: HTTP GET (curl / HttpRequest tool)
+- **Prerequisites**: no browser, no extra dependencies — pure REST API
+
+## Credential Setup
+
+This skill requires a Baidu Map AK (access key):
+
+1. Register a developer account at the [Baidu Map Open Platform](https://lbsyun.baidu.com/)
+2. Console → App Management → Create an app (enable the "Place Search" service; choose the empty-whitelist `0.0.0.0/0` AK type)
+3. Export the AK as the environment variable `BAIDU_MAP_AK`, or replace the `{BAIDU_MAP_AK}` placeholder in the commands below
+
+> If the local DesireCore service catalog already registers the Baidu Map service (endpoint `https://api.map.baidu.com`), prefer calling it through the catalog so credentials are managed centrally.
+
+## L2: Procedure
+
+### 1. Build the request
+
+```bash
+curl -s --max-time 15 --ssl-no-revoke \
+ "https://api.map.baidu.com/place/v2/search?query={company-name-URL-encoded}®ion={city-or-nationwide}&output=json&page_size=20&ak=${BAIDU_MAP_AK}"
+```
+
+**Parameters**:
+
+| Param | Value | Notes |
+|---|---|---|
+| query | Company name (URL-encoded) | e.g. `华为技术有限公司` → `%E5%8D%8E%E4%B8%BA%E6%8A%80%E6%9C%AF%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8` |
+| region | City name or `全国` (nationwide) | Scope; use nationwide when unsure |
+| output | json | Fixed |
+| page_size | 20 | Max 20 per page |
+| ak | `{BAIDU_MAP_AK}` | Baidu Map AK (free for individual developers) |
+
+### 2. Interpret the response
+
+- `status == 0`: success, extract `results[]`
+- `status != 0`: failure, check `message` (101 = AK missing, 200 = AK disabled, 302 = quota exceeded)
+
+### 3. Normalized mapping
+
+Map each entry in `results[]` to:
+
+```json
+{
+ "source": "baidu-poi",
+ "company_name": "{user input}",
+ "poi_name": "{result.name}",
+ "address": "{result.address}",
+ "latitude": "{result.location.lat}",
+ "longitude": "{result.location.lng}",
+ "province": "{result.province}",
+ "city": "{result.city}"
+}
+```
+
+### 4. Homonym filtering (due-diligence scenario)
+
+POI results may contain same-name noise (e.g. "南岗华为公司" is not "华为技术有限公司"). Filtering suggestion:
+
+- Exact match: `result.name` equals the full company name → `match=exact`
+- Partial match: `result.name` contains the full name or its short name → `match=partial`
+- Otherwise → `match=related`, listed separately in due-diligence reports
+
+### 5. Output format
+
+```json
+{
+ "query_status": "success",
+ "source": "baidu-poi",
+ "total": 5,
+ "results": [
+ { "poi_name": "华为技术有限公司", "address": "广东省深圳市龙岗区...", "latitude": "22.656137", "longitude": "114.066131", "match": "exact" }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+## Known Limitations
+
+- Free quota: QPS (~3/s) and daily caps (~100 place-search calls/day) for individual developers, per console quota management
+- POI ≠ registered business address: results are map annotations and may differ from the registered address (note the distinction in due diligence)
+- Homonyms: short names of famous companies hit many non-target POIs — prefer the full company name
+
+## Troubleshooting
+
+| Code | Meaning | Fix |
+|---|---|---|
+| 0 | Success | — |
+| 101 | AK param missing | Check the ak parameter |
+| 200 | AK disabled | Check app status in the Baidu console |
+| 201 | AK/SN check failed | This recipe uses an empty-whitelist `0.0.0.0/0` AK; no SN needed |
+| 302 | Quota exceeded | Wait for the daily reset or upgrade the quota |
+| 240 | API service invalid | The AK has not enabled "Place Search" — fix the app in the console |
diff --git a/skills/baidu-poi-search/SKILL.zh-CN.md b/skills/baidu-poi-search/SKILL.zh-CN.md
new file mode 100644
index 0000000..dadd423
--- /dev/null
+++ b/skills/baidu-poi-search/SKILL.zh-CN.md
@@ -0,0 +1,102 @@
+# 百度地图 POI 搜索
+
+## L0
+
+输入企业名称,调用百度地图地点检索 API,返回标准化 POI 数据(名称/地址/经纬度/省市)。
+
+## L1 概述
+
+- **数据源**:百度地图开放平台地点检索 API v2
+- **认证**:AK(个人开发者免费配额)
+- **调用方式**:HTTP GET(curl / HttpRequest 工具)
+- **前置条件**:无浏览器依赖、无额外依赖——纯 REST API
+
+## 凭证获取
+
+本技能需要百度地图 AK(访问令牌):
+
+1. 访问 [百度地图开放平台](https://lbsyun.baidu.com/) 注册开发者账号
+2. 控制台 → 应用管理 → 创建应用(启用"地点检索"服务,AK 类型选"浏览器白名单"并将白名单留空 `0.0.0.0/0`)
+3. 将 AK 配置为环境变量 `BAIDU_MAP_AK`,或替换下文命令中的 `{BAIDU_MAP_AK}` 占位符
+
+> 若本机 DesireCore 服务目录已注册百度地图服务(端点 `https://api.map.baidu.com`),优先通过服务目录调用,凭证由服务配置统一管理。
+
+## L2 操作步骤
+
+### 1. 构造请求
+
+```bash
+curl -s --max-time 15 --ssl-no-revoke \
+ "https://api.map.baidu.com/place/v2/search?query={企业名称URL编码}®ion={城市或全国}&output=json&page_size=20&ak=${BAIDU_MAP_AK}"
+```
+
+**参数说明**:
+
+| 参数 | 值 | 说明 |
+|---|---|---|
+| query | 企业名称(URL 编码) | 如"华为技术有限公司"→ `%E5%8D%8E%E4%B8%BA%E6%8A%80%E6%9C%AF%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8` |
+| region | 城市名或"全国" | 限定检索范围;不确定时用"全国" |
+| output | json | 固定 |
+| page_size | 20 | 每页条数(最大 20) |
+| ak | `{BAIDU_MAP_AK}` | 百度地图 AK(个人开发者免费申请) |
+
+### 2. 判断响应
+
+- `status == 0`:成功,提取 `results[]`
+- `status != 0`:失败,查看 `message`(如 101=AK参数不存在,200=AK被禁用,302=配额超限)
+
+### 3. 标准化映射
+
+对 `results[]` 中每条记录映射为:
+
+```json
+{
+ "source": "baidu-poi",
+ "company_name": "{用户输入的企业名称}",
+ "poi_name": "{result.name}",
+ "address": "{result.address}",
+ "latitude": "{result.location.lat}",
+ "longitude": "{result.location.lng}",
+ "province": "{result.province}",
+ "city": "{result.city}"
+}
+```
+
+### 4. 同名词过滤(尽调场景)
+
+POI 结果可能包含同名词干扰(如"南岗华为公司"不是"华为技术有限公司")。过滤建议:
+
+- 精确匹配:`result.name` 与企业全名一致 → 标记 `match=exact`
+- 包含匹配:`result.name` 包含企业全名或其简称 → 标记 `match=partial`
+- 其他 → 标记 `match=related`,尽调报告单独归类
+
+### 5. 输出格式
+
+```json
+{
+ "query_status": "success",
+ "source": "baidu-poi",
+ "total": 5,
+ "results": [
+ { "poi_name": "华为技术有限公司", "address": "广东省深圳市龙岗区...", "latitude": "22.656137", "longitude": "114.066131", "match": "exact" }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+## 已知限制
+
+- 免费配额:个人开发者有 QPS(约 3 次/秒)与日量上限(地点检索约 100 次/日,以控制台额度管理为准)
+- POI ≠ 工商注册地址:返回的是地图标注地址,可能与工商注册地址不同(尽调时注意区分)
+- 同名词:知名企业简称(如"华为")会命中大量非目标 POI,建议输入企业全名
+
+## 故障排查
+
+| 错误码 | 含义 | 处理 |
+|---|---|---|
+| 0 | 成功 | — |
+| 101 | AK 参数不存在 | 检查 ak 参数是否正确传递 |
+| 200 | AK 被禁用 | 到百度地图开放平台控制台检查应用状态 |
+| 201 | AK 校验失败 / SN 校验失败 | 本方案使用白名单 0.0.0.0/0 类型 AK,无需 SN |
+| 302 | 配额超限 | 查看控制台额度管理,等待次日或升级配额 |
+| 240 | API 服务无效 | AK 未勾选"地点检索"服务——到控制台修改应用勾选 |
diff --git a/skills/baidu-poi-search/catalog-metadata.v1.json b/skills/baidu-poi-search/catalog-metadata.v1.json
new file mode 100644
index 0000000..25fbe8d
--- /dev/null
+++ b/skills/baidu-poi-search/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "baidu-poi-search"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "百度地图POI搜索",
+ "summary": "输入企业名称,返回 POI 名称/地址/经纬度/分支机构",
+ "description": "百度地图企业 POI 搜索——输入企业名称,返回 POI 名称/地址/经纬度/分支机构。Use when 用户提到\"查企业地址\"、\"查公司位置\"、\"POI搜索\"、\"企业地图\"、\"经纬度\"、\"查分支机构\"、\"百度地图\"、\"企业网点\"、\"周边企业\"。"
+ },
+ "en-US": {
+ "name": "Baidu Map POI Search",
+ "summary": "Enterprise POI lookup by company name — name, address, coordinates, branches",
+ "description": "Baidu Map enterprise POI search — input a company name and return POI name, address, latitude/longitude, and branch listings. Use when the user asks to look up a company address, location, POI, enterprise map, coordinates, branches, or nearby companies."
+ }
+ },
+ "category": "data",
+ "tags": [
+ "due-diligence",
+ "baidu-map",
+ "poi",
+ "geolocation"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "low"
+ }
+}
diff --git a/skills/ccgp-gov-procurement/SKILL.md b/skills/ccgp-gov-procurement/SKILL.md
new file mode 100644
index 0000000..2a8b661
--- /dev/null
+++ b/skills/ccgp-gov-procurement/SKILL.md
@@ -0,0 +1,203 @@
+---
+name: ccgp-gov-procurement
+description: >-
+ 中国政府采购网招标公告查询——输入企业名称(或简称),搜索该企业参与的采购公告,返回公告列表(标题/链接/日期)并可深度提取详情字段(项目编号/采购人/代理机构/更正内容/联系人)。Use when 用户提到"查招投标"、"政府采购"、"采购公告"、"中标公告"、"招标信息"、"ccgp"、"企业中标"。
+version: 1.0.0
+type: procedural
+risk_level: medium
+status: enabled
+tags:
+ - due-diligence
+ - procurement
+ - government
+ - bidding
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 政府采购网招标查询
+ short_desc: 输入企业名称(建议简称),返回采购公告列表与详情字段
+ description: >-
+ 中国政府采购网招标公告查询——输入企业名称(或简称),搜索该企业参与的采购公告,返回公告列表(标题/链接/日期)并可深度提取详情字段(项目编号/采购人/代理机构/更正内容/联系人)。Use when 用户提到"查招投标"、"政府采购"、"采购公告"、"中标公告"、"招标信息"、"ccgp"、"企业中标"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:b5c84bd5f84eeb34
+ translated_by: human
+ en-US:
+ name: CCGP Procurement Search
+ short_desc: Search China Government Procurement announcements by company name
+ description: >-
+ China Government Procurement (ccgp.gov.cn) announcement search — input a company name (short name recommended) and return procurement announcements (title / link / date), with optional deep extraction of detail fields (project number / purchaser / agency / corrections / contacts). Use when the user asks about tenders, procurement announcements, winning bids, or ccgp.
+ body: ./SKILL.md
+ source_hash: sha256:b5c84bd5f84eeb34
+ translated_by: human
+market:
+ icon: >-
+
+ category: business
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# CCGP Government Procurement Search
+
+## L0: One-Sentence Summary
+
+Input a company name (short name recommended, e.g. "华为" instead of the full legal name), search ccgp.gov.cn via Kimi WebBridge browser automation, and return a structured list of procurement announcements.
+
+## L1: Overview
+
+- **Data source**: China Government Procurement search (`search.ccgp.gov.cn`)
+- **Auth**: none (public search)
+- **Invocation**: Kimi WebBridge browser automation (navigate + evaluate)
+- **Prerequisites**: Kimi WebBridge daemon running (`127.0.0.1:10086`) + browser extension connected
+- **Key advantage**: a browser session naturally avoids the IP throttling applied to direct curl calls
+
+## L2: Procedure
+
+### 1. Check the WebBridge daemon
+
+```bash
+curl -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ -d '{"action":"list_tabs","session":"ccgp-query"}' --max-time 10
+```
+
+If unreachable, start the daemon:
+
+```bash
+~/.kimi-webbridge/bin/kimi-webbridge.exe start
+```
+
+### 2. Navigate to the search results page
+
+**Windows approach** (write JSON to a temp file to avoid encoding issues):
+
+Write `C:\tmp\ccgp-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://search.ccgp.gov.cn/bxsearch?searchtype=1&page_index=1&bidSort=0&pinMu=0&bidType=0&dbselect=bidx&kw={company-short-name-URL-encoded}",
+ "newTab": true,
+ "group_title": "政府采购网查询"
+ },
+ "session": "ccgp-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\ccgp-nav.json" --max-time 30
+```
+
+Wait 5 seconds before continuing.
+
+### 3. Extract the announcement list
+
+Write `C:\tmp\ccgp-extract.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var txt=document.body.innerText||'';var total=(txt.match(/共找到\\s*(\\d+)\\s*条/)||[])[1]||'?';var items=[];document.querySelectorAll('a').forEach(function(a){var t=(a.innerText||'').replace(/\\s+/g,' ').trim();if(t.includes('{company-keyword}')&&t.length>10){var li=a.closest('li')||a.closest('div');var date='';if(li){var m=(li.innerText||'').match(/\\d{4}[-:]\\d{2}[-:]\\d{2}/);if(m)date=m[0];}items.push({title:t.slice(0,80),href:(a.href||'').slice(0,100),date:date});}});return JSON.stringify({total:total,count:items.length,items:items.slice(0,10)});})()"
+ },
+ "session": "ccgp-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\ccgp-extract.json" --max-time 40
+```
+
+### 4. Deep extraction from detail pages (optional)
+
+Navigate to each announcement's detail page and extract structured fields:
+
+```json
+{
+ "action": "navigate",
+ "args": { "url": "{announcement-detail-URL}" },
+ "session": "ccgp-query"
+}
+```
+
+Wait 5 seconds, then extract:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var txt=document.body.innerText||'';var lines=txt.split('\\n').map(function(s){return s.trim();}).filter(function(s){return s.length>0;});var fields={};for(var i=0;i 10, change `page_index=2` in the URL and repeat steps 2-3. Keep ≥5-second intervals.
+
+### 7. Close the session
+
+```json
+{
+ "action": "close_session",
+ "session": "ccgp-query"
+}
+```
+
+## Known Limitations
+
+- **Default time window is about one week**: results may be 0 — add `start_time` and `end_time` to the URL (e.g. `start_time=2026:01:01&end_time=2026:08:31`) or click the page's time filter
+- **Title-keyword search**: matching happens on announcement titles, not a supplier dimension — full legal names rarely hit; use the short name
+- **Polite pacing**: even browser sessions should keep ≥5 s between requests; do not hammer pagination
+- **HTML coupling**: redesigns may break selectors — if extraction is empty, fall back to reading `document.body.innerText`
+
+## Troubleshooting
+
+| Problem | Cause | Fix |
+|---|---|---|
+| navigate fails | daemon down / extension disconnected | restart via `kimi-webbridge.exe start` |
+| "频繁访问" (frequent-access) | IP throttling | browser sessions usually avoid it; wait 60 s and retry |
+| Empty extraction | 0 results / selectors broken | check the keyword; fall back to `evaluate` reading `body.innerText` |
+| Empty detail fields | async content not loaded | retry after 5 s |
diff --git a/skills/ccgp-gov-procurement/SKILL.zh-CN.md b/skills/ccgp-gov-procurement/SKILL.zh-CN.md
new file mode 100644
index 0000000..1f4385f
--- /dev/null
+++ b/skills/ccgp-gov-procurement/SKILL.zh-CN.md
@@ -0,0 +1,153 @@
+# 中国政府采购网招标公告查询
+
+## L0
+
+输入企业名称(建议用简称而非全名,如"华为"而非"华为技术有限公司"),通过 Kimi WebBridge 浏览器自动化搜索政府采购网,返回结构化招标公告列表。
+
+## L1 概述
+
+- **数据源**:中国政府采购网搜索系统(`search.ccgp.gov.cn`)
+- **认证**:无(公开搜索)
+- **调用方式**:Kimi WebBridge 浏览器自动化(navigate + evaluate)
+- **前置条件**:Kimi WebBridge daemon 运行中(`127.0.0.1:10086`)+ 浏览器扩展已连接
+- **核心优势**:浏览器会话天然规避 curl 直连的 IP 限流
+
+## L2 操作步骤
+
+### 1. 检查 WebBridge daemon
+
+```bash
+curl -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ -d '{"action":"list_tabs","session":"ccgp-query"}' --max-time 10
+```
+
+若连接失败,启动 daemon:
+
+```bash
+~/.kimi-webbridge/bin/kimi-webbridge.exe start
+```
+
+### 2. 导航搜索结果页
+
+**Windows 方式**(JSON 写入临时文件避免编码问题):
+
+写入 `C:\tmp\ccgp-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://search.ccgp.gov.cn/bxsearch?searchtype=1&page_index=1&bidSort=0&pinMu=0&bidType=0&dbselect=bidx&kw={企业简称URL编码}",
+ "newTab": true,
+ "group_title": "政府采购网查询"
+ },
+ "session": "ccgp-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\ccgp-nav.json" --max-time 30
+```
+
+等待 5 秒后继续。
+
+### 3. 提取公告列表
+
+写入 `C:\tmp\ccgp-extract.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var txt=document.body.innerText||'';var total=(txt.match(/共找到\\s*(\\d+)\\s*条/)||[])[1]||'?';var items=[];document.querySelectorAll('a').forEach(function(a){var t=(a.innerText||'').replace(/\\s+/g,' ').trim();if(t.includes('{企业名称关键字}')&&t.length>10){var li=a.closest('li')||a.closest('div');var date='';if(li){var m=(li.innerText||'').match(/\\d{4}[-:]\\d{2}[-:]\\d{2}/);if(m)date=m[0];}items.push({title:t.slice(0,80),href:(a.href||'').slice(0,100),date:date});}});return JSON.stringify({total:total,count:items.length,items:items.slice(0,10)});})()"
+ },
+ "session": "ccgp-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\ccgp-extract.json" --max-time 40
+```
+
+### 4. 深度提取详情页(可选)
+
+对列表中每条公告,导航到详情页并提取结构化字段:
+
+```json
+{
+ "action": "navigate",
+ "args": { "url": "{公告详情URL}" },
+ "session": "ccgp-query"
+}
+```
+
+等待 5 秒后提取:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var txt=document.body.innerText||'';var lines=txt.split('\\n').map(function(s){return s.trim();}).filter(function(s){return s.length>0;});var fields={};for(var i=0;i 10,修改 URL 中 `page_index=2` 重复步骤 2-3。保持 ≥5 秒间隔。
+
+### 7. 关闭会话
+
+```json
+{
+ "action": "close_session",
+ "session": "ccgp-query"
+}
+```
+
+## 已知限制
+
+- **默认时间范围仅近一周**:搜索结果可能为 0——需在 URL 中加 `start_time` 和 `end_time` 参数放宽(如 `start_time=2026:01:01&end_time=2026:08:31`),或点击页面"近半年"筛选
+- **标题检索模式**:搜索匹配公告标题中的关键词,非供应商维度——企业全名命中率低,建议用简称(如"华为"而非"华为技术有限公司")
+- **礼貌间隔**:浏览器会话虽规避了 curl 限流,但仍应保持 ≥5 秒/次的间隔,不要高频翻页
+- **HTML 结构依赖**:页面改版可能导致选择器失效——若提取为空,改用 `document.body.innerText` 全文读取
+
+## 故障排查
+
+| 问题 | 原因 | 处理 |
+|---|---|---|
+| navigate 失败 | daemon 未运行 / 扩展断开 | `kimi-webbridge.exe start` 重启 daemon |
+| "频繁访问" | IP 限流 | 浏览器会话一般不触发;若触发等 60 秒重试 |
+| 提取列表为空 | 搜索结果为 0 / 选择器失效 | 检查 keyword 是否正确;改用 `evaluate` 读 `body.innerText` |
+| 详情页字段为空 | 页面异步加载未完成 | 等 5 秒后重试提取 |
diff --git a/skills/ccgp-gov-procurement/catalog-metadata.v1.json b/skills/ccgp-gov-procurement/catalog-metadata.v1.json
new file mode 100644
index 0000000..9980125
--- /dev/null
+++ b/skills/ccgp-gov-procurement/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "ccgp-gov-procurement"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "政府采购网招标查询",
+ "summary": "输入企业名称(建议简称),返回采购公告列表与详情字段",
+ "description": "中国政府采购网招标公告查询——输入企业名称(或简称),搜索该企业参与的采购公告,返回公告列表(标题/链接/日期)并可深度提取详情字段(项目编号/采购人/代理机构/更正内容/联系人)。Use when 用户提到\"查招投标\"、\"政府采购\"、\"采购公告\"、\"中标公告\"、\"招标信息\"、\"ccgp\"、\"企业中标\"。"
+ },
+ "en-US": {
+ "name": "CCGP Procurement Search",
+ "summary": "Search China Government Procurement announcements by company name",
+ "description": "China Government Procurement (ccgp.gov.cn) announcement search — input a company name (short name recommended) and return procurement announcements (title / link / date), with optional deep extraction of detail fields (project number / purchaser / agency / corrections / contacts). Use when the user asks about tenders, procurement announcements, winning bids, or ccgp."
+ }
+ },
+ "category": "business",
+ "tags": [
+ "due-diligence",
+ "procurement",
+ "government",
+ "bidding"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "medium"
+ }
+}
diff --git a/skills/cnipa-patent-search/SKILL.md b/skills/cnipa-patent-search/SKILL.md
new file mode 100644
index 0000000..8a3e016
--- /dev/null
+++ b/skills/cnipa-patent-search/SKILL.md
@@ -0,0 +1,228 @@
+---
+name: cnipa-patent-search
+description: >-
+ 国家知识产权局专利检索——输入企业名称(作为申请人),返回专利列表(申请号/申请日/发明名称/专利类型/专利状态/主分类号/申请人/发明人/公开号/公开日/代理机构)。Use when 用户提到"查专利"、"知识产权"、"专利检索"、"专利申请"、"cnipa"、"pss-system"、"发明"、"实用新型"、"外观设计"、"专利状态"。
+version: 1.0.0
+type: procedural
+risk_level: medium
+status: enabled
+tags:
+ - due-diligence
+ - patent
+ - cnipa
+ - intellectual-property
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 知识产权局专利检索
+ short_desc: 登录态检索 pss-system,返回企业专利列表(申请号/类型/状态等)
+ description: >-
+ 国家知识产权局专利检索——输入企业名称(作为申请人),返回专利列表(申请号/申请日/发明名称/专利类型/专利状态/主分类号/申请人/发明人/公开号/公开日/代理机构)。Use when 用户提到"查专利"、"知识产权"、"专利检索"、"专利申请"、"cnipa"、"pss-system"、"发明"、"实用新型"、"外观设计"、"专利状态"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:08c8cb6ca63c6dd9
+ translated_by: human
+ en-US:
+ name: CNIPA Patent Search
+ short_desc: Logged-in pss-system patent search by applicant company name
+ description: >-
+ CNIPA patent search — input a company name (as applicant) and return a patent list (application number / date / title / type / status / main class / applicant / inventors / publication). Use when the user asks about patents, intellectual property, patent applications, cnipa, pss-system, inventions, utility models, or designs.
+ body: ./SKILL.md
+ source_hash: sha256:08c8cb6ca63c6dd9
+ translated_by: human
+market:
+ icon: >-
+
+ category: business
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# CNIPA Patent Search
+
+## L0: One-Sentence Summary
+
+Input a company name, drive the CNIPA pss-system patent search via Kimi WebBridge browser automation, and return a structured patent list.
+
+## L1: Overview
+
+- **Data source**: CNIPA Patent Search and Analysis System (`pss-system.cponline.cnipa.gov.cn`)
+- **Auth**: logged-in account (**registration required** — anonymous search redirects to login)
+- **Invocation**: Kimi WebBridge browser automation (navigate + evaluate + CDP insertText)
+- **Prerequisites**:
+ - Kimi WebBridge daemon running
+ - the user has **logged into pss-system** in the browser (login persists; log in once and reuse)
+
+## Account Registration
+
+pss-system requires real-name registration (phone + SMS):
+
+1. Open `https://pss-system.cponline.cnipa.gov.cn/` in the browser
+2. Click "注册" and complete real-name registration
+3. Log in once — the browser keeps the session for later automation
+
+## L2: Procedure
+
+### 1. Check the WebBridge daemon
+
+```bash
+~/.kimi-webbridge/bin/kimi-webbridge.exe status
+```
+
+If down or disconnected, start it: `kimi-webbridge.exe start`.
+
+### 2. Navigate to pss-system
+
+Write `C:\tmp\cnipa-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://pss-system.cponline.cnipa.gov.cn/",
+ "newTab": true,
+ "group_title": "专利检索"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cnipa-nav.json" --max-time 30
+```
+
+Wait 5 seconds.
+
+### 3. Confirm login, accept the disclaimer, enter search
+
+Write `C:\tmp\cnipa-agree.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(async function(){var txt=document.body.innerText||'';var hasLogout=txt.includes('退出');if(txt.includes('免责声明')){var btns=document.querySelectorAll('button.el-button--primary');for(var b of btns){if((b.innerText||'').replace(/\\s+/g,'')==='同意'){b.click();break;}}await new Promise(function(r){setTimeout(r,4000);});}txt=document.body.innerText||'';return JSON.stringify({url:location.href.slice(0,80),isSearch:txt.includes('常规检索'),inputs:document.querySelectorAll('input').length,hasLogout:hasLogout});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+**Login check**: if `hasLogout=false`, the user must log into pss-system in the browser first.
+
+### 4. Focus the search box + CDP input
+
+Write `C:\tmp\cnipa-focus.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){for(var i of document.querySelectorAll('input')){if((i.placeholder||'').includes('请输入关键词')){i.value='';i.dispatchEvent(new Event('input',{bubbles:true}));i.focus();return 'focused';}}return 'not-found';})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+Then write `C:\tmp\cnipa-insert.json` (CDP real input, Vue-compatible):
+
+```json
+{
+ "action": "cdp",
+ "args": {
+ "method": "Input.insertText",
+ "params": { "text": "{company name}" }
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 5. Click search + wait for results
+
+Write `C:\tmp\cnipa-click.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(async function(){var clicked=false;for(var el of document.querySelectorAll('div.btn')){if((el.innerText||'').replace(/\\s+/g,'')==='检索'){el.click();clicked=true;break;}}await new Promise(function(r){setTimeout(r,8000);});var tables=document.querySelectorAll('table').length;var rows=document.querySelectorAll('table tr').length;var hits=(document.body.innerText.match(/共[\\d,]+[条篇]/)||[])[0]||'';return JSON.stringify({clicked:clicked,url:location.href.slice(0,80),tables:tables,rows:rows,hits:hits});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 6. Extract the result table
+
+Write `C:\tmp\cnipa-table.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var table=document.querySelector('table');if(!table)return JSON.stringify({err:'no-table'});var headers=[];table.querySelectorAll('thead th').forEach(function(th){headers.push((th.innerText||'').trim())});var rows=[];table.querySelectorAll('tbody tr').forEach(function(tr){var cells=[];tr.querySelectorAll('td').forEach(function(td){cells.push((td.innerText||'').trim().slice(0,60))});rows.push(cells)});return JSON.stringify({headers:headers,rowCount:rows.length,rows:rows});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 7. Normalized mapping
+
+```json
+{
+ "query_status": "success",
+ "source": "cnipa",
+ "company_name": "{company name}",
+ "total_found": 1,
+ "patents": [
+ {
+ "patent_number": "202310104843.5",
+ "application_date": "2023.01.16",
+ "patent_name": "一种通信方法及装置",
+ "patent_type": "发明",
+ "patent_status": "实质审查的生效",
+ "main_class_code": "H04W72/54",
+ "applicant": "华为技术有限公司",
+ "applicant_address": "广东省深圳市",
+ "publication_number": "CN117834529A",
+ "publication_date": "2024.04.05"
+ }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 8. Close the session
+
+```json
+{
+ "action": "close_session",
+ "session": "cnipa-patent"
+}
+```
+
+## Known Limitations
+
+- **Login required**: anonymous searches redirect to login or silently fail (unstable behavior); logged-in sessions return results reliably
+- **Session persistence**: browser cookies keep the login valid for a long time, but re-login may be needed after long idle periods
+- **Vue compatibility**: real input must go through CDP `Input.insertText` (not DOM setters), otherwise the Vue autocomplete ignores the text
+- **Pagination**: when results exceed 10, click the pager and extract each page
+
+## Troubleshooting
+
+| Problem | Cause | Fix |
+|---|---|---|
+| Search click redirects to login | not logged in | log into pss-system in the browser |
+| Search click does nothing | Vue event not triggered | confirm CDP insertText was used; check the login state |
+| Table empty | async results loading | retry extraction after 8 s |
+| Stuck on the disclaimer | agree button not clicked | re-run the evaluate that clicks 同意 |
diff --git a/skills/cnipa-patent-search/SKILL.zh-CN.md b/skills/cnipa-patent-search/SKILL.zh-CN.md
new file mode 100644
index 0000000..fb2ba7c
--- /dev/null
+++ b/skills/cnipa-patent-search/SKILL.zh-CN.md
@@ -0,0 +1,178 @@
+# 国家知识产权局专利检索
+
+## L0
+
+输入企业名称,通过 Kimi WebBridge 浏览器自动化操作 pss-system 专利检索系统,返回结构化专利列表。
+
+## L1 概述
+
+- **数据源**:国家知识产权局专利检索及分析系统(`pss-system.cponline.cnipa.gov.cn`)
+- **认证**:账号登录态(**必须先注册登录**——匿名检索会跳转登录页)
+- **调用方式**:Kimi WebBridge 浏览器自动化(navigate + evaluate + CDP insertText)
+- **前置条件**:
+ - Kimi WebBridge daemon 运行中
+ - 用户已在浏览器中**登录 pss-system 账号**(登录态长期有效,登录一次即可复用)
+
+## 账号注册
+
+pss-system 需实名注册(手机号 + 短信验证):
+
+1. 浏览器访问 `https://pss-system.cponline.cnipa.gov.cn/`
+2. 点击"注册"完成实名注册
+3. 登录一次——登录态由浏览器保存,后续自动化复用
+
+## L2 操作步骤
+
+### 1. 检查 WebBridge daemon
+
+```bash
+~/.kimi-webbridge/bin/kimi-webbridge.exe status
+```
+
+若 daemon 未运行或扩展断开,启动:`kimi-webbridge.exe start`。
+
+### 2. 导航 pss-system
+
+写入 `C:\tmp\cnipa-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://pss-system.cponline.cnipa.gov.cn/",
+ "newTab": true,
+ "group_title": "专利检索"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cnipa-nav.json" --max-time 30
+```
+
+等待 5 秒。
+
+### 3. 确认登录态 + 同意声明 + 进入检索页
+
+写入 `C:\tmp\cnipa-agree.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(async function(){var txt=document.body.innerText||'';var hasLogout=txt.includes('退出');if(txt.includes('免责声明')){var btns=document.querySelectorAll('button.el-button--primary');for(var b of btns){if((b.innerText||'').replace(/\\s+/g,'')==='同意'){b.click();break;}}await new Promise(function(r){setTimeout(r,4000);});}txt=document.body.innerText||'';return JSON.stringify({url:location.href.slice(0,80),isSearch:txt.includes('常规检索'),inputs:document.querySelectorAll('input').length,hasLogout:hasLogout});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+**登录态判断**:若 `hasLogout=false`,说明未登录——需用户在浏览器中登录 pss-system 后重试。
+
+### 4. 聚焦检索框 + CDP 真实输入
+
+写入 `C:\tmp\cnipa-focus.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){for(var i of document.querySelectorAll('input')){if((i.placeholder||'').includes('请输入关键词')){i.value='';i.dispatchEvent(new Event('input',{bubbles:true}));i.focus();return 'focused';}}return 'not-found';})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+执行后,写入 `C:\tmp\cnipa-insert.json`(CDP 真实输入,Vue 组件兼容):
+
+```json
+{
+ "action": "cdp",
+ "args": {
+ "method": "Input.insertText",
+ "params": { "text": "{企业名称}" }
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 5. 点击检索 + 等待结果
+
+写入 `C:\tmp\cnipa-click.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(async function(){var clicked=false;for(var el of document.querySelectorAll('div.btn')){if((el.innerText||'').replace(/\\s+/g,'')==='检索'){el.click();clicked=true;break;}}await new Promise(function(r){setTimeout(r,8000);});var tables=document.querySelectorAll('table').length;var rows=document.querySelectorAll('table tr').length;var hits=(document.body.innerText.match(/共[\\d,]+[条篇]/)||[])[0]||'';return JSON.stringify({clicked:clicked,url:location.href.slice(0,80),tables:tables,rows:rows,hits:hits});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 6. 提取表格数据
+
+写入 `C:\tmp\cnipa-table.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var table=document.querySelector('table');if(!table)return JSON.stringify({err:'no-table'});var headers=[];table.querySelectorAll('thead th').forEach(function(th){headers.push((th.innerText||'').trim())});var rows=[];table.querySelectorAll('tbody tr').forEach(function(tr){var cells=[];tr.querySelectorAll('td').forEach(function(td){cells.push((td.innerText||'').trim().slice(0,60))});rows.push(cells)});return JSON.stringify({headers:headers,rowCount:rows.length,rows:rows});})()"
+ },
+ "session": "cnipa-patent"
+}
+```
+
+### 7. 标准化映射
+
+```json
+{
+ "query_status": "success",
+ "source": "cnipa",
+ "company_name": "{企业名称}",
+ "total_found": 1,
+ "patents": [
+ {
+ "patent_number": "202310104843.5",
+ "application_date": "2023.01.16",
+ "patent_name": "一种通信方法及装置",
+ "patent_type": "发明",
+ "patent_status": "实质审查的生效",
+ "main_class_code": "H04W72/54",
+ "applicant": "华为技术有限公司",
+ "applicant_address": "广东省深圳市",
+ "publication_number": "CN117834529A",
+ "publication_date": "2024.04.05"
+ }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 8. 关闭会话
+
+```json
+{
+ "action": "close_session",
+ "session": "cnipa-patent"
+}
+```
+
+## 已知限制
+
+- **必须登录态**:匿名状态下点击检索会跳转 login 页或静默无响应(行为不稳定);登录态下检索正常返回结果
+- **登录态会话保持**:浏览器登录 pss-system 后 cookie 长期有效,WebBridge 会话可复用——但长时间未操作后可能需要重新登录
+- **Vue 组件兼容性**:必须用 CDP `Input.insertText` 真实输入(非 DOM setter),否则 Vue 下拉联想组件不接收文本
+- **翻页**:结果超过 10 条时,点击页面分页按钮翻页,提取每页表格数据
+
+## 故障排查
+
+| 问题 | 原因 | 处理 |
+|---|---|---|
+| 点击检索后 URL 跳转到 login | 未登录 | 用户在浏览器中登录 pss-system |
+| 点击检索后无响应 | Vue 事件未触发 | 确认用 CDP insertText 输入了检索词;检查登录态是否有效 |
+| 表格为空 | 结果异步加载中 | 等待 8 秒后重新提取表格 |
+| "免责声明"页卡住 | 同意按钮未点击成功 | 重新执行 evaluate 点击同意按钮 |
diff --git a/skills/cnipa-patent-search/catalog-metadata.v1.json b/skills/cnipa-patent-search/catalog-metadata.v1.json
new file mode 100644
index 0000000..9578f2d
--- /dev/null
+++ b/skills/cnipa-patent-search/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "cnipa-patent-search"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "知识产权局专利检索",
+ "summary": "登录态检索 pss-system,返回企业专利列表(申请号/类型/状态等)",
+ "description": "国家知识产权局专利检索——输入企业名称(作为申请人),返回专利列表(申请号/申请日/发明名称/专利类型/专利状态/主分类号/申请人/发明人/公开号/公开日/代理机构)。Use when 用户提到\"查专利\"、\"知识产权\"、\"专利检索\"、\"专利申请\"、\"cnipa\"、\"pss-system\"、\"发明\"、\"实用新型\"、\"外观设计\"、\"专利状态\"。"
+ },
+ "en-US": {
+ "name": "CNIPA Patent Search",
+ "summary": "Logged-in pss-system patent search by applicant company name",
+ "description": "CNIPA patent search — input a company name (as applicant) and return a patent list (application number / date / title / type / status / main class / applicant / inventors / publication). Use when the user asks about patents, intellectual property, patent applications, cnipa, pss-system, inventions, utility models, or designs."
+ }
+ },
+ "category": "business",
+ "tags": [
+ "due-diligence",
+ "patent",
+ "cnipa",
+ "intellectual-property"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "medium"
+ }
+}
diff --git a/skills/creditchina-query/SKILL.md b/skills/creditchina-query/SKILL.md
new file mode 100644
index 0000000..266c247
--- /dev/null
+++ b/skills/creditchina-query/SKILL.md
@@ -0,0 +1,279 @@
+---
+name: creditchina-query
+description: >-
+ 信用中国企业信用信息查询——输入企业名称,自动通过图形验证码(ddddocr 本地 OCR 100ms),返回信用信息(行政处罚/失信被执行/行政许可)。Use when 用户提到"查信用"、"信用中国"、"行政处罚"、"失信企业"、"企业信用"、"失信被执行人"、"行政许可"、"creditchina"。
+version: 1.0.0
+type: procedural
+risk_level: high
+status: enabled
+tags:
+ - due-diligence
+ - credit
+ - creditchina
+ - compliance
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 信用中国查询
+ short_desc: 浏览器自动化 + ddddocr 本地过验证码,返回企业信用信息
+ description: >-
+ 信用中国企业信用信息查询——输入企业名称,自动通过图形验证码(ddddocr 本地 OCR 100ms),返回信用信息(行政处罚/失信被执行/行政许可)。Use when 用户提到"查信用"、"信用中国"、"行政处罚"、"失信企业"、"企业信用"、"失信被执行人"、"行政许可"、"creditchina"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:ae28ca7a89d99438
+ translated_by: human
+ en-US:
+ name: Credit China Query
+ short_desc: Browser automation with local ddddocr captcha solving for enterprise credit records
+ description: >-
+ Credit China (creditchina.gov.cn) enterprise credit query — input a company name, automatically pass the graphic captcha (ddddocr local OCR, ~100 ms), and return credit records (administrative penalties / dishonest debtors / administrative licenses). Use when the user asks about enterprise credit, administrative penalties, dishonest-debtor lists, or creditchina.
+ body: ./SKILL.md
+ source_hash: sha256:ae28ca7a89d99438
+ translated_by: human
+market:
+ icon: >-
+
+ category: business
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# Credit China Query
+
+## L0: One-Sentence Summary
+
+Input a company name, pass the graphic captcha automatically via Kimi WebBridge plus ddddocr local OCR, and return the enterprise's credit records.
+
+## L1: Overview
+
+- **Data source**: Credit China (`creditchina.gov.cn`, guided by NDRC)
+- **Auth**: graphic captcha (solved locally by ddddocr, ~100 ms)
+- **Invocation**: Kimi WebBridge + CDP screenshot + ddddocr Python OCR
+- **Prerequisites**:
+ - Kimi WebBridge daemon running
+ - Python with `ddddocr` (`pip install ddddocr`)
+ - Python with `Pillow` (`pip install pillow`)
+
+## L2: Procedure
+
+### 1. Navigate to the search page
+
+Write `C:\tmp\cc-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://www.creditchina.gov.cn/xinyongxinxi/?keyword={company-name-URL-encoded}&scenesVal=default&tableName=credit_xyzx_tyshxydm",
+ "newTab": true,
+ "group_title": "信用中国查询"
+ },
+ "session": "creditchina-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cc-nav.json" --max-time 30
+```
+
+Wait 6 seconds.
+
+### 2. Confirm the captcha overlay
+
+Write `C:\tmp\cc-check.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var v=document.getElementById('vcode');var i=document.getElementById('vcodeimg');return JSON.stringify({vcode:v?v.getBoundingClientRect().width>0:false,vimg:i?i.getBoundingClientRect().width>0:false});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+If `vcode=true` and `vimg=true`, the captcha overlay is visible — continue.
+
+### 3. Get the captcha image coordinates
+
+Write `C:\tmp\cc-coord.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var img=document.getElementById('vcodeimg');if(!img)return 'no-img';var r=img.getBoundingClientRect();return JSON.stringify({x:Math.round(r.x),y:Math.round(r.y),w:Math.round(r.width),h:Math.round(r.height),dpr:window.devicePixelRatio});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+Record `x` / `y` / `w` / `h`.
+
+### 4. CDP screenshot of the captcha region
+
+> **Note**: the WebBridge screenshot action fails intermittently on this site (HTTP 000/400) — **always use CDP `Page.captureScreenshot` with the clip parameter**.
+
+Write `C:\tmp\cc-shot.json` (replace `{x}` / `{y}` / `{w}` / `{h}`):
+
+```json
+{
+ "action": "cdp",
+ "args": {
+ "method": "Page.captureScreenshot",
+ "params": {
+ "format": "png",
+ "clip": { "x": {x}, "y": {y}, "width": {w}, "height": {h}, "scale": 1 }
+ }
+ },
+ "session": "creditchina-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cc-shot.json" --max-time 40 -o "C:/tmp/cc-cdp-resp.json"
+```
+
+Decode the base64 payload and save the image:
+
+```python
+import json, base64
+d = json.load(open(r'C:\tmp\cc-cdp-resp.json', encoding='utf-8'))
+b64 = d.get('data', {}).get('data', '')
+open(r'C:\tmp\cc-captcha.png', 'wb').write(base64.b64decode(b64))
+```
+
+### 5. ddddocr recognition (~100 ms)
+
+```python
+import ddddocr, sys, time
+sys.stdout.reconfigure(encoding='utf-8')
+ocr = ddddocr.DdddOcr(show_ad=False)
+t0 = time.time()
+with open(r'C:\tmp\cc-captcha.png', 'rb') as f:
+ code = ocr.classification(f.read())
+print(f'验证码: {code} ({(time.time()-t0)*1000:.0f}ms)')
+open(r'C:\tmp\cc-code.txt', 'w').write(code)
+```
+
+### 6. Fill and submit the captcha
+
+Write `C:\tmp\cc-submit.json` (replace `{code}`):
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var inp=document.getElementById('vcode');if(!inp)return 'no-input';var s=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;s.call(inp,'{code}');inp.dispatchEvent(new Event('input',{bubbles:true}));inp.dispatchEvent(new Event('change',{bubbles:true}));for(var el of document.querySelectorAll('button, a, input[type=button]')){if((el.innerText||el.value||'').trim()==='验证'){el.click();break;}}return 'submitted';})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+Wait 5 seconds.
+
+### 7. Check the verification result
+
+Write `C:\tmp\cc-result.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var t=document.body.innerText||'';if(t.includes('验证码错误'))return '验证码错误';if(t.includes('失效'))return '验证码已失效';return JSON.stringify({hasResult:t.includes('共')||t.includes('条'),textSample:t.slice(0,500)});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+**Three outcomes**:
+
+- `"验证码错误"` / `"验证码已失效"` → retry from step 3 (click 换一张 to refresh)
+- `hasResult=true` with data → success, go to step 8
+- `textSample` contains "很抱歉,没有找到您搜索的数据" → captcha passed but the keyword has no match — retry with the full name or a short name
+
+### 8. Read the search results
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){return document.body.innerText.slice(0,1500);})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+### 9. Normalized mapping
+
+```json
+{
+ "query_status": "success",
+ "source": "creditchina",
+ "company_name": "{company name}",
+ "captcha_solved": true,
+ "search_result": "有结果 | 无匹配",
+ "credit_info": [
+ {
+ "event_type": "行政处罚 | 行政许可 | 失信被执行 | 守信激励",
+ "event_title": "...",
+ "event_date": "...",
+ "source_url": "...",
+ "summary": "..."
+ }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 10. Close the session
+
+```json
+{
+ "action": "close_session",
+ "session": "creditchina-query"
+}
+```
+
+## Retry Strategy
+
+On captcha failure (wrong/expired), retry automatically up to 3 rounds:
+
+1. Click 换一张 to refresh the captcha via `evaluate`
+2. Wait 2 seconds for the new image
+3. Repeat steps 3-6 (screenshot → recognize → submit)
+
+After 3 failed rounds: ask the user to solve the captcha manually once in the browser, then resume — once verified, the browser remembers the state and subsequent queries skip the captcha.
+
+## Known Limitations
+
+- **Very short captcha TTL**: screenshot-to-submit must stay under ~15 s — **use ddddocr locally (~100 ms); cloud OCR (10-30 s round trips) always times out**
+- **CDP screenshot required**: the WebBridge screenshot action fails intermittently here; use CDP `Page.captureScreenshot` with clip
+- **Verification caching**: once passed, subsequent searches (navigating to new keyword URLs) return results without another captcha
+- **CORS**: `fetch+FileReader` or `canvas.toDataURL` cannot capture the image (cross-origin taint) — CDP screenshots only
+- **Keyword advice**: exact full names may return "no data" (the database only covers entities with credit records) — try the full name first, then the short name
+
+## Troubleshooting
+
+| Problem | Cause | Fix |
+|---|---|---|
+| 412 on direct HTTP | WAF blocks non-browser calls | always go through WebBridge |
+| Captcha overlay missing | keyword param not triggered | check the keyword in the URL |
+| Empty CDP screenshot | wrong coordinates / scrolled page | re-read `vcodeimg` bounding rect |
+| ddddocr returns empty | broken image / recognition failure | refresh and retry; confirm screenshot bytes > 3000 |
+| Wrong/expired captcha | misread / timeout | refresh (up to 3 rounds); fall back to manual |
+| "没有找到您搜索的数据" | no credit records / keyword mismatch | retry with the short name |
diff --git a/skills/creditchina-query/SKILL.zh-CN.md b/skills/creditchina-query/SKILL.zh-CN.md
new file mode 100644
index 0000000..3856226
--- /dev/null
+++ b/skills/creditchina-query/SKILL.zh-CN.md
@@ -0,0 +1,229 @@
+# 信用中国查询
+
+## L0
+
+输入企业名称,通过 Kimi WebBridge 浏览器自动化 + ddddocr 本地 OCR 自动过图形验证码,返回企业信用信息。
+
+## L1 概述
+
+- **数据源**:信用中国(`creditchina.gov.cn`,国家发改委指导)
+- **认证**:图形验证码(ddddocr 本地 OCR 自动识别,~100ms)
+- **调用方式**:Kimi WebBridge + CDP 截图 + ddddocr Python OCR
+- **前置条件**:
+ - Kimi WebBridge daemon 运行中
+ - Python 已安装 `ddddocr`(`pip install ddddocr`)
+ - Python 已安装 `Pillow`(`pip install pillow`)
+
+## L2 操作步骤
+
+### 1. 导航搜索页
+
+写入 `C:\tmp\cc-nav.json`:
+
+```json
+{
+ "action": "navigate",
+ "args": {
+ "url": "https://www.creditchina.gov.cn/xinyongxinxi/?keyword={企业名称URL编码}&scenesVal=default&tableName=credit_xyzx_tyshxydm",
+ "newTab": true,
+ "group_title": "信用中国查询"
+ },
+ "session": "creditchina-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cc-nav.json" --max-time 30
+```
+
+等待 6 秒。
+
+### 2. 确认验证码弹层
+
+写入 `C:\tmp\cc-check.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var v=document.getElementById('vcode');var i=document.getElementById('vcodeimg');return JSON.stringify({vcode:v?v.getBoundingClientRect().width>0:false,vimg:i?i.getBoundingClientRect().width>0:false});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+若 `vcode=true` 且 `vimg=true`,验证码弹层已出现,继续下一步。
+
+### 3. 获取验证码图坐标
+
+写入 `C:\tmp\cc-coord.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var img=document.getElementById('vcodeimg');if(!img)return 'no-img';var r=img.getBoundingClientRect();return JSON.stringify({x:Math.round(r.x),y:Math.round(r.y),w:Math.round(r.width),h:Math.round(r.height),dpr:window.devicePixelRatio});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+记录返回的 `x` / `y` / `w` / `h`。
+
+### 4. CDP 截图验证码区域
+
+> **注意**:WebBridge 的 screenshot 工具对此页面存在间歇性失败(HTTP 000/400),**必须用 CDP `Page.captureScreenshot` 的 clip 参数**。
+
+写入 `C:\tmp\cc-shot.json`(替换 `{x}` / `{y}` / `{w}` / `{h}` 为上一步返回值):
+
+```json
+{
+ "action": "cdp",
+ "args": {
+ "method": "Page.captureScreenshot",
+ "params": {
+ "format": "png",
+ "clip": { "x": {x}, "y": {y}, "width": {w}, "height": {h}, "scale": 1 }
+ }
+ },
+ "session": "creditchina-query"
+}
+```
+
+```bash
+curl.exe -s -X POST "http://127.0.0.1:10086/command" \
+ -H "Content-Type: application/json" \
+ --data-binary "@C:\tmp\cc-shot.json" --max-time 40 -o "C:/tmp/cc-cdp-resp.json"
+```
+
+解码 base64 并保存为图片:
+
+```python
+import json, base64
+d = json.load(open(r'C:\tmp\cc-cdp-resp.json', encoding='utf-8'))
+b64 = d.get('data', {}).get('data', '')
+open(r'C:\tmp\cc-captcha.png', 'wb').write(base64.b64decode(b64))
+```
+
+### 5. ddddocr 识别(~100ms)
+
+```python
+import ddddocr, sys, time
+sys.stdout.reconfigure(encoding='utf-8')
+ocr = ddddocr.DdddOcr(show_ad=False)
+t0 = time.time()
+with open(r'C:\tmp\cc-captcha.png', 'rb') as f:
+ code = ocr.classification(f.read())
+print(f'验证码: {code} ({(time.time()-t0)*1000:.0f}ms)')
+open(r'C:\tmp\cc-code.txt', 'w').write(code)
+```
+
+### 6. 填入验证码 + 点击验证
+
+写入 `C:\tmp\cc-submit.json`(替换 `{code}` 为识别结果):
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var inp=document.getElementById('vcode');if(!inp)return 'no-input';var s=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;s.call(inp,'{code}');inp.dispatchEvent(new Event('input',{bubbles:true}));inp.dispatchEvent(new Event('change',{bubbles:true}));for(var el of document.querySelectorAll('button, a, input[type=button]')){if((el.innerText||el.value||'').trim()==='验证'){el.click();break;}}return 'submitted';})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+等待 5 秒。
+
+### 7. 检查验证结果
+
+写入 `C:\tmp\cc-result.json`:
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){var t=document.body.innerText||'';if(t.includes('验证码错误'))return '验证码错误';if(t.includes('失效'))return '验证码已失效';return JSON.stringify({hasResult:t.includes('共')||t.includes('条'),textSample:t.slice(0,500)});})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+**三种结果**:
+
+- `"验证码错误"` / `"验证码已失效"` → 返回步骤 3 重试(点"换一张"刷新验证码)
+- `hasResult=true` 且返回搜索数据 → 成功,继续步骤 8
+- `textSample` 含"很抱歉,没有找到您搜索的数据" → 验证码已通过,但搜索词无匹配(非技术错误)——建议换企业全名或简称重试
+
+### 8. 读取搜索结果
+
+```json
+{
+ "action": "evaluate",
+ "args": {
+ "code": "(function(){return document.body.innerText.slice(0,1500);})()"
+ },
+ "session": "creditchina-query"
+}
+```
+
+### 9. 标准化映射
+
+```json
+{
+ "query_status": "success",
+ "source": "creditchina",
+ "company_name": "{企业名称}",
+ "captcha_solved": true,
+ "search_result": "有结果 | 无匹配",
+ "credit_info": [
+ {
+ "event_type": "行政处罚 | 行政许可 | 失信被执行 | 守信激励",
+ "event_title": "...",
+ "event_date": "...",
+ "source_url": "...",
+ "summary": "..."
+ }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 10. 关闭会话
+
+```json
+{
+ "action": "close_session",
+ "session": "creditchina-query"
+}
+```
+
+## 重试策略
+
+验证码识别失败(错误/失效)时自动重试,最多 3 轮:
+
+1. 点击"换一张"刷新验证码:`evaluate` 点击文本含"换一张"的元素
+2. 等 2 秒(新图加载)
+3. 重复步骤 3-6(重新截图→识别→提交)
+
+3 轮失败后:报告用户,请人工在浏览器中手动过一次验证码,然后智能体接管继续(验证通过后浏览器记住验证态,后续查询免验证码)。
+
+## 已知限制
+
+- **验证码时效极短**:从截图到提交需 <15 秒——**必须用 ddddocr 本地识别(~100ms),禁用云端 OCR(10~30 秒往返必超时)**
+- **CDP 截图替代 screenshot**:WebBridge screenshot 工具对此页面间歇性失败(HTTP 000/400),必须用 CDP `Page.captureScreenshot` 的 clip 参数
+- **验证态缓存**:一次验证通过后,浏览器记住验证态——后续搜索(导航到新 keyword URL)不再需要验证码,直接返回结果
+- **CORS 限制**:不能通过 `fetch+FileReader` 或 `canvas.toDataURL` 取图(跨子域 tainted)——只能用 CDP 截图
+- **搜索词建议**:精确企业全名可能"没有找到您搜索的数据"(信用库只收录有信用记录的主体)——先试全名,无结果再试简称
+
+## 故障排查
+
+| 问题 | 原因 | 处理 |
+|---|---|---|
+| 412(直连被 WAF 拦截) | 未用浏览器 | 必须通过 WebBridge 浏览器访问 |
+| 验证码弹层未出现 | keyword 参数未触发 | 检查 URL 中的 keyword 参数 |
+| CDP 截图返回空 | 坐标错误 / 页面滚动 | 重新获取 vcodeimg 的 getBoundingClientRect |
+| ddddocr 识别为空 | 图片损坏 / 识别失败 | 刷新验证码重试;确认 CDP 截图 bytes > 3000 |
+| 验证码错误/失效 | 识别错 / 超时 | 点"换一张"重试(最多 3 轮);仍失败转人工 |
+| "没有找到您搜索的数据" | 企业无信用记录 / 词不匹配 | 换简称重试;确认企业有信用记录 |
diff --git a/skills/creditchina-query/catalog-metadata.v1.json b/skills/creditchina-query/catalog-metadata.v1.json
new file mode 100644
index 0000000..170904f
--- /dev/null
+++ b/skills/creditchina-query/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "creditchina-query"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "信用中国查询",
+ "summary": "浏览器自动化 + ddddocr 本地过验证码,返回企业信用信息",
+ "description": "信用中国企业信用信息查询——输入企业名称,自动通过图形验证码(ddddocr 本地 OCR 100ms),返回信用信息(行政处罚/失信被执行/行政许可)。Use when 用户提到\"查信用\"、\"信用中国\"、\"行政处罚\"、\"失信企业\"、\"企业信用\"、\"失信被执行人\"、\"行政许可\"、\"creditchina\"。"
+ },
+ "en-US": {
+ "name": "Credit China Query",
+ "summary": "Browser automation with local ddddocr captcha solving for enterprise credit records",
+ "description": "Credit China (creditchina.gov.cn) enterprise credit query — input a company name, automatically pass the graphic captcha (ddddocr local OCR, ~100 ms), and return credit records (administrative penalties / dishonest debtors / administrative licenses). Use when the user asks about enterprise credit, administrative penalties, dishonest-debtor lists, or creditchina."
+ }
+ },
+ "category": "business",
+ "tags": [
+ "due-diligence",
+ "credit",
+ "creditchina",
+ "compliance"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "high"
+ }
+}
diff --git a/skills/multi-source-sentiment/SKILL.md b/skills/multi-source-sentiment/SKILL.md
new file mode 100644
index 0000000..5a36fc9
--- /dev/null
+++ b/skills/multi-source-sentiment/SKILL.md
@@ -0,0 +1,229 @@
+---
+name: multi-source-sentiment
+description: >-
+ 企业尽调舆情采集——通过抖音指数、抖音精选、WebSearch 三大数据源采集企业舆情,分析负面风险(诉讼/处罚/质量/高管/劳资),输出尽调舆情报告。Use when 用户提到"查舆情"、"企业舆情"、"负面新闻"、"舆论风险"、"尽调舆情"、"企业口碑"、"舆情分析"、"网络口碑"。
+version: 1.0.0
+type: procedural
+risk_level: medium
+status: enabled
+tags:
+ - due-diligence
+ - sentiment
+ - public-opinion
+ - douyin
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 企业尽调舆情采集
+ short_desc: 抖音指数+抖音精选+WebSearch 三渠道采集,输出尽调舆情报告
+ description: >-
+ 企业尽调舆情采集——通过抖音指数、抖音精选、WebSearch 三大数据源采集企业舆情,分析负面风险(诉讼/处罚/质量/高管/劳资),输出尽调舆情报告。Use when 用户提到"查舆情"、"企业舆情"、"负面新闻"、"舆论风险"、"尽调舆情"、"企业口碑"、"舆情分析"、"网络口碑"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:e102f3139e03fcd5
+ translated_by: human
+ en-US:
+ name: Multi-Source Sentiment
+ short_desc: Due-diligence sentiment via Douyin Index, Douyin Featured, and WebSearch
+ description: >-
+ Due-diligence sentiment collection — gather enterprise public opinion via three channels (Douyin Index, Douyin Featured, WebSearch), analyze negative risks (litigation / penalties / quality / executives / labor), and output a due-diligence sentiment report. Use when the user asks about enterprise sentiment, negative news, reputation risk, or public opinion.
+ body: ./SKILL.md
+ source_hash: sha256:e102f3139e03fcd5
+ translated_by: human
+market:
+ icon: >-
+
+ category: research
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# Multi-Source Sentiment (Due Diligence)
+
+## L0: One-Sentence Summary
+
+Input a company name, collect public opinion via Douyin Index (trend) + Douyin Featured (negative material) + WebSearch (web-wide news), and output a due-diligence sentiment report (negative-risk list / positive highlights / sentiment overview / overall judgment).
+
+## L1: Overview
+
+- **Purpose**: answer the core due-diligence questions — any negative publicity? litigation/penalty coverage? product-quality issues? executive misconduct? overall reputation?
+- **Channel split**:
+
+| Channel | Due-diligence use | Collection |
+|---|---|---|
+| **Douyin Index** | Quantified heat trend (is something fermenting recently?) | Kimi WebBridge visiting Oceanengine Trends |
+| **Douyin Featured** | Concrete negative material (complaint/expose videos) | Kimi WebBridge searching Douyin |
+| **WebSearch** | Web-wide negative news / court notices / penalties / complaints | DesireCore built-in WebSearch |
+
+- **Prerequisites**: Kimi WebBridge daemon running (`127.0.0.1:10086`) + browser extension connected
+
+## L2: Procedure
+
+### Source 1: Douyin Index (heat trend)
+
+#### Access Method
+
+```
+URL: https://trendinsight.oceanengine.com/arithmetic-index/analysis/keyword?keyword={company-short-name}&appName=aweme
+Method: Kimi WebBridge opens the URL and extracts page content
+Note: URL-parameterized access avoids captchas. Do not type into the search box.
+```
+
+#### Keyword Strategy
+
+| Dimension | Keyword |
+|---|---|
+| Overall heat | `{short name}` |
+| Negative heat | `{short name} 负面` |
+| Complaint heat | `{short name} 投诉` |
+
+#### Interpretation
+
+- **Sudden spike** (MoM > 200%) → a negative event may be fermenting; investigate
+- **Flat trend** → low reputation risk
+- **Persistently high** → normal for famous companies; judge by content
+
+### Source 2: Douyin Featured (negative material)
+
+#### Access Method
+
+```
+URL: https://www.douyin.com/search/{company-short-name}?type=video
+Method: Kimi WebBridge searches Douyin, extracts title / author / likes / comments
+Note: search by short name (full names rarely hit); prioritize high-engagement videos.
+```
+
+#### Collected Fields
+
+Collected fields: video title (negative signals: complaint / rights-protection / exposure / quality / scam / runaway), likes & comments (reach = impact), author (personal vent vs media report vs competitor smear), publish date (recent vs historical).
+
+#### Signal Grading
+
+| Signals | Risk |
+|---|---|
+| 投诉 / 维权 / 欺骗 / 诈骗 / 跑路 | 🔴 high |
+| 质量 / 召回 / 不合格 / 假货 | 🔴 high |
+| 欠薪 / 辞退 / 仲裁 | 🟡 medium |
+| 吐槽 / 差评 / 不满 | 🟡 medium |
+| positive / awards / innovation | 🟢 positive |
+
+### Source 3: WebSearch (web-wide)
+
+#### Search Keyword Groups
+
+```python
+# High priority (always)
+search_queries_high = [
+ "{company} 负面 OR 投诉 OR 维权 OR 欺骗 OR 跑路",
+ "{company} 起诉 OR 法院 OR 被告 OR 被执行 OR 失信",
+ "{company} 处罚 OR 违规 OR 罚款 OR 整改 OR 通报批评",
+]
+
+# Medium priority (recommended)
+search_queries_mid = [
+ "{company} 质量 OR 召回 OR 不合格 OR 安全事故",
+ "{company} 老板 OR 法人 OR 总经理 丑闻 OR 被查 OR 被抓",
+ "{company} 欠薪 OR 辞退 OR 劳动仲裁 OR 工伤",
+]
+
+# Low priority (positive control)
+search_queries_low = [
+ "{company} 获奖 OR 创新 OR 认定 OR 排名",
+]
+```
+
+#### Collected Fields
+
+Collected fields: title / source site / date / summary / URL. **Note**: distinguish the company as **plaintiff** (enforcement, not a negative signal) vs **defendant** (negative signal).
+
+### Step 1: Run the three channels
+
+1. **WebSearch** first (highest information density): run high/medium/low query groups and collect results
+2. **Douyin Index**: check the heat trend for signs of recent fermentation
+3. **Douyin Featured**: search videos and filter by negative signal words
+
+### Step 2: LLM post-processing
+
+| Step | Description |
+|---|---|
+| Sentiment classification | tag each item positive / neutral / negative |
+| Risk grading | negative → high (defendant / penalty / runaway / safety accident) / medium (complaints / quality gripes / labor) / low (generic bad reviews) |
+| Event merging | merge duplicate coverage of one event (keep the earliest) |
+| Plaintiff/defendant split | litigation where the company is plaintiff is **not** a negative risk |
+| Recency | mark "recent" (≤3 months) vs "historical" |
+
+### Step 3: Output the report
+
+```json
+{
+ "query_status": "success",
+ "source": "multi-source-sentiment",
+ "company_name": "{company}",
+ "sentiment_overview": {
+ "overall_assessment": "正面 | 中性偏正 | 中性 | 中性偏负 | 负面 | 高风险",
+ "negative_ratio": "15%",
+ "neutral_ratio": "60%",
+ "positive_ratio": "25%",
+ "trend": "稳定 | 近期发酵 | 持续负面"
+ },
+ "negative_risks": [
+ {
+ "risk_type": "诉讼报道(被告) | 行政处罚 | 产品质量 | 高管负面 | 劳资纠纷 | 消费者投诉 | 经营异常",
+ "event_title": "……",
+ "event_date": "YYYY-MM-DD",
+ "recency": "近期 | 历史",
+ "source_url": "https://……",
+ "severity": "高 | 中 | 低",
+ "summary": "1-2 sentence summary"
+ }
+ ],
+ "controversies": [],
+ "positive_highlights": [],
+ "sentiment_summary": "3-5 sentence judgment: overall reputation, main negatives and severity, fermentation status, due-diligence advice",
+ "data_sources_used": ["websearch", "douyin-index", "douyin-featured"],
+ "collection_time": "ISO8601"
+}
+```
+
+## Quality Standards
+
+- **Authenticity**: all content must come from actual collection (WebSearch results / Douyin pages); never fabricate
+- **Traceability**: every negative risk carries a source_url
+- **Plaintiff/defendant**: litigation where the company is plaintiff goes to "litigation updates", not negative risks
+- **Recency**: every negative item is marked recent (≤3 months) or historical
+- **No absolute conclusions**: sentiment is one auxiliary signal; the report must note it should be combined with business-registration, judicial, and financial data
+
+## Error Handling
+
+| Scenario | Handling |
+|---|---|
+| Douyin Index unreachable | skip; supplement with WebSearch + Featured; note "heat data missing" in the report |
+| Douyin search requires login | skip; WebSearch `{company} 抖音 负面` instead |
+| WebSearch returns nothing | mark "no negative found" — a positive signal |
+| Too many negatives | keep the top 10 by severity; count the rest |
+
+## Known Limitations
+
+- **Not real-time**: depends on search-engine indexing and Douyin pages; hour-to-day latency (7×24 monitoring requires commercial sentiment APIs)
+- **LLM-based sentiment**: no dedicated sentiment model; ~85-90% accuracy, edge cases may misjudge
+- **Douyin coverage**: WeChat/Weibo/Xiaohongshu content is only covered indirectly via WebSearch
+- **Full vs short name**: WebSearch uses the full name (precision), Douyin the short name (recall); results may differ
+
+## Troubleshooting
+
+| Problem | Cause | Fix |
+|---|---|---|
+| WebBridge daemon unreachable | daemon down | `~/.kimi-webbridge/bin/kimi-webbridge.exe start` |
+| Trends page blank | JS not rendered | wait 5 s, then evaluate innerText |
+| Douyin search empty | login required / name mismatch | skip; supplement via WebSearch |
+| WebSearch results all positive | weak negative keywords | use concrete terms (e.g. "被处罚" instead of "处罚") |
diff --git a/skills/multi-source-sentiment/SKILL.zh-CN.md b/skills/multi-source-sentiment/SKILL.zh-CN.md
new file mode 100644
index 0000000..e8a230b
--- /dev/null
+++ b/skills/multi-source-sentiment/SKILL.zh-CN.md
@@ -0,0 +1,193 @@
+# 企业尽调舆情采集
+
+## L0
+
+输入企业名称,通过抖音指数(热度趋势)+ 抖音精选(负面素材)+ WebSearch(全网新闻)三渠道采集舆情,输出尽调舆情报告(负面风险清单/正面亮点/情感概览/综合判断)。
+
+## L1 概述
+
+- **目的**:回答尽调核心问题——有没有负面舆情?有没有诉讼/处罚报道?产品质量有没有问题?高管有没有负面?舆论形象如何?
+- **三渠道分工**:
+
+| 渠道 | 尽调用途 | 采集方式 |
+|---|---|---|
+| **抖音指数** | 舆论热度量化(时间序列,看是否近期发酵) | Kimi WebBridge 访问巨量算数 |
+| **抖音精选** | 具体负面内容素材(投诉视频/维权曝光/质量吐槽) | Kimi WebBridge 搜索抖音 |
+| **WebSearch** | 全网负面新闻/法院公告/监管处罚/消费者投诉 | DesireCore 内置 WebSearch |
+
+- **前置依赖**:Kimi WebBridge daemon 运行中(`127.0.0.1:10086`)+ 浏览器扩展已连接
+
+## L2 详细操作
+
+### 数据源一:抖音指数(企业名热度趋势)
+
+#### 访问方式
+
+```
+URL: https://trendinsight.oceanengine.com/arithmetic-index/analysis/keyword?keyword={企业简称}&appName=aweme
+方法: Kimi WebBridge 浏览器自动访问页面并提取内容
+注意: URL 参数化访问,不触发验证码。不要尝试在搜索框输入文字。
+```
+
+#### 尽调关键词策略
+
+| 尽调维度 | 搜索关键词 |
+|---|---|
+| 舆论整体热度 | `{企业简称}` |
+| 负面热度 | `{企业简称} 负面` |
+| 投诉热度 | `{企业简称} 投诉` |
+
+#### 尽调判断要点
+
+- **热度骤升**:近期热度陡增(环比 >200%)→ 可能存在负面事件发酵,需重点排查
+- **热度平稳**:无异常波动 → 舆论风险较低
+- **长期高热**:知名企业的常态,需结合内容素材判断正负
+
+### 数据源二:抖音精选(负面内容素材)
+
+#### 访问方式
+
+```
+URL: https://www.douyin.com/search/{企业简称}?type=video
+方法: Kimi WebBridge 搜索抖音,提取视频标题/作者/点赞数/评论数
+注意: 用企业简称搜索(全名命中率低);优先看点赞/评论高的视频(传播广=影响大)。
+```
+
+#### 尽调采集字段
+
+- 视频标题(判断是否负面:投诉/维权/曝光/质量/欺骗/跑路)
+- 点赞数 / 评论数(传播广度 = 负面影响程度)
+- 作者昵称(个人吐槽 vs 媒体报道 vs 竞品抹黑)
+- 发布时间(近期 vs 历史)
+
+#### 负面视频筛选标准
+
+| 信号词 | 风险等级 |
+|---|---|
+| 投诉 / 维权 / 欺骗 / 诈骗 / 跑路 | 🔴 高 |
+| 质量 / 召回 / 不合格 / 假货 | 🔴 高 |
+| 欠薪 / 辞退 / 仲裁 | 🟡 中 |
+| 吐槽 / 差评 / 不满 | 🟡 中 |
+| 正面宣传 / 获奖 / 创新 | 🟢 正面 |
+
+### 数据源三:WebSearch(全网尽调舆情)
+
+#### 搜索关键词组合(按尽调维度)
+
+```python
+# 高优先级(必查)
+search_queries_high = [
+ "{企业名} 负面 OR 投诉 OR 维权 OR 欺骗 OR 跑路",
+ "{企业名} 起诉 OR 法院 OR 被告 OR 被执行 OR 失信",
+ "{企业名} 处罚 OR 违规 OR 罚款 OR 整改 OR 通报批评",
+]
+
+# 中优先级(建议查)
+search_queries_mid = [
+ "{企业名} 质量 OR 召回 OR 不合格 OR 安全事故",
+ "{企业名} 老板 OR 法人 OR 总经理 丑闻 OR 被查 OR 被抓",
+ "{企业名} 欠薪 OR 辞退 OR 劳动仲裁 OR 工伤",
+]
+
+# 低优先级(正面对照)
+search_queries_low = [
+ "{企业名} 获奖 OR 创新 OR 认定 OR 排名",
+]
+```
+
+#### 采集字段
+
+- 新闻标题 / 来源网站 / 发布时间 / 摘要 / 原文链接
+- **注意**:区分企业作为**原告**(维权,非负面信号)vs **被告**(被诉,负面信号)
+
+### Step 1:三渠道采集执行
+
+1. **WebSearch 尽调搜索**(先执行,信息量最大):按高/中/低优先级逐组搜索,收集新闻标题+来源+日期+摘要
+2. **抖音指数热度**:访问巨量算数查企业简称热度趋势,判断是否近期发酵
+3. **抖音精选内容**:搜索抖音视频,按负面信号词筛选高互动视频
+
+### Step 2:LLM 后处理(情感分析 + 风险分级)
+
+对采集到的原始内容执行:
+
+| 分析步骤 | 说明 |
+|---|---|
+| **情感分类** | 每条标注:正面 / 中性 / 负面 |
+| **风险分级** | 负面内容分:高(诉讼被告/处罚/跑路/安全事故)/ 中(投诉/质量吐槽/劳资)/ 低(一般差评) |
+| **事件归并** | 同一事件的多条报道归并为一条(以最早报道为准) |
+| **原被告区分** | 企业作为原告的维权诉讼**不是**负面风险信号 |
+| **时效判断** | 近 3 个月的负面标记"近期",更早的标记"历史" |
+
+### Step 3:输出尽调舆情报告
+
+```json
+{
+ "query_status": "success",
+ "source": "multi-source-sentiment",
+ "company_name": "{企业名}",
+ "sentiment_overview": {
+ "overall_assessment": "正面 | 中性偏正 | 中性 | 中性偏负 | 负面 | 高风险",
+ "negative_ratio": "15%",
+ "neutral_ratio": "60%",
+ "positive_ratio": "25%",
+ "trend": "稳定 | 近期发酵 | 持续负面"
+ },
+ "negative_risks": [
+ {
+ "risk_type": "诉讼报道(被告) | 行政处罚 | 产品质量 | 高管负面 | 劳资纠纷 | 消费者投诉 | 经营异常",
+ "event_title": "……",
+ "event_date": "YYYY-MM-DD",
+ "recency": "近期 | 历史",
+ "source_url": "https://……",
+ "severity": "高 | 中 | 低",
+ "summary": "1-2 句事件摘要"
+ }
+ ],
+ "controversies": [
+ {
+ "event_title": "……",
+ "description": "争议双方与焦点",
+ "status": "发酵中 | 已平息 | 官方已回应"
+ }
+ ],
+ "positive_highlights": [
+ "获奖/创新/贡献等正面事件(一句话)"
+ ],
+ "sentiment_summary": "3-5 句舆情综合判断:整体舆论形象、主要负面及严重程度、是否近期发酵、尽调建议",
+ "data_sources_used": ["websearch", "douyin-index", "douyin-featured"],
+ "collection_time": "ISO8601"
+}
+```
+
+## 质量标准
+
+- **数据真实性**:所有舆情内容必须来自实际采集(WebSearch 结果 / 抖音页面),绝不编造
+- **来源可溯**:每条负面风险必须附 source_url
+- **原被告区分**:企业作为原告的诉讼报道不列入负面风险(单独归类为"涉诉动态")
+- **时效标注**:每条负面标注"近期"(3 个月内)或"历史"
+- **不做绝对结论**:舆情是辅助信号,报告末尾注明"舆情仅为尽调参考维度之一,需结合工商/司法/财务数据综合判断"
+
+## 错误处理
+
+| 场景 | 处理方式 |
+|---|---|
+| 抖音指数页面无法访问 | 跳过该源,用 WebSearch + 抖音精选补充,报告中注明"热度数据缺失" |
+| 抖音搜索需登录 | 跳过该源,WebSearch 补充搜索 `{企业名} 抖音 负面` |
+| WebSearch 无结果 | 该维度标注"未检索到相关负面",属正面信号 |
+| 负面信息量极大 | 只取前 10 条高严重度条目,其余归入计数 |
+
+## 已知限制
+
+- **非实时**:依赖搜索引擎收录与抖音页面展示,存在小时级~天级延迟(非 7×24 实时监测——持续监测需商业舆情 API)
+- **情感分析靠 LLM**:无专用情感模型,由 LLM 后处理推断(准确率约 85-90%,边界案例可能误判)
+- **抖音覆盖**:微信公众号/微博/小红书等平台内容仅能通过 WebSearch 间接覆盖(非全平台直达)
+- **企业全名 vs 简称**:WebSearch 用全名(精确),抖音用简称(命中率);两者结果可能有差异
+
+## 故障排查
+
+| 问题 | 原因 | 处理 |
+|---|---|---|
+| WebBridge daemon 不可达 | daemon 未运行 | `~/.kimi-webbridge/bin/kimi-webbridge.exe start` |
+| 巨量算数页面空白 | JS 渲染未完成 | 等 5 秒后 evaluate 读 innerText |
+| 抖音搜索页无结果 | 需登录 / 简称不匹配 | 跳过,WebSearch 补充 |
+| WebSearch 结果全是正面 | 负面词组合不当 | 换用具体负面词(如"被处罚"而非"处罚") |
diff --git a/skills/multi-source-sentiment/catalog-metadata.v1.json b/skills/multi-source-sentiment/catalog-metadata.v1.json
new file mode 100644
index 0000000..d5eed4a
--- /dev/null
+++ b/skills/multi-source-sentiment/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "multi-source-sentiment"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "企业尽调舆情采集",
+ "summary": "抖音指数+抖音精选+WebSearch 三渠道采集,输出尽调舆情报告",
+ "description": "企业尽调舆情采集——通过抖音指数、抖音精选、WebSearch 三大数据源采集企业舆情,分析负面风险(诉讼/处罚/质量/高管/劳资),输出尽调舆情报告。Use when 用户提到\"查舆情\"、\"企业舆情\"、\"负面新闻\"、\"舆论风险\"、\"尽调舆情\"、\"企业口碑\"、\"舆情分析\"、\"网络口碑\"。"
+ },
+ "en-US": {
+ "name": "Multi-Source Sentiment",
+ "summary": "Due-diligence sentiment via Douyin Index, Douyin Featured, and WebSearch",
+ "description": "Due-diligence sentiment collection — gather enterprise public opinion via three channels (Douyin Index, Douyin Featured, WebSearch), analyze negative risks (litigation / penalties / quality / executives / labor), and output a due-diligence sentiment report. Use when the user asks about enterprise sentiment, negative news, reputation risk, or public opinion."
+ }
+ },
+ "category": "research",
+ "tags": [
+ "due-diligence",
+ "sentiment",
+ "public-opinion",
+ "douyin"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "medium"
+ }
+}
diff --git a/skills/tianyancha-risk/SKILL.md b/skills/tianyancha-risk/SKILL.md
new file mode 100644
index 0000000..3f96eb6
--- /dev/null
+++ b/skills/tianyancha-risk/SKILL.md
@@ -0,0 +1,154 @@
+---
+name: tianyancha-risk
+description: >-
+ 天眼查企业风险查询——输入企业名称,返回风险画像(自身风险/周边风险/历史风险/预警提醒,含分类统计与明细)。Use when 用户提到"查风险"、"企业风险"、"风险画像"、"司法风险"、"经营风险"、"开庭公告"、"裁判文书"、"被执行人"、"天眼查"。
+version: 1.0.0
+type: procedural
+risk_level: low
+status: enabled
+tags:
+ - due-diligence
+ - risk
+ - tianyancha
+ - corporate
+metadata:
+ author: desirecore
+ updated_at: '2026-09-03'
+ i18n:
+ default_locale: en-US
+ source_locale: zh-CN
+ locales:
+ - zh-CN
+ - en-US
+ zh-CN:
+ name: 天眼查企业风险查询
+ short_desc: 输入企业名称,返回自身/周边/历史/预警四类风险画像
+ description: >-
+ 天眼查企业风险查询——输入企业名称,返回风险画像(自身风险/周边风险/历史风险/预警提醒,含分类统计与明细)。Use when 用户提到"查风险"、"企业风险"、"风险画像"、"司法风险"、"经营风险"、"开庭公告"、"裁判文书"、"被执行人"、"天眼查"。
+ body: ./SKILL.zh-CN.md
+ source_hash: sha256:b58091c7ef9e968e
+ translated_by: human
+ en-US:
+ name: Tianyancha Risk Query
+ short_desc: Enterprise risk profile by company name — self/related/historical/warning risk
+ description: >-
+ Tianyancha enterprise risk query — input a company name and return a structured risk profile (self risk / related-party risk / historical risk / early warnings, with category counts and details). Use when the user asks about enterprise risk, judicial risk, litigation announcements, court rulings, dishonest debtors, or Tianyancha.
+ body: ./SKILL.md
+ source_hash: sha256:b58091c7ef9e968e
+ translated_by: human
+market:
+ icon: >-
+
+ category: business
+ maintainer:
+ name: DesireCore Official
+ verified: true
+ compatible_agents: []
+ channel: latest
+ required_client_version: 10.0.115
+---
+
+# Tianyancha Risk Query
+
+## L0: One-Sentence Summary
+
+Input a company name, call the Tianyancha risk-info API, and return a structured risk profile (self / related-party / historical / warning, four categories).
+
+## L1: Overview
+
+- **Data source**: Tianyancha Open Platform `risk/riskInfo/2.0`
+- **Auth**: Token (`Authorization` header, **without** the `Bearer` prefix)
+- **Invocation**: HTTP GET (curl / HttpRequest tool)
+- **Prerequisites**: a valid Token with the risk API enabled
+
+## Credential Setup
+
+This skill requires a Tianyancha Open Platform Token:
+
+1. Register an enterprise account at the [Tianyancha Open Platform](https://open.tianyancha.com/)
+2. Purchase/enable an API package (`risk/riskInfo/2.0` is authorized per package tier)
+3. Export the token as the environment variable `TIANYANCHA_TOKEN`, or replace the `{TIANYANCHA_TOKEN}` placeholder below
+
+## L2: Procedure
+
+### 1. Build the request
+
+```bash
+curl -s --max-time 30 --ssl-no-revoke \
+ "https://open.api.tianyancha.com/services/open/risk/riskInfo/2.0?keyword={company-name-URL-encoded}" \
+ -H "Authorization: ${TIANYANCHA_TOKEN}"
+```
+
+**Parameters**:
+
+| Param | Value | Notes |
+|---|---|---|
+| keyword | Company name (URL-encoded) | e.g. `华为技术有限公司` |
+| Authorization | `{TIANYANCHA_TOKEN}` | **Token in header, no `Bearer` prefix** (adding one returns 300009) |
+
+### 2. Interpret the response
+
+- `error_code == 0` and `reason == "ok"`: success, extract `result.riskList[]`
+- `error_code == 300009`: account error — wrong token or a `Bearer` prefix was added
+- `error_code == 300005`: no permission for this API — the token does not cover it
+- `error_code == 300008`: missing parameter — check keyword
+
+### 3. Response structure
+
+`result` contains:
+
+- `riskLevel`: overall risk level
+- `riskList[]`: four risk categories (each with name / count / type / list[])
+
+| Category | type | Meaning |
+|---|---|---|
+| Self risk | 1 | The company's own judicial/business risks (court hearings / rulings / case filings / court announcements / judicial auctions) |
+| Related-party risk | 2 | Risks of shareholders, executives, invested companies |
+| Historical risk | 3 | Closed historical risks (historical filings / hearings / dishonest-debtor history) |
+| Early warnings | 0 | Business-registration changes (investor / key-personnel / registered-capital / legal-representative changes, bankruptcy cases) |
+
+Each category's `list[]` holds sub-items with `title` (e.g. "开庭公告") / `total` / `tag` (warning / high-risk / info) / `list[]` (top details with id / title / desc / riskCount).
+
+### 4. Normalized mapping
+
+```json
+{
+ "query_status": "success",
+ "source": "tianyancha",
+ "company_name": "{company name}",
+ "risk_level": "{result.riskLevel}",
+ "summary": {
+ "self_risk_count": 3127,
+ "related_risk_count": 1505,
+ "history_risk_count": 9113,
+ "warning_count": 815
+ },
+ "self_risks": [
+ { "risk_type": "开庭公告", "count": 1501, "level": "警示", "title": "该公司起诉他人或公司的开庭公告", "detail_count": 1096 }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 5. Due-diligence highlights
+
+Prioritize as follows when composing the report:
+
+1. **High-risk entries** (tag=高风险): e.g. "被执行人", "清算信息", "失信被执行人" — list as major risk items
+2. **Large warning counts** (total > 100): e.g. 1,501 hearing announcements — list as judicial-activity indicators
+3. **Change warnings**: recent investor / legal-representative / capital changes — list as business dynamics
+
+## Known Limitations
+
+- **Tiered token authorization**: APIs are authorized per package; unauthorized APIs return 300005 — full-dimension packages unlock business/shareholder/IP endpoints
+- **QPS throttling**: rate limits depend on the package; keep ≥1 s between calls
+- **Large responses**: big companies can return 98KB+ — extract summaries plus top-N details to keep context small
+
+## Troubleshooting
+
+| Code | Meaning | Fix |
+|---|---|---|
+| 0 | Success | — |
+| 300005 | No permission for this API | Confirm the endpoint is covered by your package |
+| 300008 | Missing parameter | Check the keyword parameter |
+| 300009 | Account error | Wrong token / Bearer prefix / expired token — remove the prefix and retry; if still failing, update the token |
diff --git a/skills/tianyancha-risk/SKILL.zh-CN.md b/skills/tianyancha-risk/SKILL.zh-CN.md
new file mode 100644
index 0000000..51a1511
--- /dev/null
+++ b/skills/tianyancha-risk/SKILL.zh-CN.md
@@ -0,0 +1,106 @@
+# 天眼查企业风险查询
+
+## L0
+
+输入企业名称,调用天眼查风险信息 API,返回结构化风险画像(自身/周边/历史/预警四类)。
+
+## L1 概述
+
+- **数据源**:天眼查开放平台 `risk/riskInfo/2.0`
+- **认证**:Token(`Authorization` Header,**不带 `Bearer` 前缀**)
+- **调用方式**:HTTP GET(curl / HttpRequest 工具)
+- **前置条件**:Token 有效(需在天眼查开放平台开通对应接口权限)
+
+## 凭证获取
+
+本技能需要天眼查开放平台 Token:
+
+1. 访问 [天眼查开放平台](https://open.tianyancha.com/) 注册企业账号
+2. 购买/开通接口套餐(风险信息接口 `risk/riskInfo/2.0` 按套餐分级授权)
+3. 将 Token 配置为环境变量 `TIANYANCHA_TOKEN`,或替换下文命令中的 `{TIANYANCHA_TOKEN}` 占位符
+
+## L2 操作步骤
+
+### 1. 构造请求
+
+```bash
+curl -s --max-time 30 --ssl-no-revoke \
+ "https://open.api.tianyancha.com/services/open/risk/riskInfo/2.0?keyword={企业名称URL编码}" \
+ -H "Authorization: ${TIANYANCHA_TOKEN}"
+```
+
+**参数说明**:
+
+| 参数 | 值 | 说明 |
+|---|---|---|
+| keyword | 企业名称(URL 编码) | 如"华为技术有限公司" |
+| Authorization | `{TIANYANCHA_TOKEN}` | **Header 传 Token,不带 `Bearer` 前缀**(带前缀返回 300009) |
+
+### 2. 判断响应
+
+- `error_code == 0` 且 `reason == "ok"`:成功,提取 `result.riskList[]`
+- `error_code == 300009`:账号信息有误——Token 错误或加了 Bearer 前缀
+- `error_code == 300005`:无权限访问此 API——当前 Token 未授权该接口
+- `error_code == 300008`:缺少必要参数——检查 keyword
+
+### 3. 响应结构解析
+
+`result` 包含两个字段:
+
+- `riskLevel`:整体风险等级
+- `riskList[]`:四类风险(每类含 name / count / type / list[])
+
+四类风险:
+
+| 类型 | type | 含义 |
+|---|---|---|
+| 自身风险 | 1 | 该企业自身的司法/经营风险(开庭公告/裁判文书/立案信息/法院公告/司法拍卖等) |
+| 周边风险 | 2 | 关联方(股东/高管/投资企业)的风险 |
+| 历史风险 | 3 | 已了结的历史风险(历史立案/历史开庭/被执行人_历史等) |
+| 预警提醒 | 0 | 工商变更提醒(投资人变更/主要人员变更/注册资本变更/法定代表人变更/破产案件等) |
+
+每类下 `list[]` 为子项,每子项含 `title`(如"开庭公告")/ `total`(条数)/ `tag`(警示/高风险/提示信息)/ `list[]`(前几条明细,含 id / title / desc / riskCount)。
+
+### 4. 标准化映射
+
+```json
+{
+ "query_status": "success",
+ "source": "tianyancha",
+ "company_name": "{企业名称}",
+ "risk_level": "{result.riskLevel}",
+ "summary": {
+ "self_risk_count": 3127,
+ "related_risk_count": 1505,
+ "history_risk_count": 9113,
+ "warning_count": 815
+ },
+ "self_risks": [
+ { "risk_type": "开庭公告", "count": 1501, "level": "警示", "title": "该公司起诉他人或公司的开庭公告", "detail_count": 1096 }
+ ],
+ "timestamp": "2026-08-31T21:00:00+08:00"
+}
+```
+
+### 5. 尽调要点提炼
+
+输出报告时按以下优先级提炼:
+
+1. **高风险条目**(tag=高风险):如"被执行人"、"清算信息"、"失信被执行人"——直接列为重大风险项
+2. **警示条目大额计数**(total > 100):如开庭公告 1501 条——列为司法活跃度指标
+3. **预警变更**:近期投资人/法定代表人/注册资本变更——列为经营动态
+
+## 已知限制
+
+- **Token 分级授权**:接口按套餐授权,未授权接口返回 300005——购买全维度套餐后可扩展工商/股权/知产等接口
+- **QPS 限流**:天眼查 API 按套餐有 QPS 限制,连续调用注意间隔(建议 ≥1 秒)
+- **响应体量大**:大企业响应可达 98KB+,解析时注意内存与上下文压缩(只提取汇总+前 N 条明细)
+
+## 故障排查
+
+| 错误码 | 含义 | 处理 |
+|---|---|---|
+| 0 | 成功 | — |
+| 300005 | 无权限访问此 API | 当前 Token 未授权该接口;确认调用的接口在授权范围内 |
+| 300008 | 缺少必要参数 | 检查 keyword 参数 |
+| 300009 | 账号信息有误 | Token 错误 / 加了 Bearer 前缀 / Token 过期——去掉前缀重试,仍失败则更新 Token |
diff --git a/skills/tianyancha-risk/catalog-metadata.v1.json b/skills/tianyancha-risk/catalog-metadata.v1.json
new file mode 100644
index 0000000..c8809de
--- /dev/null
+++ b/skills/tianyancha-risk/catalog-metadata.v1.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "../../schemas/catalog-metadata.v1.schema.json",
+ "schemaVersion": 1,
+ "identity": {
+ "kind": "skill",
+ "id": "tianyancha-risk"
+ },
+ "presentation": {
+ "defaultLocale": "en-US",
+ "i18n": {
+ "zh-CN": {
+ "name": "天眼查企业风险查询",
+ "summary": "输入企业名称,返回自身/周边/历史/预警四类风险画像",
+ "description": "天眼查企业风险查询——输入企业名称,返回风险画像(自身风险/周边风险/历史风险/预警提醒,含分类统计与明细)。Use when 用户提到\"查风险\"、\"企业风险\"、\"风险画像\"、\"司法风险\"、\"经营风险\"、\"开庭公告\"、\"裁判文书\"、\"被执行人\"、\"天眼查\"。"
+ },
+ "en-US": {
+ "name": "Tianyancha Risk Query",
+ "summary": "Enterprise risk profile by company name — self/related/historical/warning risk",
+ "description": "Tianyancha enterprise risk query — input a company name and return a structured risk profile (self risk / related-party risk / historical risk / early warnings, with category counts and details). Use when the user asks about enterprise risk, judicial risk, litigation announcements, court rulings, dishonest debtors, or Tianyancha."
+ }
+ },
+ "category": "business",
+ "tags": [
+ "due-diligence",
+ "risk",
+ "tianyancha",
+ "corporate"
+ ]
+ },
+ "release": {
+ "state": "known",
+ "version": "1.0.0",
+ "versionScheme": "semver"
+ },
+ "timestamps": {
+ "catalogUpdatedAt": {
+ "state": "known",
+ "value": "2026-09-03T05:45:00Z",
+ "precision": "second"
+ },
+ "releasePublishedAt": {
+ "state": "unknown"
+ },
+ "reviewedAt": {
+ "state": "unknown"
+ },
+ "upstreamObservedAt": {
+ "state": "unknown"
+ }
+ },
+ "provenance": {},
+ "governance": {
+ "stewardship": "official",
+ "availability": "installable",
+ "license": {
+ "state": "unknown"
+ },
+ "redistribution": "verify-package-terms",
+ "listingMaintainer": {
+ "name": "DesireCore Official",
+ "verified": true
+ }
+ },
+ "compatibility": {
+ "platforms": {
+ "state": "unknown"
+ },
+ "requiredClientVersion": "10.0.115"
+ },
+ "spec": {
+ "kind": "skill",
+ "riskLevel": "low"
+ }
+}