aiconductor-cli 1.3.5 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ # 抖音三技能上架计划
2
+
3
+ 目标:在 `douyin-script-extract` 之外再补 3 个可独立上架的流量入口,每个都能用一句话说清"用户为什么装它",且交付物比裸命令多出加工价值。
4
+
5
+ ---
6
+
7
+ ## 一、稳定层(承诺,入库)
8
+
9
+ ### 1. 共同骨架(三个技能一致,不逐条重复)
10
+
11
+ | 项 | 约定 |
12
+ |---|---|
13
+ | 目录 | `.codex/skills/<name>/`,同时镜像到 `~/.agents/skills/<name>/`,两处正文逐字一致 |
14
+ | frontmatter | 8 项必填 + `author: "AI指挥家"` + `examples_zh/en` 各 3 条(用能跑通的真链接) |
15
+ | 正文开头 | `## 概述`,口吻"默认已装好 CLI 与 API Key",故障才读 `references/aiconductor-skills-setup.md` |
16
+ | 验真 | 外层 `success`/退出码不可信,一律落 `data.data.success`;失败给 `message` |
17
+ | 不写价格 | 单价、扣费、"免费"不进 SKILL.md;余额不足这类故障信息可以写 |
18
+ | 交付纪律 | 数字必须有出处(哪条数据算出来的),结论必须挂原话或原作品,不编造 |
19
+ | 时区 | `create_time` 是 Unix 时间戳,统一显式转北京时间再展示,禁止把 UTC 当本地 |
20
+ | 字段降级 | 上游透传字段可能缺(TikHub 侧变动),缺字段时降级展示,不报错也不猜 |
21
+
22
+ ### 2. 三个技能的规格
23
+
24
+ #### A. `douyin-topic-radar` — 抖音爆款选题
25
+
26
+ - **用户话术**:最近什么在爆 / 这个赛道谁做起来了 / 找几个对标 / 我该拍什么
27
+ - **命令**:`aiconductor-cli douyin video-search <keyword>`
28
+ - **预设分档**(技能的核心价值,用户不需要知道参数存在)
29
+
30
+ | 档位 | 参数 | 用途 |
31
+ |---|---|---|
32
+ | 近一周最热 | `--sort-type 1 --publish-time 7 --max-pages 1` | 默认档,看当下 |
33
+ | 半年爆款池 | `--sort-type 1 --publish-time 180 --max-pages 2` | 找可复刻的长期爆款 |
34
+ | 最新动向 | `--sort-type 2 --publish-time 1 --max-pages 1` | 追热点 |
35
+ | 长视频对标 | `--sort-type 1 --filter-duration 5-10000` | 口播/知识类 |
36
+
37
+ - **多关键词**:用户给一个赛道词时,自动扩 3–4 个同义词(AI编程 / AI写代码 / 程序员用AI),串行跑,按 `aweme_id` 合并去重
38
+ - **交付契约**
39
+ 1. Top N 表:点赞 / 评论 / 时长 / 发布时间(北京时间)/ 作者 / 标题
40
+ 2. 共性:时长区间、发布时间段、标题钩子类型、内容形式(口播/实拍/图文)
41
+ 3. 选题建议 3–5 条,每条挂"哪几条爆款支撑"
42
+ 4. 数据口径一句:点赞是抓取时点快照,非实时
43
+ - **过滤**:时长 < 10 秒(切片/图文)、重复搬运(同 desc)、点赞低于本批中位数
44
+ - **边界**:不下载视频、不分析评论、不提取文案
45
+ - **已知坑**
46
+ - `max_seconds` 上限 **50 秒**,翻页会被截断且 `success` 仍为 `true`、`has_more=1` → 必须提示"未取全"
47
+ - 搜索是关键词匹配不是赛道,关键词太泛会灌进无关内容,需要 `--filter-duration` 收窄
48
+
49
+ #### B. `douyin-comment-insight` — 抖音评论洞察
50
+
51
+ - **用户话术**:评论区在吵什么 / 用户对 XX 的真实反馈 / 这条视频为什么被骂
52
+ - **命令**:`aiconductor-cli douyin video-comments <video_url> --max-count 50`
53
+ - **交付契约**
54
+ 1. 热评 Top 10:原话引用 + 点赞数(按 `digg_count` 降序,不按接口顺序)
55
+ 2. 争议点:正反两派各自的原话,各 1–2 条
56
+ 3. 用户诉求/高频提问:问得最多的问题
57
+ 4. 情绪倾向:只给"按原话看,X 多于 Y",**不给编造的百分比**
58
+ 5. 一句话结论
59
+ - **过滤**:广告引流(私信/加V/主页)、纯表情、互喷、完全重复
60
+ - **纪律**:结论必须挂原话;必须说明"样本是前 50 条,不代表全量民意"
61
+ - **边界**:不抓二级评论(只用 `reply_comment_total` 给数量)、不爬作者主页
62
+ - **已知坑**:`is_folded` 折叠评论、无评论/评论关闭、视频已删
63
+
64
+ #### C. `douyin-account-audit` — 抖音账号拆解
65
+
66
+ - **用户话术**:扒一下这个号 / 他为什么火 / 找几个这个领域的号
67
+ - **命令链**:`user-detail` → `user-videos` →(可选)对 Top3 调 `video-info`
68
+ - **找号模式**:用户只给赛道词时,先 `user-search <关键词> --fans-range … --user-type …`,再按简介/作品二次筛
69
+ - **交付契约**
70
+ 1. 账号画像:昵称 / 粉丝 / 获赞 / 作品数 / 认证 / 简介 / IP 属地
71
+ 2. 更新频率:由 `create_time` 算近 N 条的周更条数
72
+ 3. 内容结构:按主题分组,各组点赞中位数与爆款数
73
+ 4. 爆款率:点赞 ≥ 该号中位数 × 3 的作品占比
74
+ 5. 可复制点 3 条,每条挂具体作品
75
+ 6. 口径一句:只分析了最近 N 条,不是全量
76
+ - **脚本**:`scripts/profile.mjs`(纯统计,无网络)
77
+ - 输入:`user-videos` 的原始 JSON;输出:结构化摘要(时间跨度、周更频率、中位数、爆款清单)
78
+ - 理由:爆款率/频率这类口径每次手写必漂,固化成脚本才可复现
79
+ - 三个技能里**只有它带脚本**;另外两个的排序过滤是单行逻辑,先不写,等 eval 发现重复劳动再抽
80
+ - **已知坑**
81
+ - `user-videos` 默认 1 页 / 50 秒;**`max_seconds` 上限 180**(已与服务方确认,`api_docs/douyin_user_videos.md` 同步为 180)。大号要取全就得显式调到 180,但仍必须在交付物里说明「只看了最近 N 条」
82
+ - 大号一页约 20–30 条,必须一开始就说清"只看最近 N 条"
83
+ - 私密/隐藏作品拿不到,粉丝数增长历史拿不到(只有当前值)
84
+
85
+ ### 3. 验收标准(每个技能都要过)
86
+
87
+ - [ ] `node bin/aiconductor-cli.js douyin <cmd> --help` 与技能里写的参数逐项一致
88
+ - [ ] frontmatter 8 项齐全,`name == 目录名`,`references/` 路径可达
89
+ - [ ] 真实调用至少 1 次:字段路径对得上、时间戳是北京时间、交付物符合契约
90
+ - [ ] 失败分支实测 1 次(错链接/无评论/空结果),能识别且话术对
91
+ - [ ] 全文零价格词(`元/计费/扣费/付费/免费/按次`)
92
+ - [ ] 两个副本正文逐字一致;提交到项目仓库与技能库
93
+ - [ ] **目录本身可直接上架 WorkBuddy**:根目录 `SKILL.md`、`references/` 随目录一起走、不依赖目录外任何文件
94
+ - [ ] 交付时附一份可复制的上架清单(见第四节)
95
+
96
+ ---
97
+
98
+ ## 二、可变层(脚手架,随实现修订)
99
+
100
+ ### 实施顺序与粒度
101
+
102
+ | 步 | 动作 | 产出 |
103
+ |---|---|---|
104
+ | 1 | `douyin-topic-radar` 起草 + 真实跑 1 个关键词 | SKILL.md + references |
105
+ | 2 | 按交付契约手工核一遍(Top N 表、共性、建议是否挂得住) | 修订记录 |
106
+ | 3 | `douyin-comment-insight` 起草 + 真实跑 1 条视频 | SKILL.md + references |
107
+ | 4 | `douyin-account-audit` 起草 + `scripts/profile.mjs` + 真实跑 1 个号 | SKILL.md + references + scripts |
108
+ | 5 | 三技能交叉检查:命名/描述不互抢、边界互不重叠 | 一次 diff |
109
+ | 6 | 提交(每个技能一个 commit) | 两个仓库 |
110
+
111
+ ### 真实调用成本与授权
112
+
113
+ 三个技能各需 1–2 次真实调用,合计约 1 元级。执行前单独确认(项目规矩:带 Key 的计费调用先问)。
114
+
115
+ ### 风险
116
+
117
+ 1. **同名技能互抢**:三个 description 必须写清边界(选题=找什么拍 / 评论=看反馈 / 拆号=看一个账号),否则平台内部排序自己打自己
118
+ 2. **setup 副本增至 9 份**:改一次密钥说明要改 9 处。可选先做一件事——加一条比对命令(`md5sum` 全部副本),漂移立刻可见;不新增脚本
119
+ 3. **字段漂移**:`video_search` 是 TikHub 透传,字段名可能变;技能里写成"缺字段降级",不硬依赖
120
+ 4. **样本偏差**:搜索只返回前 N 页、评论只前 50 条、账号只最近 N 条;三个技能都必须把这句话写在交付物里,不能默认用户知道
121
+
122
+ ---
123
+
124
+ ## 四、WorkBuddy 交付格式(最终产物)
125
+
126
+ 每个技能交出去的东西必须能直接上传,不靠二次解释:
127
+
128
+ ```text
129
+ <skill-name>/
130
+ ├── SKILL.md # 8 项必填 frontmatter + 概述 + 执行/失败/限制
131
+ └── references/
132
+ └── aiconductor-skills-setup.md # 安装与密钥兜底,随目录走
133
+ (douyin-account-audit 额外带 scripts/profile.mjs)
134
+ ```
135
+
136
+ 硬性要求:
137
+
138
+ - 目录名 == `name`;根下必须有 `SKILL.md`
139
+ - 引用的文件全在目录内,用 Markdown 链接 `[references/x.md](references/x.md)`
140
+ - 不依赖仓库内的其他路径(技能是独立安装单元)
141
+ - 不写价格(单价/扣费/"免费");余额不足这类故障提示可以写
142
+ - 中文名、英文名、中英简介、中英案例各就各位(详情页直接读这些字段)
143
+
144
+ 交付时额外给一份**上架清单**(可整段复制进 WorkBuddy 后台表单):
145
+
146
+ | 项 | 内容 |
147
+ |---|---|
148
+ | 技能标识 / 目录 | `<name>` |
149
+ | 中文名 / 英文名 | `display_name` / `display_name_en` |
150
+ | 中文简介 / 英文简介 | `description_zh` / `description_en` |
151
+ | 使用案例 ×3(中/英) | `examples_zh` / `examples_en`,用能真跑通的链接 |
152
+ | 作者 | AI指挥家 |
153
+ | 版本 | 1.0.0 |
154
+
155
+ ---
156
+
157
+ ## 五、未决问题(开工前请确认)
158
+
159
+ 1. 命名是否接受:`douyin-topic-radar`(抖音爆款选题)、`douyin-comment-insight`(抖音评论洞察)、`douyin-account-audit`(抖音账号拆解)
160
+ 2. 达人筛选并入账号拆解的"找号模式",不单独上架——是否同意
161
+ 3. 是否先做第 1 个跑通再继续,还是三个一起起草完再统一直真实测
package/AGENTS.md CHANGED
@@ -1,107 +1,186 @@
1
- # Repository Guidelines
1
+ # 项目协作规范
2
+
3
+ ## 项目概述
4
+
5
+ `aiconductor-cli` 是 AIConductor 平台 API 的命令行封装:Node.js >= 18、CommonJS、唯一运行时依赖 `commander`,发布到 npm 供 agent 与终端用户直接调用。七组命令覆盖网页发布、豆包搜索、热点简报、抖音数据、小红书数据、公众号数据;`.codex/skills/` 存放面向 agent 的工作流,指导如何调用这些命令,其中对外发布的技能(`xhs-note-publish`、`douyin-script-extract`)还要满足 WorkBuddy 上架字段,见 `references/workbuddy技能规范.md`。`README.md` 是对外命令契约,本文档是开发与维护契约。
6
+
7
+ ## 项目结构与模块组织
8
+
9
+ ```text
10
+ bin/aiconductor-cli.js 唯一入口:注册全部命令、参数与选项(Commander.js)
11
+ src/api.js 平台 HTTP 客户端:端点常量、请求体映射、鉴权、文件上传
12
+ src/lib/cli-utils.js 输出与错误:outputResult / outputError / resolveKeyOrExit / handleApiError / safeParseInt
13
+ src/commands/
14
+ html_publish.js html publish
15
+ md_publish.js webpage publish | list | delete
16
+ web_search.js search web | image
17
+ content.js content briefing
18
+ douyin.js douyin 的 7 个子命令
19
+ xhs.js xhs hot-list | note-publish
20
+ wx.js wx article-data | history
21
+ src/api.test.js 全部自动化测试(api 映射 + 纯格式化/聚合函数)
22
+ api_docs/<endpoint>.md 每个平台接口的请求/响应/计费契约(`aiconductor-platform` 对应文件的整文件副本)
23
+ references/ 平台侧规范(workbuddy技能规范.md),不参与 CLI 运行;已 gitignore + npmignore,只在本机
24
+ .codex/skills/<name>/ SKILL.md(路由与执行)+ references/(按条件加载)+ 可选 scripts/
25
+ ```
2
26
 
3
- ## Project Structure & Module Organization
27
+ 推导规则:命令组名与文件名**不一一对应**(`webpage` → `md_publish.js`,`search` → `web_search.js`),找实现先看 `bin/aiconductor-cli.js` 的注册处。命令文件只做四件事:解析选项、调用 `src/api.js`、格式化输出、`process.exit`;共享逻辑进 `src/lib/cli-utils.js`,HTTP 与鉴权细节不允许出现在命令文件里。
4
28
 
5
- ```
6
- bin/aiconductor-cli.js CLI entry point (Commander.js)
7
- src/
8
- api.js HTTP API client — all platform calls live here
9
- lib/cli-utils.js Shared helpers: output, error handling, key resolution
10
- commands/
11
- html_publish.js `html publish` command
12
- md_publish.js `webpage publish` command (Markdown/HTML)
13
- web_search.js `search web` / `search image` commands
14
- douyin.js All `douyin` subcommands
15
- xhs.js `xhs note-publish` command
16
- .codex/skills/
17
- <skill-name>/
18
- SKILL.md Skill entry point and decision/execution workflow
19
- references/ Documentation loaded only when its stated condition applies
20
- scripts/ Optional deterministic, reusable helper scripts
21
- ```
29
+ ## 配套项目:aiconductor-platform(接口契约的源头)
30
+
31
+ 本 CLI 只是 `aiconductor-platform` 里 78 个插件端点的薄封装。接口行为、返回字段、计费口径、上游第三方服务的坑都在那边;CLI 侧遇到「字段对不上 / 端点是 404 / 参数被拒」,先回那边查,不要在本仓库猜。
32
+
33
+ - **路径**:`D:/Development/aiconductor-platform`(monorepo:`backend/` FastAPI 插件、`frontend/` Next.js 控制台,同机部署在平台那台 ECS 上)
34
+ - **路由推导**:`backend/plugins/<name>.py` → `/api/<name>`;`backend/plugins/<group>/<name>.py` → `/api/<group>/<name>`。删文件即下线路由,没有注册表
35
+ - **契约文档**:`backend/api_docs/<name>.md` 是唯一源头;`aiconductor-cli/api_docs/` 是它的**整文件副本**(例外:`china_stock_data.md` 只在 CLI 侧)。改契约先改 platform 再覆盖过来,不在 CLI 侧手改副本;已知 `xhs_note_publish.md` 两边已漂移,下次碰它时整文件对齐
36
+ - **平台侧的开发与运维规则**(新增插件、计费三件套、180s 超时预算、nginx 60s、发版自检清单、已验证的坑)全在 `aiconductor-platform/AGENTS.md`,动接口前读那里,本文档不复述
37
+
38
+ ### 端点到命令的落点
39
+
40
+ | 要做的事 | 改哪里 |
41
+ |---|---|
42
+ | 确认真实行为、字段、上游依赖 | `aiconductor-platform/backend/plugins/<name>.py` + `api_docs/<name>.md` |
43
+ | 新增/修改接口契约 | platform 侧插件与 `api_docs`,再覆盖到 `aiconductor-cli/api_docs/` |
44
+ | CLI 接入 | `src/api.js`(端点常量 + `httpPost` + `stripBilling`)→ `src/commands/<组>.js` → `bin/aiconductor-cli.js` 注册 |
45
+ | 测试 | `src/api.test.js`,请求字段抄 `api_docs`,不抄实现 |
46
+ | 对外文档与技能 | `README.md`、`.codex/skills/*/SKILL.md` |
47
+
48
+ ### 鉴权与计费的两侧分工
49
+
50
+ - **鉴权**:platform 框架会把 `Authorization: Bearer <key>` 与 body/query 里的 `api_key` 都塞进 `args.input.api_key`,所以插件两种都收;CLI 只照 `api_docs` 写的那一种发,不要"统一"。
51
+ - **计费**:单价、折扣、停用状态都在 platform 的 `api_services` 表(`service_code` 维度)。CLI 不写价格、不输出 `billing`;README 计费表里配置驱动的项写「以平台服务配置为准」,不写死数字。
52
+ - **失败面**:`wx_*` 系列把业务失败放在 HTTP 200 的响应体里(`success:false` + `message`),CLI 在 `api.js` 用 `throwOnBusinessFailure` 转成 `api_error`(退出码 1、错误进 stderr),不要改成"成功退出 + 空 data"。
53
+
54
+ ### 联调限制(别假设能做)
55
+
56
+ - `API_HOST` 是 `src/api.js` 里的常量 `plugin.aiconductor.fun`,**没有环境变量覆盖**:CLI 现在无法指向本地后端(本地起服务是 `cd aiconductor-platform/backend && uvicorn main:app --reload --port 8000`)。要做本地联调得先给 CLI 加 host 覆盖,未做之前不要在文档里声称支持。
57
+ - 线上端点是否在线可直接查:`curl -s https://plugin.aiconductor.fun/api/plugins`(2026-11-04 实测 78 个)。判断"某端点不存在"以它为准,不以本文档的数字为准。
58
+ - 返回不对时先用 `-f json` 看原始响应:能对上就是 CLI 映射/格式化的问题,对不上或报上游错误就是 platform 侧契约或第三方服务变了。
59
+
60
+ ### 公众号(wx_*)已接与未接
61
+
62
+ 已接 2 个(`wx` 组):`wx_article_data` → `wx article-data`、`wx_history_articles` → `wx history`。
63
+
64
+ platform 侧还有、CLI 未接 10 个:`wx_rss_reader`、`flow_wx_history_articles`、`wx_access_token`、`wx_md_to_html`、`md_to_wxhtml`、`wx_image_upload`、`wx_draft_add`、`wx_draft_publish`、`users/wx_article_style_rewrite`、`wx_article_analysis_data_push`(最后一个只是扣费触发器,不返回数据)。`wx_rss_reader` 与 `flow_wx_history_articles` **用户明确不要**(2026-11-04),不要再当成待补项;接发布链路时注意 `wx_draft_add` 要先用 `wx_image_upload` 拿 `thumb_media_id`。
65
+
66
+ ## 构建、测试与开发命令
67
+
68
+ | 命令 | 用途 |
69
+ |---|---|
70
+ | `npm install` | 安装唯一依赖 `commander`(有 lock) |
71
+ | `npm test` | `node --test`,25 个用例,离线打桩,不需要 API Key |
72
+ | `node bin/aiconductor-cli.js --help` | 不安装也能本地运行,核对命令面 |
73
+ | `node bin/aiconductor-cli.js <组> <子命令> --help` | 核对某个命令的参数与默认值;CLI 契约以它为准 |
74
+ | `npm pack --dry-run` | 确认发布内容:含 `src/**`(含测试)、`api_docs/`、`AGENTS.md`,不含 `.codex/` 与 `references/`(平台侧规范只在本机,已从 `.npmignore`/`.gitignore` 排掉) |
75
+
76
+ 无构建步骤、无 lint/formatter、无 CI。
77
+
78
+ ## 常见改动怎么做
79
+
80
+ ### 新增或修改命令
81
+
82
+ 1. 在对应 `src/commands/<组>.js` 加/改处理函数(薄封装,照现有文件风格)。
83
+ 2. 需要新端点时先读 `api_docs/<endpoint>.md`,在 `src/api.js` 加端点常量与函数,复用 `httpPost` + `stripBilling`。
84
+ 3. 在 `bin/aiconductor-cli.js` 注册子命令与选项——这是**唯一注册点**。`-k, --api-key`、`-f, --format` 每个命令各自声明,没有全局注入;可重复选项用 `collect`。
85
+ 4. 跑 `node bin/aiconductor-cli.js <组> <子命令> --help` 核对命令面,跑 `npm test`。
86
+ 5. 同步受影响产物:`README.md`(synopsis、选项表、示例)、对应的 `.codex/skills/*/SKILL.md`(命令、选项、`data.data.*` 路径)、`src/api.test.js`(改了请求映射或格式化时)。
22
87
 
23
- - Commands are thin wrappers: parse options, call `src/api.js`, format output, and exit.
24
- - Shared logic (key resolution, error formatting, output) goes into `src/lib/cli-utils.js`.
25
- - Each command file exports an async function; no side effects on load.
26
- - Skills are versioned source assets that guide use of one or more real CLI workflows. They are maintained with the corresponding command surface, but are not included in the npm package unless an explicit skill distribution mechanism is added.
88
+ ### 新增平台接口
27
89
 
28
- ## Build, Test, and Development Commands
90
+ - 先到 platform 侧读插件与 `api_docs`(见「配套项目:aiconductor-platform」),搞清上游依赖与超时预算,再动 CLI。
91
+ - 鉴权有两套并存写法,照 `api_docs` 与相邻实现选,不要"统一":搜索、热榜、网页列表/删除、R2 上传、小红书发布、抖音视频搜索、`wx_*` 全系用 `Authorization: Bearer <key>`;发布类(`html_publish`、`md_to_html`)与多数抖音接口把 `api_key` 放进请求体。
92
+ - 业务失败可能出现在 HTTP 200 的响应体里:`api.js` 内抛 `api_error`(搜索、热榜,以及用 `throwOnBusinessFailure` 包一层的 `wx_*`),或命令层用 `throwOnApiFailure`(网页列表/删除)。新接口选一种并补测试。
93
+ - 响应先过 `stripBilling`,`billing` 不进任何输出。
29
94
 
30
- - `node bin/aiconductor-cli.js --help` — run locally without a build step
31
- - `npm install` — install the single runtime dependency (`commander`)
32
- - `npm test` — run the Node.js built-in test suite (`node --test`)
95
+ ### 维护 skill
33
96
 
34
- ## Coding Style & Naming Conventions
97
+ - 目录名、frontmatter `name`、实际调用的命令必须一致;`description` 写能力 + 用户原话触发 + 与相邻 skill 的边界(简报→content-briefing,单点搜索→doubao-search,网页→webpage-publish,抖音数据→douyin-toolbox,抖音文案→douyin-script-extract,抖音选题→douyin-topic-radar,抖音评论→douyin-comment-insight,抖音账号→douyin-account-analyze,小红书→xhs-note-publish)。
98
+ - `SKILL.md` 只放路由、决策、命令行、响应路径、安全规则;长选项表、安装与密钥恢复放 `references/`,并写明何时读。
99
+ - 默认 JSON 输出,文档写稳定的 `data.data.*` 路径(`outputResult` 会额外包一层 `{success, data}`)。
100
+ - 用户请求执行即等同授权:不要每次预检安装或密钥;安装说明只在需要时读一次,修复后重试原命令一次。
101
+ - 安装说明被复制成 9 份 `references/aiconductor-skills-setup.md`(技能是独立安装单元,无法跨目录引用);改它必须同步 9 份。改完跑 `md5sum .codex/skills/*/references/aiconductor-skills-setup.md | awk '{print $1}' | sort -u | wc -l`,结果必须是 **1**。
35
102
 
36
- - 2-space indentation, no tabs
37
- - CommonJS (`require` / `module.exports`), no ESM
38
- - camelCase for JS identifiers; snake_case for API request fields
39
- - Every exported function gets a JSDoc block describing parameters and return type
40
- - Use `const` by default; `let` only when reassignment is needed
41
- - No formatter or linter configured — follow surrounding code style
103
+ ### 上架到 WorkBuddy
42
104
 
43
- ## Error Handling
105
+ 对外发布的技能比仓库内自用的多一层要求,规范全文在 `references/workbuddy技能规范.md`:
44
106
 
45
- - Never swallow errors with empty `catch`. At minimum, log and re-throw.
46
- - API errors carry a `.type` property (`http_error`, `network_error`, `validation_error`, `api_error`)
47
- - Commands exit with code 0 on success, 1 on failure
107
+ - **frontmatter 8 项必填**:`name`、`display_name`、`display_name_en`、`description`、`description_zh`、`description_en`、`version`、`author`;`author` 固定写 `"AI指挥家"`(带引号)。缺一项详情页就是残的。
108
+ - **`examples_zh` / `examples_en` 各 3 条**,展示在详情页「试试这样用」;用真能跑通的链接,别塞占位符。
109
+ - **正文顶部写 `## 概述`**,口吻是"默认已装好 CLI 与 API Key",只有出错时才引导去读 `references/aiconductor-skills-setup.md`。用户第一眼要看到能力,不是安装步骤。
110
+ - **别在正文里谈钱**:价格、单价、扣费规则、"免费"这类内容不进 `SKILL.md`——用户读技能时感觉自己在按次付费就会心疼,这是体验问题。该保留的行为约束改写成与钱无关的说法("重跑会再扣一次下载费" → "重跑等于从下载重来一遍");但故障解释里该说还得说,"余额不足"能帮用户定位问题。
111
+ - **子资源用 Markdown 链接** `[references/x.md](references/x.md)`,不用规范文档里的 `@references/x.md`:全库实测 0 处 `@`、549 处链接,已上架的 `xhs-note-publish` 也是链接。
112
+ - **交付物就是可上传的目录本身**:`SKILL.md` + `references/`(必要时 `scripts/`)随目录走,不依赖仓库内其他路径——技能是独立安装单元。交付时另附一份可直接复制进后台的清单:中英名、中英简介、3 条案例、作者、版本。
48
113
 
49
- ## Testing Guidelines
114
+ ## 关键机制(改代码前必读)
50
115
 
51
- Use the Node.js built-in test runner via `npm test`. Place tests next to the module they cover when practical (for example, `src/commands/web_search.test.js`).
116
+ - **输出分层**:`outputResult` 在 JSON 模式打印 `{success:true, data:<API 原始响应>}`,服务端字段落在 `data.data.*`(如 `content briefing` 的 `data.data.sources`);text 模式只打印自定义 formatter 的文本。错误一律走 stderr:JSON 为 `{success:false, error}`,text 为 `✗ 错误: ...`。
117
+ - **退出码**:成功 0、失败 1,每个处理函数结尾显式 `process.exit()`,因此 `await` 之后的收尾逻辑不会执行。不带参数调用时 Commander 直接向 stderr 打帮助并退出 1(bin 末尾的 `outputHelp()` 在该路径不可达)。
118
+ - **错误分类**:`http_error`(状态码 >= 400)、`network_error`、`validation_error`(本地参数校验)、`api_error`(HTTP 200 但业务失败);`handleApiError` 按 `.type` 生成中文提示。新抛错带 `.type`。
119
+ - **传输层**:请求打到 `plugin.aiconductor.fun/api/<endpoint>`。多数走 HTTPS;`hot_list_mixed` 与 `xhs_hot_list` 走明文 HTTP(`transport = http`,`api_docs` 也写作 `http://`,测试锁定 `port 80`)。线上 HTTPS 同样可达,属历史选择,别当成必须。
120
+ - **本地先校验**:`validatePositiveInt` / `validateInt` 与各命令的显式检查负责区间(`limit` 1–30、搜索 `count` 网页 ≤ 50 / 图片 ≤ 5、图文 ≤ 18 张等),失败不请求、不计费。
121
+ - **`webpage publish` 分流**:按扩展名或内容特征判定 `md`/`html`(`--type` 可强制)。html 分支直接打 `html_publish`,md 分支打 `md_to_html` 并支持 `--copy-button`;两者是不同端点。
122
+ - **小红书发布是两段式**:本地文件或 Base64 先经 `r2Upload` 换成临时公开 URL(`valid_days` 仅 1 或 7,默认 7;图片单张 ≤ 32MB,本地视频 ≤ 100MB),再调用计费接口生成 H5 页与二维码。Base64 参数支持 `@文件路径`。
123
+ - **热点简报是部分成功语义**:热榜与小红书热榜并行请求,任一成功即返回 `success:true`,失败写入 `data.failed_sources` / `data.failed_services`;仅两个服务都失败才退出 1。不要简化成"全有或全无"。
124
+ - **`wx` 组线上真实字段**(2026-11-04 实测调用):`wx_article_data` 返回 `read` / `zan` / `looking`(在看)/ `share_num` / `collect_num` / `comment_count`;`wx_history_articles` 用 `--name` 定位时业务层只有 `mp_nickname` 与 `mp_ghid`——**`api_docs` 写的 `mp_wxid` / `head_img` 实际不返回**;文章项字段与文档一致(`post_time_str` / `read` / `zan` / `original` / `url` / `digest`)。改 formatter 按实测字段,不要按文档新增字段。
125
+ - **抖音字段单位不统一**:`video-search` 的 `video.duration` 是**毫秒**,`user-videos` 的 `duration` 是 `"MM:SS"` 字符串——同名不同单位,跨端点复用代码必翻车。
126
+ - **抖音时间戳是北京时间编码**:`create_time` 按 UTC 渲染出来就是北京时间,**不要再 +8 小时**(2026-10-28 实测 `video-search`/`video-comments`/`user-videos` 三处:+8 会让半小时前发的视频落到 7 小时后)。`user-videos` 另带 `create_time_formatted`,同口径。
127
+ - **密钥解析**:`-k` > `AICONDUCTOR_API_KEY` > **当前工作目录**的 `.env`(不向上查找);缺失时 `resolveKeyOrExit` 打印错误并退出 1。
52
128
 
53
- For changes to a CLI contract (commands, arguments, options, output, or errors), verify:
54
- - The affected `--help` output exposes the intended command surface.
55
- - A representative successful response is parsed and formatted correctly.
56
- - A representative validation, authentication, or upstream API failure reports a non-zero exit path with useful error output.
129
+ ## 禁区
57
130
 
58
- ## Skill Design & Maintenance
131
+ - 不输出、不提交 `billing`、API Key、`.env` 内容、Base64 素材;密钥只走环境变量或命令行参数。
132
+ - 不手改 `api_docs/` 去迁就实现——它是接口契约(源头在 platform),契约变了才更新,并同时改测试。
133
+ - 不把 platform 侧计费单价写进 CLI 代码、README 或测试断言(价格在 `api_services` 表)。
134
+ - 不把 `hot_list_mixed` / `xhs_hot_list` 的明文 HTTP 顺手改成 HTTPS(测试锁定 `port 80`;确需改则测试、文档一起改并验证线上)。
135
+ - 不在命令文件里重写 HTTP、鉴权或格式化,不在 `src/lib` 之外复制共享工具。
136
+ - 不新增运行时依赖、不引入 ESM(当前只有 `commander`,用原生 `http/https`)。
137
+ - 不在 `src/` 内注册命令;命令注册只在 `bin/aiconductor-cli.js`。
59
138
 
60
- Skills in `.codex/skills` turn the CLI's verified capabilities into agent workflows. Keep them concise and operational; do not treat them as a second, independently authored API reference.
139
+ ## Agent 自主决策与复用约定
61
140
 
62
- ### Structure & Triggering
141
+ - 默认复用:`httpPost` / `stripBilling` / `validatePositiveInt` / `outputResult` / `handleApiError` / `resolveKeyOrExit`;新增代码照同目录文件写,不另起一套。
142
+ - 默认选型:CommonJS + `commander` + 原生 `http/https` + `node:test`;不引入 axios、node-fetch 或测试框架。
143
+ - 目录落点:一组命令一个 `src/commands/<组>.js`;HTTP 接口进 `src/api.js`;纯函数(格式化、聚合)留在命令文件内并导出以便测试。
144
+ - 直接做:读改代码、跑 `npm test`、跑 `--help`、`npm pack --dry-run`。
145
+ - 先确认:`npm publish`/发版、`git push`、技能上架到 WorkBuddy、任何带 API Key 的真实计费调用(`search`、`douyin`、`xhs`、`content`、`wx`)、`webpage delete`(不可逆,会失效公开链接)、批量改写 skills。
146
+ - 缺 API Key 时提示配置方式,不伪造、不复用示例输出。接任务先补齐背景、交付物、不做边界、约束、验收;"优化一下/完善一下"先翻译成可测量标准(哪条命令、哪个字段、什么退出码)。
63
147
 
64
- - The skill directory name and the `name` field in `SKILL.md` frontmatter must identify the same skill.
65
- - The frontmatter `description` must state the capability, likely user phrasing or context, and boundaries with adjacent skills. Define one clear owner for overlapping workflows so similar skills do not compete for the same request.
66
- - Keep `SKILL.md` focused on routing, decisions, command invocation, response handling, and safety rules. Move long option tables, platform-specific setup, and detailed background material into `references/`, and state exactly when that reference should be read.
67
- - Add `scripts/` only for deterministic, reusable work that avoids repeated implementation. Do not add scripts solely to wrap a single documented CLI command.
68
- - Add platform-specific metadata (such as files under `agents/`) only after validating its schema and behavior in the target runtime. Remove obsolete or unverified metadata rather than preserving it by convention.
148
+ ## 最短验证闭环
69
149
 
70
- ### CLI Contract & Execution
150
+ `npm test`(25 个用例,离线打桩,不需要 API Key)。改动涉及 `bin/`、`README.md`、skill 文字或新增命令时,再补一条人工核对:`node bin/aiconductor-cli.js <组> <子命令> --help`——`bin/` 的接线没有自动化测试覆盖。
71
151
 
72
- - Derive command names, arguments, option names, defaults, response fields, and error semantics from the local `--help` output, implementation, or tests. Do not copy stale documentation or infer unsupported behavior.
73
- - Default to JSON output and document stable response paths for the information the agent must return. Use text output only when the user asks for terminal-readable results.
74
- - A user's request for a CLI operation authorizes direct execution. Do not preflight installation, API Key availability, or environment setup on every invocation.
75
- - Put installation, upgrade, and API Key recovery instructions in an on-demand reference. Read it only when the user requests configuration or the command reports a missing CLI, authentication failure, or option/version incompatibility; after recovery, retry the original command at most once.
152
+ ## 任务执行与报告约定
76
153
 
77
- ### Safety & External Effects
154
+ 复杂任务先定位根因或明确方案,再拆分实施与验证;≤3 文件的局部改动直接改并验证。步骤 ≥3 用 todo 跟踪,一次一个 in_progress,做完立即标 completed。交付用通俗语言报告改了什么、验证结果(命令 + 实际输出)、对外影响(命令面、计费、技能)。
78
155
 
79
- - Never write, commit, or echo API Keys, `.env` content, Base64 media, or other sensitive user material.
80
- - Describe externally visible effects such as paid calls, temporary links, and public publishing accurately, including their success condition. Do not expose internal billing fields in user-facing output.
81
- - For irreversible actions, including deletion or invalidating public links, first show the exact target and obtain explicit confirmation unless the user already supplied the unique target and explicitly requested deletion.
156
+ ## 编码风格与命名约定
82
157
 
83
- ## CLI & Skill Synchronization
158
+ - 2 空格缩进,无 tab;CommonJS(`require` / `module.exports`),不写 ESM。
159
+ - JS 标识符 camelCase;请求字段用 API 的 snake_case(`need_content`、`max_pages`),映射在 `api.js` 完成,命令层保留 camelCase 选项名。
160
+ - 导出函数写 JSDoc(参数 + 返回类型);`const` 优先,必要时 `let`。
161
+ - 用户可见文本用中文;默认 JSON 输出,text 输出用 `✓` / `✗` 前缀与对齐字段名。
162
+ - 无 formatter/linter,跟随相邻文件风格。
84
163
 
85
- - When a command, argument, option, default, output shape, or error behavior is added, renamed, or removed, search for affected skills, README sections, and tests. Update all impacted artifacts in the same change.
86
- - New or changed skills must be added to Git with their `.codex/skills/**` files. Keep `.codex/` excluded from `.npmignore` so skills remain versioned repository assets without being included in the npm package.
87
- - Before finalizing a skill-related change, validate the referenced command's `--help` output and the documented JSON response path against implementation or tests.
164
+ ## 测试指南
88
165
 
89
- ## Commit & Pull Request Guidelines
166
+ - 框架:Node 内置 `node:test` + `node:assert/strict`,`npm test` 一次跑完;测试与模块同目录(目前集中在 `src/api.test.js`)。
167
+ - 网络必须打桩:`captureRequest` 替换 `https.request` / `http.request`,断言 `options.path`、`options.port`、`Authorization` 与请求体,同时校验返回值。测试不依赖 API Key、不发真实请求。
168
+ - 期望值独立于实现:请求字段以 `api_docs/<endpoint>.md` 为准;text 输出断言关键行(如 `结果数`、`URL`、`H5 地址`),不用整段快照。
169
+ - CLI 契约改动覆盖三类:`--help` 暴露的命令面(人工核对)、成功响应的解析与格式化(单测)、校验/鉴权/上游失败的非零退出(单测 + 一次手工失败调用)。
90
170
 
91
- From the existing history:
171
+ ## 提交与 PR 规范
92
172
 
93
- - Messages are in English, often prefixed with conventional commit tags: `feat:`, `fix:`, `refactor:`, `chore:`, `style:`, `ci:`
94
- - Agent-authored commits include `[Agent]` before the description
95
- - PRs should describe the change, note API surface impacts, and keep diffs focused
173
+ - 格式 `<tag>: <描述>`,tag 取自既有历史:`feat:`、`fix:`、`refactor:`、`docs:`、`skills:`、`search:`、`content:`、`release:`;agent 提交在前面加 `[Agent]`(如 `[Agent] release(cli): 1.4.0 —— ...`),描述可用中文。
174
+ - 发版提交只改 `package.json` + `package-lock.json` 的版本号;发版前先跑 `npm test`。
175
+ - 新增或修改 skill 必须随 `.codex/skills/**` 一起进 Git(`.npmignore` 已排除 `.codex/`,所以技能在仓库里版本化、不进 npm 包)。
176
+ - 历史只有单作者、无 PR 记录,可直接在 `master` 提交;若走 PR,描述写清命令面/API 影响与验证命令,保持 diff 聚焦。
96
177
 
97
- ## Adding a New Command
178
+ ## 安全与配置
98
179
 
99
- 1. Create `src/commands/<name>.js` with an async handler that calls `src/api.js`
100
- 2. Add the API function to `src/api.js` if it calls a new endpoint
101
- 3. Register the subcommand in `bin/aiconductor-cli.js`
102
- 4. Update `README.md` — command synopsis, option table, and example
180
+ - 只需一个环境变量 `AICONDUCTOR_API_KEY`(只写变量名,值不入库);解析顺序 `-k` > 环境变量 > 当前目录 `.env`。
181
+ - `.env`、`*.log`、`node_modules/` 已在 `.gitignore`;Base64 素材文件同样不得入库。
182
+ - 平台接口域名与各端点契约见 `api_docs/`,不要在代码外另维护第二份接口清单。
103
183
 
104
- ## Security & Configuration
184
+ ## 文档维护约定(常驻,不删除)
105
185
 
106
- - API Key is read from three sources in order: `-k` CLI argument → `AICONDUCTOR_API_KEY` env var → `.env` file
107
- - Never commit `.env` files or hardcoded credentials
186
+ 当本文档缺失/过时导致你走弯路时,在任务收尾顺手更新对应章节,只改受影响的最小范围。公共接口、命令、目录约定变化必须同步更新;一次性的会话经验不写入,只收下次还会踩的坑。
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AIConductor CLI
2
2
 
3
- AIConductor 平台命令行工具箱,提供网页发布、搜索、抖音数据和小红书扫码发布功能。
3
+ AIConductor 平台命令行工具箱,提供内容选题简报、网页发布、搜索、抖音数据和小红书工具。
4
4
 
5
5
  ## 安装
6
6
 
@@ -159,7 +159,7 @@ aiconductor-cli search image "长城风景" -n 3 --image-width-min 1200 --image-
159
159
 
160
160
  ### 热点选题简报
161
161
 
162
- 聚合多个平台的热点条目,为内容选题提供带来源链接的原料。默认查询知乎、微博、抖音和 AIHOT,每个来源返回 30 条。
162
+ 聚合多个平台热点与小红书实时热榜,为内容选题提供带来源链接的原料。默认查询知乎、微博、抖音和 AIHOT,每个来源返回 30 条,并额外请求一次小红书热榜。
163
163
 
164
164
  ```bash
165
165
  aiconductor-cli content briefing [选项]
@@ -181,7 +181,14 @@ aiconductor-cli content briefing -f text
181
181
  aiconductor-cli content briefing --sources aihot,hackernews,producthunt,juejin --limit 15 -f text
182
182
  ```
183
183
 
184
- 默认 JSON 输出会保留成功来源、缓存状态和失败来源,便于后续选题处理。部分来源失败时仍返回其他成功来源;仅成功返回数据的来源会计费。
184
+ 默认 JSON 输出保留以下字段,便于后续选题处理:
185
+
186
+ - `data.data.sources`:成功的综合热榜来源,兼容旧版本。
187
+ - `data.data.failed_sources`:综合热榜中失败的平台来源。
188
+ - `data.data.xhs_hot_list`:小红书热榜结果,包含日期与话题条目;小红书热榜接口失败时为 `null`。
189
+ - `data.data.failed_services`:综合热榜或小红书热榜接口级失败信息。
190
+
191
+ 任一服务成功时命令仍会返回可用数据;只有两个服务都失败时才退出失败。成功来源和成功的小红书热榜调用均按平台现有规则计费。
185
192
 
186
193
  ### 抖音数据工具箱
187
194
 
@@ -295,6 +302,19 @@ aiconductor-cli douyin link-to-text <视频URL> [选项]
295
302
  aiconductor-cli douyin link-to-text "https://www.douyin.com/video/xxxxx"
296
303
  ```
297
304
 
305
+ ### 小红书数据工具
306
+
307
+ 获取小红书实时热榜:
308
+
309
+ ```bash
310
+ aiconductor-cli xhs hot-list [选项]
311
+ ```
312
+
313
+ 示例:
314
+ ```bash
315
+ aiconductor-cli xhs hot-list -f text
316
+ ```
317
+
298
318
  ### 小红书扫码发布
299
319
 
300
320
  生成图文或视频笔记的 H5 发布页与二维码。素材支持公网 URL、本地文件、Base64/data URL,以及包含 Base64 内容的文本文件。
@@ -333,6 +353,27 @@ aiconductor-cli xhs note-publish video \
333
353
 
334
354
  本地文件会在 CLI 内转换成 data URL,与 Base64 素材统一通过 JSON 接口免费上传为临时公开 URL,不使用 multipart。图片合计最多 18 张、单张最多 32MB;本地/Base64 视频受上传接口限制为 100MB,URL 视频上限为 200MB。
335
355
 
356
+ ### 微信公众号数据工具
357
+
358
+ 两个子命令:取单篇文章的互动数据、取公众号历史文章列表。
359
+
360
+ ```bash
361
+ # 单篇文章互动数据(阅读 / 点赞 / 在看 等)
362
+ aiconductor-cli wx article-data "https://mp.weixin.qq.com/s?__biz=xxxx&mid=xxxx&idx=1&sn=xxxx"
363
+
364
+ # 公众号历史文章列表:用公众号名称或任意一篇文章链接定位
365
+ aiconductor-cli wx history --name "人民日报" --max-pages 3 --max-seconds 50
366
+ aiconductor-cli wx history "https://mp.weixin.qq.com/s?__biz=xxxx" -f text
367
+ ```
368
+
369
+ | 选项 | 适用命令 | 说明 | 默认值 |
370
+ |------|----------|------|--------|
371
+ | `--name <name>` | `history` | 公众号名称或微信 ID(与 `url` 至少提供一个) | 无 |
372
+ | `--max-pages <n>` | `history` | 最大翻页数量 | 1 |
373
+ | `--max-seconds <n>` | `history` | 最长运行时间(秒),上限 170 | 50 |
374
+
375
+ 返回路径:`article-data` 的互动数据在 `data.data`(`read` / `zan` / `looking` / `share_num` / `collect_num` / `comment_count`,text 模式渲染成阅读/点赞/在看/分享/收藏/评论,未知字段原样输出);`history` 的文章在 `data.data.data[]`(标题 `title`、时间 `post_time_str`、阅读 `read`、点赞 `zan`、链接 `url`)。
376
+
336
377
  ### 通用选项
337
378
 
338
379
  所有命令支持:
@@ -353,7 +394,10 @@ aiconductor-cli xhs note-publish video \
353
394
  | 抖音用户搜索 | 0.15 元/页 |
354
395
  | 抖音视频搜索 | 0.15 元/页 |
355
396
  | 抖音链接转文字 | 0.01 元/次 + 0.0003 元/秒 |
397
+ | 小红书热榜 | 以平台服务配置为准 |
356
398
  | 小红书扫码发布 | 0.05 元/次 |
399
+ | 公众号文章互动数据 | 以平台服务配置为准(按次) |
400
+ | 公众号历史文章列表 | 以平台服务配置为准(按成功翻页数) |
357
401
 
358
402
  > 搜索/调用失败不扣费,仅成功时计费。
359
403
 
@@ -365,8 +409,8 @@ cd aiconductor-cli
365
409
  npm install
366
410
  node bin/aiconductor-cli.js --help # 本地运行
367
411
  ```
368
-
369
- 贡献前请阅读 [AGENTS.md](./AGENTS.md) 了解项目结构、编码风格与提交流程。
412
+
413
+ 贡献前请阅读 [AGENTS.md](./AGENTS.md) 了解项目结构、编码风格与提交流程。
370
414
 
371
415
  ## License
372
416
 
@@ -12,7 +12,7 @@
12
12
  |--------|------|------|--------|------|
13
13
  | home_page | string | 是 | - | 抖音用户主页URL |
14
14
  | api_key | string | 是 | - | 计费系统API密钥 |
15
- | max_seconds | integer | 否 | 50 | 最长运行时间(秒),最大50 |
15
+ | max_seconds | integer | 否 | 50 | 最长运行时间(秒),内部上限 180 秒 |
16
16
  | max_pages | integer | 否 | 1 | 最大页数 |
17
17
 
18
18
  ## 响应参数
@@ -44,6 +44,6 @@
44
44
 
45
45
  ## 注意事项
46
46
  1. 支持抖音短链接和长链接,自动解析
47
- 2. max_seconds最大值为50秒
47
+ 2. max_seconds 最大值为 180 秒
48
48
  3. 按页收费,每成功获取一页数据扣费一次
49
49
  4. 达到时间限制或页数限制时会自动停止翻页