@miracleplus/mplus 0.2.2 → 0.2.3

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.
@@ -1,49 +1,78 @@
1
1
  /**
2
- * postinstall hook — 自动将 skills 安装到 ~/.agents/skills/
3
- * npm install -g @miracleplus/mplus 时自动执行
2
+ * postinstall hook — 自动分发 AI Agent 资源。
3
+ * npm install -g @miracleplus/mplus 时自动执行。
4
+ *
5
+ * 分发两类资源到用户级目录(父目录存在才铺,不凭空创建):
6
+ * - skills/ → ~/.agents/skills/(通用,总是)+ ~/.claude/skills/(Claude Code,若 ~/.claude 存在)
7
+ * - commands/ → ~/.claude/commands/(Claude Code 斜杠命令,若 ~/.claude 存在)
8
+ * + ~/.codex/prompts/(Codex 自定义命令,若 ~/.codex 存在)
4
9
  */
5
10
 
6
11
  const fs = require('fs');
7
12
  const path = require('path');
8
13
  const os = require('os');
9
14
 
10
- const skillsSource = path.resolve(__dirname, '..', 'skills');
11
- const skillsTarget = path.join(os.homedir(), '.agents', 'skills');
15
+ const root = path.resolve(__dirname, '..');
16
+ const skillsSource = path.join(root, 'skills');
17
+ const commandsSource = path.join(root, 'commands');
18
+ const home = os.homedir();
19
+
20
+ function exists(p) {
21
+ try {
22
+ return fs.existsSync(p);
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
12
27
 
13
28
  function copyDirSync(src, dest) {
14
29
  fs.mkdirSync(dest, { recursive: true });
15
- const entries = fs.readdirSync(src, { withFileTypes: true });
16
- for (const entry of entries) {
30
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
17
31
  const srcPath = path.join(src, entry.name);
18
32
  const destPath = path.join(dest, entry.name);
19
- if (entry.isDirectory()) {
20
- copyDirSync(srcPath, destPath);
21
- } else {
22
- fs.copyFileSync(srcPath, destPath);
23
- }
33
+ if (entry.isDirectory()) copyDirSync(srcPath, destPath);
34
+ else fs.copyFileSync(srcPath, destPath);
24
35
  }
25
36
  }
26
37
 
27
- // 静默执行:失败不阻塞安装
28
- try {
29
- if (!fs.existsSync(skillsSource)) {
30
- // 开发环境或 skills 目录未打包,跳过
31
- process.exit(0);
38
+ /** 把 skills/ 下每个子目录铺到每个目标 skills 根目录 */
39
+ function installSkills(targets) {
40
+ if (!exists(skillsSource) || targets.length === 0) return 0;
41
+ const dirs = fs.readdirSync(skillsSource, { withFileTypes: true }).filter((d) => d.isDirectory());
42
+ for (const target of targets) {
43
+ for (const d of dirs) copyDirSync(path.join(skillsSource, d.name), path.join(target, d.name));
32
44
  }
45
+ return dirs.length;
46
+ }
33
47
 
34
- const skillDirs = fs.readdirSync(skillsSource, { withFileTypes: true })
35
- .filter((d) => d.isDirectory());
36
-
37
- if (skillDirs.length === 0) {
38
- process.exit(0);
48
+ /** commands/ 下每个 .md 铺到每个目标命令目录 */
49
+ function installCommands(targets) {
50
+ if (!exists(commandsSource) || targets.length === 0) return 0;
51
+ const files = fs.readdirSync(commandsSource).filter((f) => f.endsWith('.md'));
52
+ for (const target of targets) {
53
+ fs.mkdirSync(target, { recursive: true });
54
+ for (const f of files) fs.copyFileSync(path.join(commandsSource, f), path.join(target, f));
39
55
  }
56
+ return files.length;
57
+ }
40
58
 
41
- for (const dir of skillDirs) {
42
- copyDirSync(path.join(skillsSource, dir.name), path.join(skillsTarget, dir.name));
43
- }
59
+ // 静默执行:失败不阻塞 npm install;用户可后续手动 mplus install-skills
60
+ try {
61
+ const hasClaude = exists(path.join(home, '.claude'));
62
+ const hasCodex = exists(path.join(home, '.codex'));
63
+
64
+ const skillTargets = [path.join(home, '.agents', 'skills')];
65
+ if (hasClaude) skillTargets.push(path.join(home, '.claude', 'skills'));
66
+
67
+ const commandTargets = [];
68
+ if (hasClaude) commandTargets.push(path.join(home, '.claude', 'commands'));
69
+ if (hasCodex) commandTargets.push(path.join(home, '.codex', 'prompts'));
70
+
71
+ const nSkills = installSkills(skillTargets);
72
+ const nCommands = installCommands(commandTargets);
44
73
 
45
- console.log(`mplus: ✓ ${skillDirs.length} AI skills installed to ${skillsTarget}`);
74
+ if (nSkills) console.log(`mplus: ✓ ${nSkills} AI skills installed (${skillTargets.length} 处)`);
75
+ if (nCommands) console.log(`mplus: ✓ ${nCommands} slash commands installed (${commandTargets.length} 处)`);
46
76
  } catch (err) {
47
77
  // 静默失败,不阻塞 npm install
48
- // 用户可以后续手动执行 mplus install-skills
49
78
  }
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: mplus-reports
3
+ version: 0.1.0
4
+ description: "奇绩创坛 DS 报告数据源:拉取线索/人脉统计明细(手机号 contacts、企微 soc_channel_users),支持按业务时间段(本期累计/本周/上期同比等)查询。当用户要统计奇绩线索来源、做周期/同比分析、或生成「线索来源周期对比报告」(DS 报告) 时使用。"
5
+ metadata:
6
+ requires:
7
+ bins: ["mplus"]
8
+ ---
9
+
10
+ # reports(DS 报告数据源)
11
+
12
+ **CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../mplus-shared/SKILL.md`](../mplus-shared/SKILL.md)(认证、登录、错误处理、`--json`)**
13
+
14
+ ## 这是什么
15
+
16
+ reports 提供「线索来源周期对比分析报告」(DS 报告) 的**数据源**。它返回某日期区间内的线索**原始明细**,你(AI)再按归属原则归类、聚合、套 prompt 生成报告。
17
+
18
+ - 两类数据源(各一条命令):
19
+ - **contacts**(手机号人脉)
20
+ - **soc_channel_users**(企微好友,别名 `qywechat`)
21
+ - 接口本质:「日期区间 → 原始明细」的瘦查询,只认 `start_date` / `end_date`。
22
+ - **归类与聚合是你的工作**:接口对渠道字段(`s_channel`/`s_product`/`utm_source`)做了中文映射(如 `inbound`/`创业营`/`公众号`),但**不做渠道归类**。你要按「归属原则」把线索归到 13 个报告渠道(见 [references/reports-query.md](references/reports-query.md) 的「归属规则」)。
23
+
24
+ ## 业务周期与 6 个时间段
25
+
26
+ 奇绩按**半年一期**(26 周):上半年 1/13–7/12、下半年 7/13–次年1/12。报告对比 6 个时间段,用 `--period` 一键指定(纯客户端换算成日期区间):
27
+
28
+ | `--period` | 含义 | 区间口径 |
29
+ |---|---|---|
30
+ | `benqi-leiji` | 本期累计 | 本期周期起始日 ~ 今天 |
31
+ | `shangqi-tongri-leiji` | 上期同日累计 | 上期周期起始日 ~ 今天−26周 |
32
+ | `shangshangqi-leiji` | 上上期累计 | 上上期周期起始日 ~ 今天−52周 |
33
+ | `benzhou` | 本周 | 本周一 ~ 今天 |
34
+ | `shangqi-tongzhou` | 上期同周 | 本周区间整体 −26周 |
35
+ | `shangshangqi-tongzhou` | 上上期同周 | 本周区间整体 −52周 |
36
+
37
+ > 命令输出会回显实际区间,便于核对。也可用 `--start-date`/`--end-date` 自定义(与 `--period` 互斥)。
38
+
39
+ ## 认证要求
40
+
41
+ reports 是**管理员命令**,需 `apply_admin` 角色。先 `mplus login`(OAuth)或 `mplus configure`(API Key)。非管理员看不到该命令。详见 mplus-shared。
42
+
43
+ ## 命令速查
44
+
45
+ | 命令 | 说明 | 参考 |
46
+ |---|---|---|
47
+ | `mplus reports contacts` | 手机号人脉明细 | [references/reports-query.md](references/reports-query.md) |
48
+ | `mplus reports soc-channel-users` | 企微好友明细(别名 `qywechat`) | 同上 |
49
+ | `mplus reports summary` | **周期对比聚合**:一条命令拉全 6 时段 + 归类 13 渠道 + 剥离批量数据 | [references/reports-query.md](references/reports-query.md) |
50
+
51
+ contacts / soc 参数相同:`--period <key>` 或 `--start-date`/`--end-date`,外加 `--profile`、`--json`;summary 只接 `--profile`/`--json`。
52
+
53
+ ## 自然语言 → 命令
54
+
55
+ | 用户说 | 命令 |
56
+ |---|---|
57
+ | 统计奇绩线索来源**本期**数据 | `mplus reports contacts --period benqi-leiji --json`(企微再调 `soc-channel-users`) |
58
+ | **本周**新增 | `mplus reports contacts --period benzhou --json` |
59
+ | 本期**与上期同比** | 调两次:`--period benqi-leiji` + `--period shangqi-tongri-leiji`,再对比 |
60
+ | 某个**自定义区间** | `--start-date 2026-03-01 --end-date 2026-03-31 --json` |
61
+
62
+ > 一份完整 DS 报告通常要 **2 类数据 × 6 个时间段 = 12 次调用**。
63
+
64
+ ## 生成 DS 报告的流程
65
+
66
+ **推荐:一条命令出聚合** —— `mplus reports summary --json` 对 6 时段 ×(手机号 + 企微)用 `mode=count` 拿原始字段组合计数,按归属规则归类到 13 渠道,聚合成「渠道 × 时段」(每段含 `total`、`channels` 各渠道 phone/qy/total)。**秒级**(约 5s),接口默认已剥离批量数据。
67
+
68
+ 1. **拉聚合**:`mplus reports summary --json`。
69
+ 2. **成文**:套报告 prompt(角色 = 销售数据分析助手),按 prompt 的**四段结构**:① 整体总结(本周结构与关键变化);② 本期累计/本周 vs 上期同日累计/上期同周;③ 本期累计/本周 vs 上上期累计/上上期同周;④ 管理层可关注的判断。②③ 用 `total`/`phone_total`/`qy_total` 做总量对比、`channels` 做 13 渠道逐条原因分析(表格);④ 给管理视角的判断与建议(结构分化、累计欠账、各渠道是节奏波动还是供给不足、复盘/清洗方向)。
70
+
71
+ 13 渠道:自然流量 / 创业社区 / 潜空间 / SS / 前沿信号 / 算力 / outbound汇总 / 大厂 / 高校 / 广告投放 / 北美 / mapping / 校友。
72
+
73
+ > summary 的归类是程序化近似(归属规则内嵌在 CLI,会随运营变动)。count 现已纳入 `source_other`(后端 Q6② 已加,「奇绩主编/PRteam→创业社区」已精确归类);但**仍不含 `qy_tag_names`**,故 soc 的「Olivia/Leo 标签细分」会降级(归 outbound汇总)。存疑渠道用 `reports contacts/soc-channel-users --json`(detail,中文字段、精度全)复核。
74
+
75
+ ## AI 使用建议
76
+
77
+ 1. **始终加 `--json`**:默认文本只给区间 + 条数;解析数据必须 `--json`。
78
+ 2. **同比要多次调用**:6 个时间段是 6 次独立请求,自己组合对比。
79
+ 3. **大区间用 count**:detail 半年级累计区间会超时;统计用 `--mode count`(秒级、不超时)。
80
+ 4. **字段差异**:信封字段是 `message`;数组 key——detail 为 `contacts`/`soc_channel_users`、count 为 `groups`;**detail 字段是中文(inbound/创业营)、count 是代码(ib/ba)**,归类时注意。
81
+ 5. **保护 PII**:明细含手机号 / 微信,不要直接回显给用户,按需聚合后再呈现。
@@ -0,0 +1,168 @@
1
+ # reports 查询(contacts / soc-channel-users)
2
+
3
+ > **前置条件:** 先用 Read 工具读取 [`../../mplus-shared/SKILL.md`](../../mplus-shared/SKILL.md)(认证、全局参数),以及 [`../SKILL.md`](../SKILL.md)(reports 概览、6 时间段、自然语言映射)。
4
+
5
+ 查询某日期区间内的线索原始明细。两个子命令同构:
6
+
7
+ - `mplus reports contacts` → `GET /open_api/v2/reports/contacts`(只返回有手机号的人脉)
8
+ - `mplus reports soc-channel-users` → `GET /open_api/v2/reports/soc_channel_users`(企微好友;别名 `qywechat`)
9
+
10
+ 均为**管理员命令**(需 `apply_admin` 角色),走 apply 主站 open_api(API Key 换 JWT,或 OAuth access token,由 CLI 自动处理)。
11
+
12
+ ## 命令示例
13
+
14
+ ```bash
15
+ # 本期累计(推荐用 --period,自动换算区间)
16
+ mplus reports contacts --period benqi-leiji --json
17
+
18
+ # 本周企微新增
19
+ mplus reports qywechat --period benzhou --json
20
+
21
+ # 自定义区间(与 --period 互斥)
22
+ mplus reports contacts --start-date 2026-03-01 --end-date 2026-03-31 --json
23
+
24
+ # 同比:本期累计 vs 上期同日累计(调两次再对比)
25
+ mplus reports contacts --period benqi-leiji --json
26
+ mplus reports contacts --period shangqi-tongri-leiji --json
27
+
28
+ # 大区间统计用 count(秒级、不超时):按原始字段分组计数
29
+ mplus reports contacts --period shangqi-tongri-leiji --mode count --group-by s_channel,s_product,utm_source --json
30
+ mplus reports qywechat --period shangqi-tongri-leiji --mode count --group-by add_juzi_follow_user_earliest_name --json
31
+
32
+ # 过滤 + 字段裁剪
33
+ mplus reports contacts --period benzhou --s-channel ib --fields id,phone,s_channel --json # 过滤值用代码 ib(非中文 inbound)
34
+ ```
35
+
36
+ ## 参数
37
+
38
+ | 参数 | 必填 | 类型 | 默认 | 说明 |
39
+ |------|------|------|------|------|
40
+ | `--period <key>` | 否 | string | — | 便捷时间段,6 选 1:`benqi-leiji` / `shangqi-tongri-leiji` / `shangshangqi-leiji` / `benzhou` / `shangqi-tongzhou` / `shangshangqi-tongzhou`。**与 `--start-date`/`--end-date` 互斥** |
41
+ | `--start-date <date>` | 否 | string | 当期周期起始日 | `YYYY-MM-DD`,区间开始 |
42
+ | `--end-date <date>` | 否 | string | 今天 | `YYYY-MM-DD`,区间结束 |
43
+ | `--mode <mode>` | 否 | string | `detail` | `detail`=明细;`count`=计数统计(返回 `groups`+`total`,大区间秒级、不超时) |
44
+ | `--group-by <fields>` | 否 | string | — | 仅 count:按原始字段分组 CSV,如 `s_channel,s_product,utm_source`(contacts)/ `add_juzi_follow_user_earliest_name`(soc) |
45
+ | `--fields <fields>` | 否 | string | 全量 | 只返回指定字段,CSV |
46
+ | `--date-field <field>` | 否 | string | `created_at` | 按哪个时间字段过滤区间 |
47
+ | `--page <n>` / `--page-size <n>` | 否 | int | 1 / — | 仅 detail,分页 |
48
+ | `--include-batch` | 否 | bool | 关 | 默认接口已剥离批量数据;加此开关才包含 |
49
+ | `--meeting-success <bool>` | 否 | string | — | 按是否成功开会过滤 |
50
+ | contacts 过滤 | 否 | string | — | `--s-channel`/`--s-product`/`--utm-source`/`--utm-campaign`/`--utm-content`/`--s-referral`(**值用原始代码**,如 `--s-channel ib`、`--utm-source gzh`,**不是**中文 inbound/公众号) |
51
+ | soc 过滤 | 否 | string | — | `--channel-type`/`--early-follower`/`--qy-tag`/`--qy-tag-match`(any\|all\|none) |
52
+ | `--profile <name>` | 否 | string | 当前 profile/session | 临时指定,不改变默认 |
53
+ | `--json` | 否 | boolean | false | 输出完整 JSON 响应 |
54
+
55
+ ## 6 个时间段的区间口径
56
+
57
+ 业务周期半年一期(26 周):上半年 1/13–7/12、下半年 7/13–次年1/12。`--period` 换算规则:
58
+
59
+ | key | start_date | end_date |
60
+ |---|---|---|
61
+ | `benqi-leiji` 本期累计 | 本期周期起始日(1/13 或 7/13) | 今天 |
62
+ | `shangqi-tongri-leiji` 上期同日累计 | 上期周期起始日 | 今天 − 26 周 |
63
+ | `shangshangqi-leiji` 上上期累计 | 上上期周期起始日 | 今天 − 52 周 |
64
+ | `benzhou` 本周 | 本周一 | 今天 |
65
+ | `shangqi-tongzhou` 上期同周 | 本周一 − 26 周 | 今天 − 26 周 |
66
+ | `shangshangqi-tongzhou` 上上期同周 | 本周一 − 52 周 | 今天 − 52 周 |
67
+
68
+ > 口径(已按刘绍栋 prompt 定稿):周期边界取 prompt 口径(7/13 起下半年);同日/同周用 26/52 周整体平移近似半年/一年。命令输出会回显实际区间,可核对。
69
+
70
+ ## 响应结构
71
+
72
+ 统一信封 `{ code, message, data }`(**注意:字段是 `message`,不是 `msg`**)。
73
+
74
+ **detail 模式**(明细行):
75
+
76
+ ```json
77
+ { "code": 0, "message": "success",
78
+ "data": { "start_date": "2026-01-13", "end_date": "2026-06-08",
79
+ "contacts": [ { "id": "...", "phone": "...", "s_channel": "inbound", "s_product": "创业营", "utm_source": "公众号", ... } ] } }
80
+ ```
81
+
82
+ **count 模式**(`--mode count`,计数统计):
83
+
84
+ ```json
85
+ { "code": 0, "message": "success",
86
+ "data": { "start_date": "2026-01-13", "end_date": "2026-06-08", "total": 7766,
87
+ "group_by": ["s_channel","s_product"],
88
+ "groups": [ { "s_channel": "ib", "s_product": "ba", "count": 125 } ] } }
89
+ ```
90
+
91
+ - `code` = 0 表示成功;非 0 时看 `message`。
92
+ - 数组 key:**detail** 模式 contacts 接口为 `contacts`、soc 接口为 `soc_channel_users`;**count** 模式两者均为 `groups`(每组 `{分组字段..., count}`)+ `total`。
93
+ - **字段值差异(重要!)**:**detail** 的渠道字段是**中文映射值**(`s_channel="inbound"`、`s_product="创业营"`、`utm_source="公众号"`);**count** 的 groups 字段是**原始代码**(`s_channel="ib"`、`s_product="ba"`、`utm_source="gzh"`)。归类到 13 渠道仍需自行按下方「归属规则」完成——**detail 用中文匹配、count 用代码匹配**。
94
+
95
+ ### contacts 字段(21)
96
+
97
+ `id, wechat_unionid, phone, email, wechat, msg_active, contact_method, created_at(录入时间), revisit_at(最新跟进), confirm_meeting_at, meeting_at, successful_contact_at, contact_at, meeting_success, s_product(来源产品), s_channel(渠道大类), utm_source(一级渠道), utm_campaign(二级渠道), utm_content(三级渠道), source_other(来源备注), s_referral(分享人)`
98
+
99
+ ### soc_channel_users 字段(11)
100
+
101
+ `id, unionid, add_juzi_follow_user_earliest_name(最早托管账号), qy_tag_names(企微标签,逗号分隔), created_at, revisit_at, successful_contact_at, contact_at, confirm_meeting_at, meeting_at, meeting_success`
102
+
103
+ ## 归属规则(把原始明细归到 13 个报告渠道)
104
+
105
+ 报告拆分渠道:自然流量、创业社区、潜空间、SS、前沿信号、算力、outbound汇总(外部活动/学术活动/政府活动/Github)、大厂、高校、广告投放、北美、mapping、校友。
106
+
107
+ > 来源:飞书「提交归属原则」表。以下为规则要点,最终以该表为准。
108
+
109
+ ### 手机号(contacts)— 按 `s_channel`/`s_product`/`utm_source`(一级)/`utm_campaign`(二级)/`source_other`(备注)
110
+
111
+ | 归属 | 规则 |
112
+ |---|---|
113
+ | 自然流量 | `s_channel`=inbound + 产品∉{潜空间,公开课,前沿信号,算力} + 一级∉社媒* + 备注∉{奇绩主编,PRteam} |
114
+ | 创业社区 | inbound + 产品∉{潜空间,公开课,前沿信号,算力} + (一级∈社媒* 或 备注∈{奇绩主编,PRteam}) |
115
+ | 潜空间 / SS / 前沿信号 / 算力 | inbound + 产品 = 潜空间 / 公开课 / 前沿信号 / 算力 |
116
+ | 外部活动 | outbound + 创业营 + 一级=外部活动 + 二级∉{学术活动,政府活动,大厂/媒体活动} |
117
+ | 学术活动 / 政府活动 | outbound + 创业营 + 外部活动 + 二级 = %学术活动% / %政府活动% |
118
+ | Github(跑活动) | outbound + 创业营 + 一级=外部平台 |
119
+ | 大厂 | outbound + 创业营 + 二级 = %大厂/媒体活动% |
120
+ | 高校 | outbound + 创业营 + 一级=高校 |
121
+ | 广告投放 | `s_channel` = 广告投放 |
122
+ | 北美 | `s_channel` = Researcher Founder + 创业营 |
123
+ | mapping (RF) | Researcher Founder + 潜空间 + 一级=researcher |
124
+ | 校友 | `s_channel` = 校友 |
125
+ | 其他(未归类) | 总计 − 所有已归类 |
126
+
127
+ > *社媒 = {公众号,B站,视频号,小红书,小宇宙,抖音,即刻,X,Instagram,GitHub,Linkedln,知乎,YouTube}
128
+
129
+ ### 企微(soc_channel_users)— 按 `add_juzi_follow_user_earliest_name`(账号) + `qy_tag_names`(标签)
130
+
131
+ | 归属 | 账号 / 标签 |
132
+ |---|---|
133
+ | 创业社区 | 账号∈{大模型空间站小助手1-3号, 奇绩创业社区助手1/2/6号} |
134
+ | 潜空间 | 账号 = 潜空间小助手 |
135
+ | SS | 账号∈{创业公开课小助手/④/⑤, 高校巡讲小助手} |
136
+ | 算力 | 账号 = 刘婷婷 |
137
+ | 外部活动/学术/政府/Github | 账号∈{Olivia,Leo} + 标签=%外部活动%(排除学术/政府/大厂) / %学术活动% / %政府活动% / %外部平台% |
138
+ | 数据运营 | 账号∈{吴冰冰, 陈知微, 奇绩创业营申请助手} |
139
+ | 大厂 | 账号=李思睿;或 {Olivia,Leo}+标签%大厂/媒体活动% |
140
+ | 高校 | 账号 = 高校创业社区助手 |
141
+ | 广告投放 | 账号∈{奇绩创业社区助手4号, 张晓微, 蒋瑶瑶, 李佳冉, 张小微, 张晓薇} |
142
+ | 北美 | 账号 = 奇绩海外创业者社区小助手 |
143
+ | mapping (RF) | 账号 = Researcher Founder 助手 + 标签%原始来源产品>潜空间%;或 账号=Mark |
144
+ | 校友 | 账号 = 产品日小助手 |
145
+ | 其他(未归类) | 总计 − 所有已归类 |
146
+
147
+ ## 已知限制
148
+
149
+ - **detail 大区间会超时**:detail 返回全量明细,半年级累计区间服务端扫描慢(易 60s 超时)。**统计大区间用 `--mode count`**(不返明细、秒级、不超时),或缩小区间。
150
+ - **批量数据**:接口默认 `exclude_batch`(已剥离工商导入的批量数据);要包含用 `--include-batch`。
151
+ - **PII**:detail 含手机号/微信,聚合后再呈现勿直接回显;count 模式只返计数,无 PII。
152
+
153
+ ## 常见错误
154
+
155
+ | 现象 | 原因 | 解决 |
156
+ |------|------|------|
157
+ | `错误:未知命令:reports` | 当前账号非管理员(admin 命令对非 admin 隐藏) | 用 `apply_admin` 账号登录 |
158
+ | `OAuth 鉴权失败,请运行 mplus login 重新登录` | token 失效 | `mplus login` |
159
+ | `服务器错误,请稍后重试` | 大区间全量明细致后端 5xx | 缩小日期区间分段查询 |
160
+ | `--period 仅支持:...` | period 取值非法 | 用 6 个合法 key 之一 |
161
+ | `--start-date 格式应为 YYYY-MM-DD` | 日期格式错 | 用 `YYYY-MM-DD` |
162
+ | `--period 与 --start-date/--end-date 不能同时使用` | 两者互斥 | 二选一 |
163
+
164
+ ## 参考
165
+
166
+ - [mplus-reports](../SKILL.md) — reports 概览、6 时间段、报告生成流程
167
+ - [mplus-shared](../../mplus-shared/SKILL.md) — 认证和全局参数
168
+ - `doc/8-reports接口与CLI.md`(仓库内)— 接口契约 + 上层 CLI 能力