refactor: remove xiaohongshu me, add lessons learned, fix docs

- Remove xiaohongshu/me (profile page async loading too unreliable)
- CLI-CREATOR: add 4 lessons to 常见陷阱 (stale dist YAML, TS IIFE
  format, async polling, YAML vs TS threshold)
- Fix build: clean-yaml before copy to prevent stale overrides
- Fix docs: MCP token is configured via MCP config, not env var
- Update all command lists (README, README.zh-CN, SKILL.md)
This commit is contained in:
jackwener committed 2026-03-15 08:10:40 +08:00
1 parent fd94a5d27b
commit 999d340a34
7 files changed
+10 -49

No files matched your search

+3
View File
@@ -571,6 +571,9 @@ git push
| 搜索参数被 URL 编码 | `${{ args.keyword }}` 被浏览器二次编码 | 在 evaluate 内用 `encodeURIComponent()` 手动编码 |
| Cookie 过期 | 返回 401 / 空数据 | 在浏览器里重新登录目标站点 |
| Extension tab 残留 | Chrome 多出 `chrome-extension://` tab | 已自动清理;若残留,手动关闭即可 |
| TS evaluate 格式 | `() => {}` 报 `result is not a function` | TS 中 `page.evaluate()` 必须用 IIFE:`(async () => { ... })()` |
| 页面异步加载 | evaluate 拿到空数据(store state 还没更新) | 在 evaluate 内用 polling 等待数据出现,或增加 `wait` 时间 |
| YAML 内嵌大段 JS | 调试困难,字符串转义问题 | 超过 10 行 JS 的命令改用 TS adapter |
---
+2 -2
View File
@@ -57,7 +57,7 @@ npm install -g @jackwener/opencli@latest
Browser commands need:
1. **Chrome** running **and logged into the target site** (e.g. bilibili.com, zhihu.com, xiaohongshu.com)
2. **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** extension installed
3. Configure `PLAYWRIGHT_MCP_EXTENSION_TOKEN` (from the extension settings page) as an environment variable, or in your MCP config:
3. Configure `PLAYWRIGHT_MCP_EXTENSION_TOKEN` (from the extension settings page) in your MCP config:
```json
{
@@ -83,7 +83,7 @@ Public API commands (`hackernews`, `github search`, `v2ex`) need no browser at a
|------|----------|------|
| **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `user-videos` | 🔐 Browser |
| **zhihu** | `hot` `search` `question` | 🔐 Browser |
| **xiaohongshu** | `search` `me` `notifications` `feed` | 🔐 Browser |
| **xiaohongshu** | `search` `notifications` `feed` | 🔐 Browser |
| **twitter** | `trending` | 🔐 Browser |
| **reddit** | `hot` | 🔐 Browser |
| **github** | `trending` `search` | 🔐 / 🌐 |
+2 -2
View File
@@ -57,7 +57,7 @@ npm install -g @jackwener/opencli@latest
浏览器命令需要:
1. **Chrome** 浏览器正在运行,且**已登录目标网站**(如 bilibili.com、zhihu.com、xiaohongshu.com)
2. 安装 **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** 扩展
3. 配置 `PLAYWRIGHT_MCP_EXTENSION_TOKEN`(从扩展设置页获取),设为环境变量或写入 MCP 配置:
3. 在 MCP 配置中设置 `PLAYWRIGHT_MCP_EXTENSION_TOKEN`(从扩展设置页获取):
```json
{
@@ -83,7 +83,7 @@ npm install -g @jackwener/opencli@latest
|------|------|------|
| **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `user-videos` | 🔐 浏览器 |
| **zhihu** | `hot` `search` `question` | 🔐 浏览器 |
| **xiaohongshu** | `search` `me` `notifications` `feed` | 🔐 浏览器 |
| **xiaohongshu** | `search` `notifications` `feed` | 🔐 浏览器 |
| **twitter** | `trending` | 🔐 浏览器 |
| **reddit** | `hot` | 🔐 浏览器 |
| **github** | `trending` `search` | 🔐 / 🌐 |
+1 -2
View File
@@ -30,7 +30,7 @@ npm update -g @jackwener/opencli
Browser commands require:
1. Chrome browser running **(logged into target sites)**
2. [Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm) extension
3. Configure `PLAYWRIGHT_MCP_EXTENSION_TOKEN` env var (from extension settings) or in MCP config
3. Configure `PLAYWRIGHT_MCP_EXTENSION_TOKEN` (from extension settings) in your MCP config
> **Note**: You must be logged into the target website in Chrome before running commands. Tabs opened during command execution are auto-closed afterwards.
@@ -57,7 +57,6 @@ opencli zhihu question --id 34816524 # 问题详情和回答
# 小红书 (browser)
opencli xiaohongshu search --keyword "美食" # 搜索笔记
opencli xiaohongshu me # 我的信息
opencli xiaohongshu notifications # 通知(mentions/likes/connections)
opencli xiaohongshu feed --limit 10 # 推荐 Feed
+2 -1
View File
@@ -12,7 +12,8 @@
},
"scripts": {
"dev": "tsx src/main.ts",
"build": "tsc && npm run copy-yaml",
"build": "tsc && npm run clean-yaml && npm run copy-yaml",
"clean-yaml": "find dist/clis -name '*.yaml' -o -name '*.yml' 2>/dev/null | xargs rm -f",
"copy-yaml": "find src/clis -name '*.yaml' -o -name '*.yml' | while read f; do d=\"dist/${f#src/}\"; mkdir -p \"$(dirname \"$d\")\"; cp \"$f\" \"$d\"; done",
"start": "node dist/main.js",
"typecheck": "tsc --noEmit",
-1
View File
@@ -20,4 +20,3 @@ import './zhihu/question.js';
// xiaohongshu
import './xiaohongshu/search.js';
import './xiaohongshu/me.js';
-41
View File
@@ -1,41 +0,0 @@
/**
* Xiaohongshu me — read self profile info from Pinia user store.
*/
import { cli, Strategy } from '../../registry.js';
cli({
site: 'xiaohongshu',
name: 'me',
description: '我的小红书个人信息',
domain: 'www.xiaohongshu.com',
strategy: Strategy.COOKIE,
args: [],
columns: ['nickname', 'red_id', 'fans', 'follows', 'notes', 'likes_collected'],
func: async (page) => {
await page.goto('https://www.xiaohongshu.com/user/profile/self');
await page.wait(3);
const data = await page.evaluate(`
(() => {
const app = document.querySelector('#app')?.__vue_app__;
const pinia = app?.config?.globalProperties?.$pinia;
if (!pinia?._s) return { error: 'Page not ready' };
const userStore = pinia._s.get('user');
if (!userStore) return { error: 'User store not found' };
const state = userStore.$state || {};
const u = state.selfInfo || state.currentUserInfo || state.userInfo || {};
return {
nickname: u.nickname || u.name || '',
red_id: u.red_id || u.redId || '',
fans: u.fans || u.fansCount || 0,
follows: u.follows || u.followsCount || 0,
notes: u.notes || u.noteCount || 0,
likes_collected: u.collected || u.likedAndCollected || 0,
};
})()
`);
if (!data || data.error) return [];
return [data];
},
});