refactor: pipeline error propagation, me.yaml→me.ts, docs overhaul

Code:
- pipeline.ts: warn on stderr when step returns {error} object
- xiaohongshu/me.yaml → me.ts (evaluate code belongs in TS)
- index.ts: register xiaohongshu/me.ts

Docs:
- CLI-CREATOR: YAML vs TS decision tree, tap step docs with
  real example, 'explore store first' debugging workflow
- SKILL.md: add tap to Pipeline Steps table, update XHS commands
- README + README.zh-CN: update xiaohongshu command list
This commit is contained in:
jackwener committed 2026-03-15 07:51:20 +08:00
1 parent f26b906bd5
commit 9df96db598
7 files changed
+140 -22

No files matched your search

+1
View File
@@ -20,3 +20,4 @@ import './zhihu/question.js';
// xiaohongshu
import './xiaohongshu/search.js';
import './xiaohongshu/me.js';
@@ -1,16 +1,21 @@
site: xiaohongshu
name: me
description: "我的小红书个人信息"
domain: www.xiaohongshu.com
strategy: intercept
browser: true
/**
* Xiaohongshu me — read self profile info from Pinia user store.
*/
import { cli, Strategy } from '../../registry.js';
columns: [nickname, red_id, fans, follows, notes, likes_collected]
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);
pipeline:
- navigate: https://www.xiaohongshu.com/user/profile/self
- wait: 3
- evaluate: |
const data = await page.evaluate(`
(() => {
const app = document.querySelector('#app')?.__vue_app__;
const pinia = app?.config?.globalProperties?.$pinia;
@@ -19,12 +24,18 @@ pipeline:
if (!userStore) return { error: 'User store not found' };
const state = userStore.$state || {};
const u = state.selfInfo || state.currentUserInfo || state.userInfo || {};
return [{
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];
},
});
+5
View File
@@ -26,6 +26,11 @@ export async function executePipeline(
for (const [op, params] of Object.entries(step)) {
if (debug) debugStepStart(i + 1, total, op, params);
data = await executeStep(page, op, params, data, args);
// Detect error objects returned by steps (e.g. tap store not found)
if (data && typeof data === 'object' && !Array.isArray(data) && data.error) {
process.stderr.write(` ${chalk.yellow('⚠')} ${chalk.yellow(op)}: ${data.error}\n`);
if (data.hint) process.stderr.write(` ${chalk.dim('💡')} ${chalk.dim(data.hint)}\n`);
}
if (debug) debugStepResult(op, data);
}
}