drpy-node-coder · diff

git:20260906.35a66be to git:20260906.54dc693

4 added, 0 removed. Audit B to B.

---
name: drpy-node-coder
description: drpy-node 爬虫源全生命周期一体化 skill——建源、诊断、修复、测试、播放调试、仓库发布,支持本地/远程多网关(远程部署的 drpy-node 远程写源、远程验证)。自带 CLI(scripts/cli.js),无需安装 MCP。用户提到"新建源/写源/做源/建源/生成源/爬虫源""修源/测试某个源/详情为空/搜索异常/源无效/低分评估/诊断/排障/规则不生效""播放不通/lazy 不对/iframe/m3u8/parse:0/1/假播放/加密链接/防盗链""上传仓库/替换上传/改标签/发布源/同步源/打标签/分享源""网关/远程服务器/远程部署/多台/往网关a和网关b/部署到服务器/连接远端/配置远程 drpy-node/初始化网关"时使用。
---
# drpy-node Coder
drpy-node 爬虫源的**建、修、测、放、传**全链路一体化 skill。自带 CLI 工具,**无需安装 MCP 服务**。
## 便携性说明(先读)
- ✅ **无需 MCP**:所有能力内置在 `scripts/cli.js`,AI 直接 `node scripts/cli.js <命令>` 调用。
- ✅ **零 npm 依赖**:无需 `npm install`。`localDsCore` 测试引擎 bundle(14M,全内联 cheerio/axios/drpyS/htmlParser)+ sqlite + 编码 wasm 自带于 `scripts/vendor/`。
- ⚠️ **前置**:本机需有 `drpy-node` 项目(CLI 复用其 `req`/`pdfa`/`drpyS`/DS解密 **源码模块**——这些互相 import、非 bundle,搬不动;但 `localDsCore` 已内联进 `vendor/`,`test`/`evaluate` 不再依赖 `drpy-node-bundle` 目录)。
- 首次使用:`cd scripts && node cli.js setup <drpy-node-绝对路径> && node cli.js doctor`。
- 调用范式:`node scripts/cli.js [--root <drpy-node路径>] [--target <网关名>] <命令> [参数] [--flags]`。所有命令输出 JSON:成功 `{"ok":true,"data":...}`、失败 `{"ok":false,"error":...}`。
- **输出读取**:少数命令(test/evaluate)首次加载测试引擎时 stdout 可能有一次初始化日志,**业务 JSON 始终是 stdout 最后一行**,按最后一行 `{` 解析。
## 网关与远程执行(local / 远程 drpy-node 多网关)
CLI 天然支持多网关:`local`(默认,本地 drpy-node)+ 任意多个远程部署的 drpy-node。
```bash
node cli.js gateway add prod http://1.2.3.4:5757 --user admin --password .. --api-pwd ..
node cli.js gateway persist prod # 凭据固化到系统级环境变量,新会话零配置(首次配置必跑)
node cli.js gateway test prod # 探活+版本+端点可用性(首次连接远程必跑)
node cli.js gateway use prod # 切换默认网关(nvm use 式,持久化)
node cli.js src list --target prod # 单次显式覆盖,不改默认
node cli.js gateway use local # 切回本地
```
### 首连引导剧本(用户不会敲命令时必走)
用户往往只说"帮我配置/连上远端 drpy-node http://x.x.x.x:5757",不会提 gateway 命令。AI 按此剧本**主动执行**,缺什么追问什么,不要把命令甩给用户:
1. **地址缺失先问地址**:要到 IP/域名+端口(drpy-node 默认 5757;docker 部署确认端口已映射、防火墙放行)。
2. **先试探后追问**:`gateway add <建议名> <url>`(先不带凭据)→ `gateway test <名>`,按探测结果**精准**提问,不要一次问全:
- 401 鉴权失败 → 追问远端 `.env` 的 `API_AUTH_NAME`/`API_AUTH_CODE`,顺带确认是否有 `API_PWD`
- runtime 404 → 告知远端 drpy-node 版本过旧需升级
- 全 ok → 无需凭据,跳到第 4 步
3. **带凭据重配+固化**:`gateway add <名> <url> --overwrite --user .. --password .. --api-pwd ..` → `gateway persist <名>`(一次性固化:凭据写入 Windows 用户级环境变量 + Git Bash profile,配置文件改存变量名、清掉明文;幂等可重跑)→ `gateway test` 全绿。此后**任何新终端/新会话零配置可用**,无需再 export。明文→固化的两步由 AI 连续完成,用户只需提供一次凭据。
4. **切换+验证**:`gateway use <名>` → 真实跑一条(如 `src list`)→ 向用户报告连接摘要(远端版本、源数量、网关名、当前指向)。
- **凭据**:`user`/`password`=远端 `.env` 的 `API_AUTH_NAME`/`API_AUTH_CODE`;`api_pwd`=远端 `API_PWD`。配置(`~/.drpy-node-coder/gateways.json`,不入 git)只存变量名;`gateway persist <名>` 一次性固化凭据——Windows 写用户级环境变量(注册表)+bash profile,Linux/macOS 写 `~/.bashrc`(zsh 用户自动覆盖 `.zshrc`;不创建 `.bash_profile` 以免遮蔽 `~/.profile`)。**配置完必跑 persist**,此后任何新终端/新会话零配置可用。
- **分发安全**:skill 目录无状态(凭据/配置/根定位全在 `~/.drpy-node-coder/` 与系统环境变量)。给别人发 skill 必须 `node scripts/pack.mjs` 打包(自动排除运行态残留),不要手工 zip。
- **验证口径(以网关实际服务对象为准)**:远程网关时 `test`/`evaluate`/`syntax`/`validate` 执行于远端(远端运行时真实行为,含它的环境变量/cookie/插件);本地网关时执行于本地。`fetch`/`analyze`/`guess`/`debug`/`iframe` 是外部站点分析,永远本地执行,与网关无关。`house *` 面向仓库服务器,与网关无关。
- **远程写源**:`fs write/edit` 源目录自动走远端 `sources/upload`(带服务端语法校验)与 `sources/delete`;其余目录走 files API。写后均回读验证。
- **多网关编排**:用户说"往网关a和网关b同时写xx源/都测一遍"→ AI 循环对每个网关执行同一命令(`--target a`、`--target b`),汇总对比各网关输出(evaluate 结果自带 `target` 字段)。同一源本地写好 → 逐网关 `fs write --content-file <本地文件> --target <gw>` 部署 → 逐网关 `evaluate --target <gw>`。
+ - **远程源操作三规则(防 404 迷路,本地同理)**:
+ 1. 用户给的源名常是模糊的("360影视"→真实文件 `360影视[官].js`)。`test`/`evaluate` 直接喂模糊名即可:CLI 自动解析真实源名,唯一命中自动采用并在 `source_resolved` 透明标注;多候选会列出候选让你选,无候选会提示先 `src list --filter`。
+ 2. `fs read/write`、`syntax`、`validate`、`resolved` 是文件操作,**必须带目录前缀**(`spider/js/xxx.js`、`spider/php/xxx.php`);报"文件不存在"先检查前缀。
+ 3. 找源名永远用 `src list --filter 关键词`(远端 300+ 源,全量列表浪费上下文);多引擎源(php/py/cat)远程测试加 `--do php`(`--extend` 同步透传)。
- **错误自解释**:401=凭据错(核对网关 user/password);403 只读模式=远端 `.env` 设 `READ_ONLY_MODE=0` 后重启远端;404 无此 API=远端 drpy-node 过旧,提示升级远端。原样把这些提示转告用户,不要盲目重试。
- **远程限制**:hipy/py 源在远端改动后需远端重启服务(daemon 缓存 py module);`restart` 命令远程走 admin API,但**不要**在常规部署流程里自动调用。
## 总控工作流(5 步闭环)
```
用户输入
Step1 识别输入 ──仅 URL──→ 分析站点 → 建源路线
│(已有源名/文件)
Step2 评估现状:syntax+validate(L1) → test 单接口(L2) → evaluate 全流程(L3)
Step3 判断失败类型:A规则不通 / B评估串联 / C播放链
│ 🛑 检查点1:确认诊断结论
Step4 分流执行:本 skill 修 / 转播放调试 / 转仓库
Step5 收束:evaluate 复评 → 🛑 检查点2 → 上传建议 / 结束
```
**核心原则**:先评估 → 再分流 → 再修复 → 再验证 → 最后给上传建议。不要一上来就重写。
## 模式闸门:先判断是否允许写入
| 用户模式 | 允许 | 禁止 |
|---|---|---|
| 只读/dry-run/只规划 | 读取、诊断、给方案和验证计划 | `fs write/edit`、`house upload/*` |
| 需确认后改 | 读取、诊断、输出拟改字段+验证计划 | 未确认前改源或仓库元数据 |
| 明确执行 | 按 L1/L2/L3 证据最小修复 | 跳过大改确认点、直接仓库 mutation |
| 自主全流程("修到100""自动完成""做源并上传") | alive check→建源→低风险修复→播放→L3=100→上传 | 坏站硬写、未达目标冒充完成、目标不明上传 |
## 任务分派表(场景 → 路线 + 首读 reference + 关键命令)
| 场景 | 路线 | 首读 reference | 关键 CLI 命令 |
|---|---|---|---|
| 仅 URL,新建源 | 建源 A/B/C/D | `references-create-checklist.md`、`references-template-system.md` | `fetch` `guess` `analyze` `template` `fs write` `syntax` `validate` `test` `evaluate` |
| 已有源评估低分 | 诊断 A/B/C | `references-workflow-triage.md`、`references-framework-internals.md` | `fs read` `resolved` `evaluate` `test` |
| detail 通但 play 异常 | 播放专项 | `references-play-lazy-summary.md` | `test <src> detail` `test <src> play` `iframe` `fetch` + Playwright(见下) |
| 上传/替换/改标签 | 仓库守门 | `references-upload-decision.md` | `house verify` `house upload` `house list` `house info` `house tags` |
| 模板继承排查 | 路线 A | `references-template-summary.md`、`references-inherited-template-minimal-override-site.md` | `guess` `resolved` |
| 纯 API/SPA 站 | 路线 C | `references-pure-api-async-site.md`、`references-api-functions.md` | `fetch` `analyze` |
| 签名接口站 | 路线 B2 | `references-non-template-signed-api-site.md` | `fetch` + 浏览器抓包 |
| 二级字典/多集 | detail 规范 | `references-detail-dict-and-multiep.md` | `debug` `test <src> detail` |
| 搜索异常 | 搜索策略 | `references-search-strategies.md`、`references-old-encoding-search-site.md` | `test <src> search` |
| async 函数陷阱 | 通用 | `references-async-function-patterns.md` | — |
| 特殊内容(漫画/小说/音乐/网盘) | 路线 D | `references-special-content.md` | — |
| 多引擎源(php/hipy/cat) | 路线 E | `references-multi-engine-sources.md` | `fetch` + curl `?do=py/php/cat&extend=`(**必须带 extend**;hipy 改源需 kill daemon)|
## 建源 30 秒路线(仅 URL 入口)
**Step 0 alive check**(自主模式不可跳过):`fetch <url>` 确认可达;`guess <url>` 探模板;`analyze <url>` 看 HTML/SPA。遇 `broken_site`/`hard_anti_bot`/`missing_credentials` 停手。
**站型分派**(先 `guess`):
- 命中模板 → **A 模板继承**(最小覆盖 host/url/searchUrl/class_parse,勿急重写)
- 未命中+DOM 完整 → **B1 字符串规则**(+二级字典)
- 未命中+签名接口 → **B2 async 一级/搜索**
- body 空+JSON API → **C 全 async**
- 漫画/小说/音乐/网盘 → **D 特殊内容**
- 403/登录/验证码 → **停手**
**7 条必背规则**(含 async 的源必过):①`this.input` 是 URL 不是响应,须 `await request(this.input)` ②纯数字 vod_id 必设 `detailUrl` ③POST 用 `body` 非 `data` ④`searchUrl` 必带 `**` ⑤推荐要全量聚合去重 ⑥async 用 `this.input`/`this.MY_CATE`/`this.MY_PAGE`,勿手拼 URL ⑦不写重复同名属性。
**写入验证链**:`template` → `fs write spider/js/源名.js` → `syntax` → `validate` → `test home/category/detail/search/play` → `evaluate`。
## 诊断 L1/L2/L3 证据链
| 等级 | 命令 | 能下结论 | 不能下结论 |
|---|---|---|---|
| L1 | `syntax` + `validate` | 非语法残档、rule 结构合法,可拆测 | 可用、已修好、可上传 |
| L2 | `test <src> <iface>` 单接口 | 某接口真实通/断(须带真实上游返回值) | 全链稳定、可发布 |
| L3 | `evaluate <src>` 全流程 | 首页→一级→二级→播放→搜索串联评分 | 站点长期稳定 |
**结论必须带等级**,例"L2 显示 detail 通、play 断",不要说成"整个源不通"。单接口测试必须用上游真实返回值(category→vod_id→detail→play_url),不要手推 ID。
**evaluate 丢分映射**:首页20+一级20丢 → `class_parse` 未命中;仅首页20丢 → `double` 不匹配;搜索10丢 → 已按源名后缀选默认词(漫画->海贼王/小说->修仙/短剧->离婚/音频->故事),仍丢则换词查 `searchUrl`;二级25丢 → `detailUrl`/二级字典;播放25丢 → 先看 `test detail` 的 `play_url_diagnosis`:detail 有数据但 `vod_play_url` 空属二级选择器/detailUrl 问题(非 play 层),按 hint 修二级;仅当 detail 完整且 play 真失败才转 Playwright 嗅探。常见误判:detail 返回列表项(只有 vod_id/vod_name/vod_pic)而非完整详情 = 缺 `detailUrl`。
## 播放调试(Playwright 复用指引)
CLI 提供 `test <src> play`、`iframe <url>`、`fetch <url>`。**浏览器嗅探能力不在 CLI 内**——需要嗅探 JS 运行时生成的 m3u8/签名时,使用你已连接的 **Playwright MCP**:
1. `browser_navigate(play_url)` 打开播放页
2. `browser_network_requests(filter='m3u8|mp4|api|play|url')` 看运行时请求
3. 需点播放按钮则 `browser_snapshot` 找按钮→点击→再看网络
4. 提取真实媒体 URL 或签名 API,回写 lazy
lazy 三类型:**common_lazy**(播放页有 player_* JSON,先查 encrypt)/ **def_lazy**(`{parse:1,url:input}` 嗅探)/ **cj_lazy**(parse_url)。**假通过识别**:`play` success≠真实可播,返回 url 仍是 play.html/API/普通页时继续验扩展名/content-type/网络请求。
## 仓库发布守门
上传前必跑:`house verify` + `syntax` + `validate` + 源 metadata 自洽。给出 **A/B/C 档 + L1/L2/L3 证据**:
- **A 建议上传**:至少 L2,最终版/自主要求 L3=100
- **B 技术可传不建议**:L1/L2,用户坚持才传
- **C 暂不传**:触红线(语法错/结构无效/metadata 不一致/详情空/播放假通过/特殊内容无对应协议)
**上传**:`house upload <path> --tags <逗号分隔> --is-public true --auto-replace true`(默认同名自动替换)。上传后 `house info <cid>` 核验 file_id/cid/tags/is_public 一致。
**标签规则**:不脑补、不因文件名带 `[优]` 就加 `优`,严格按用户明确要求;用户没说则从简。
## 强约束 / 停手边界
- **坏站/反爬/缺凭据** → 停手回报,不绕过(`broken_site`/`hard_anti_bot`/`missing_credentials`)。
- **高风险重写**(模板改全 async、删大段规则、引签名/登录态)→ 必须先给方案等确认。
- **仓库 mutation**(upload/replace/tags/toggle)→ 必须 `house verify` + 目标确认 + `info` 核验。
- **DS 加密源**:用 `fs read`(自动解密),勿用 IDE Edit 直接改加密文件。
- **hipy 源改动**:改 `spider/py/*.py` 或 `base/spider.py` 后必须 kill `t4_daemon` 重载(daemon 缓存 module),否则改动不生效;ds/cat 改了直接生效无此问题。见 `references-multi-engine-sources.md`。
- **大改确认点**:删手写规则、改 detail 线路逻辑、跨多 flag 的 lazy 重写 → 停手确认。
- **路径安全**:所有文件操作限定在 drpy-node 项目内(isSafePath 强制)。
## 自主全流程 handoff packet
当用户要求"自动完成/修到100/做源并上传"时,贯穿建→修→测→传全程:
```text
autonomous: true
target_score: 100
upload_preauthorized: true/false
tags/is_public: 用户明确值或空
source_name/path: ...
blocker_type: none/broken_site/hard_anti_bot/missing_credentials/high_risk_change/ambiguous_upload/score_below_target/detail_unstable
autonomous_next: continue_evaluate/return_workflow/stop_for_user
```
自主循环:`alive check → 建源 → L1/L2/L3 → 按丢分最小修复 → play(detail 稳定时)→ L3=100 → house upload → info 核验`。低风险不停手只记录;遇 high_risk/目标歧义/凭据缺失必须停手确认。
## CLI 速查(高频;完整清单见 references-cli-commands.md)
```bash
node cli.js [--root <path>] doctor # 自检(含网关概览)
node cli.js gateway add|list|use|test|remove <..> # 多网关管理(见网关章节)
node cli.js src list # 列源
node cli.js fetch <url> [--method POST --header k=v --data] # 抓取(用 drpy req)
node cli.js analyze <url> | guess <url> # 清洗DOM | 探模板
node cli.js debug --rule 'a&&href' --mode pdfh --url <url> # 规则调试(pdfa/pdfh/pd)
node cli.js fs read <path> | fs write <path> --content ... # 读写(.js自动DS解密; --target 远程)
node cli.js fs edit <path> replace_text --search .. --replacement .. # 编辑(JS语法校验)
node cli.js syntax <path> | validate <path> | resolved <path>
node cli.js test <src> <home|category|detail|search|play> [--class-id/--ids/--keyword/--play-url/--flag]
node cli.js evaluate <src> [--keyword 斗罗大陆] # 全流程评分(满分100; 远程打远端运行时)
node cli.js house verify | house upload <path> --tags .. | house info <cid>
```
参数约定:位置参数在前,flags 在后(`--flag value` / `--flag=value` / `--header k=v` 可重复)。大文本用 `--content-file` 或 stdin。
## Reference 使用规则
references/ 落地深度内容(建源清单/模板系统/async 陷阱/play lazy/上传决策/框架机制等)。主文件不重复 reference 内容,按「任务分派表」首读对应 reference。reference 不可达时不中断,按本文件内置规则最小排查并标注。