feat(huanxi): 拆为个人端 / 管理端两个插件,技能全面对齐寰汐 v2

寰汐 v2 上线双 MCP(个人端 /mcp/ 与管理端 /admin-mcp/),两条端点是**两条独立的
信任边界**——Token 前缀不同、工具集不同、视角不同(管理端看全量、个人端只看我参与的)。
一个插件塞两套会让普通员工的客户端里出现他根本调不动的管理工具,因此拆成两个插件,
按角色各装各的。

## huanxi(个人端,全体员工)

7 个技能:shared / report / leader / task / issue / meeting / org

- 新增 `issue` `meeting`——v2 的议题域与会议域(M6v2 会议×议题解耦后的产物)
- **删除 `weekly`**——v2 没有 weekly_report 表,周报已并入报告体系
- 各技能重写为**流水线定义**而非使用说明:写明工具调用顺序、ID 在步骤间怎么传、
  人工确认节点落在哪。「禁止自动提交」这条 v1 已验证的硬约束保留
- 删掉 `references/` 拆分文件——v2 技能自包含

## huanxi-admin(管理端,仅后台管理员)

4 个技能:admin-shared / admin-report / admin-module / admin-ops

MCP server key 取 `huanxi-admin`(与个人端的 `huanxi` 不同名),否则两插件并存时
会键冲突。

## 缓存目录按信任边界隔离

`~/.claude/huanxi-cache/` 下分 `personal/` `admin/` `dict/`:前两者视角不同,
混用会越权展示或数据错乱;`dict/` 与身份无关可共享。业务数据(任务/日报/会议/议题)
**显式声明不缓存**——v1 没写这条,Agent 会自行决定缓存然后拿到陈旧数据。

## 源码单一真相不在本仓库

技能源码在寰汐仓库 `skills/`,与 MCP docstring 同仓库同 commit——签名一改,
技能与工具在同一次改动里更新,从结构上消除跨仓库漂移(本仓库记忆
`feedback_plugin_dev.md` 记录的 4 类漂移覆盖全部 6 个 v1 技能,正是这个病)。
本仓库退化为**分发壳**,只接收 `python skills/sync_marketplace.py` 的产物,不手工编辑。

寰汐侧有 CI 守卫:技能里出现的每个工具名必须存在于实际注册表、个人端技能不得
指导调用管理端独有工具、不得硬编码状态字面量。

## 本分支不合 main

插件配置的域名此刻跑的还是 v1,合进 main 会通过自动更新推给已安装用户,
他们的技能会去调 v1 上不存在的工具。合并前置条件写在 CLAUDE.md「已发布插件」节。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Vyeia9k43dVaUFNLo8Lny
This commit is contained in:
SkyJourney
2026-08-06 18:56:55 +08:00
co-authored by Claude Opus 5
parent d7aaaf8224
commit 4ce9a92013
24 changed files with 744 additions and 1103 deletions
+54 -84
View File
@@ -1,106 +1,76 @@
---
name: huanxi-report
description: "寰汐员工日报工作流:查看今日日报状态(+check)、保存草稿(+draft)、提交日报(+submit)、撤回日报(+withdraw。当用户说"帮我写日报"、"填日报"、"提交日报"、"查看今日汇报情况"时触发。"
description: "寰汐员工日报:查看今日状态、填写并提交日报、撤回修改。当用户说帮我写日报」「填日报」「提交日报」「今天要报什么」时使用。"
---
# 寰汐员工日报
**前置条件:先 Read `../huanxi-shared/SKILL.md`(缓存规则 + TTL 策略)**
> ⚠️ **工具调用规范**:执行任何 `mcp__huanxi__*` 调用前,以工具实际注册的参数名和类型为准,本文档示例仅供工作流引导(见 shared 全局约定第 6 条)。
**前置:先读 `huanxi-shared`(缓存策略、状态模型、确认约定)。**
---
## 标准工作流(完整流程
## 标准流程
```
Step 0: 确认身份
→ Read ~/.claude/huanxi-cache/me.json(永久缓存)
→ 若 me.json 为空:mcp__huanxi__user_get_me() → 写入缓存
Step 1 report_get_context(date?)
↓ 一次拿全:是否工作日、是否免报、整体状态、按模块分组的待汇报条目
↓ 非工作日 → 告知并询问是否仍要填(不中断)
↓ 已全部提交 → 转「修改已提交内容」分支
↓ 免报日 → 告知无需提交,询问是否仍要记录
Step 1: 检查是否工作日
→ 查 workdays.json["今日日期"]
→ 未缓存:mcp__huanxi__system_get_workday() → 追加写入 workdays.json
→ 非工作日:告知用户,询问"是否仍要填写?"(不强制中断)
Step 2 展示待汇报任务,引导用户逐条说今天做了什么
↓ 每条记住 task_id(后续提交要用)
↓ 用户说不清的任务,可用 task_get 补上下文,不要替他编
Step 2: 查看今日日报状态
→ mcp__huanxi__report_get_today()
→ submitted → 告知"今日已提交",询问是否撤回
→ draft/empty → 继续 Step 3
Step 3 (可选)润色
↓ 你自己润色即可,**不要找工具**——你就是那个语言模型
↓ 展示润色前后,让用户选
Step 3: 获取待汇报任务并收集内容
→ mcp__huanxi__report_get_tasks_to_report()
→ 返回的每个任务条目含:idtask_id)、title、module_id、module_name、progress 等
→ 展示待汇报任务列表(任务名、模块、当前进度)
→ 引导用户逐一填写今日进展和完成百分比
→ 详见 references/report-draft.md
Step 4 report_save_draft(items=[...])
↓ 存草稿,此时还没提交
↓ 今天不报某条 → 该项加 dismissed=true;恢复 → restore=true
Step 4: 保存草稿并展示初稿
→ mcp__huanxi__report_save_draft(items=[...])
→ ⚠️ items 字段以 MCP docstring 为准;每条必须带 module_id(取自 Step 3 任务条目)
→ 展示完整初稿内容供用户预览
Step 5 ⏸ 展示完整初稿,等待用户明确确认
Step 5: 询问是否 AI 润色
→ 询问用户:"是否需要 AI 润色优化表达?"
→ 用户同意 → mcp__huanxi__llm_polish_report(content=<初稿内容>)
→ 展示润色后版本,与初稿对比
→ 用户选择采用润色版或保留原版
→ 若采用润色版:mcp__huanxi__report_save_draft(items=[...]) 更新草稿
→ 用户拒绝 → 直接进入 Step 6
Step 6 report_submit(task_ids=[...])
↓ 只提交确认过的那些;不传 task_ids 则提交全部草稿
```
Step 6: 确认并提交
→ 展示最终内容,等待用户明确确认("确认"/"提交"/"好的"等)
→ ⚠️ 未收到确认前,禁止调用 report_submit_item
→ 用户确认后:
a. mcp__huanxi__report_get_today() → 获取各条目的 item_id
b. 对每个需提交的草稿条目 → mcp__huanxi__report_submit_item(item_id)
c. 逐条提交,不影响其他条目
→ 详见 references/report-submit.md
**Step 5 不可省略。** 写日报和交日报是两个决定,用户可能只想先存着。
---
## 修改已提交内容
```
report_withdraw(task_ids=[...]) → 变回草稿
↓ 修改
report_save_draft(...)
↓ ⏸ 确认
report_submit(task_ids=[...])
```
**仅当天可撤回。** 隔天的日报已进入统计口径,撤回会被拒绝——这时应告诉用户去找管理员,
而不是反复重试。
---
## 查历史
```
report_history(scope="module", module_id=...) 某模块某天全体成员报了什么
report_history(scope="task", task_id=..., date_from=..., date_to=...)
某个任务被谁在哪天报过什么
```
---
## Shortcuts
## 几条容易踩的
| 指令 | 说明 |
|------|------|
| [`+check`](#check) | 查看今日日报状态(已提交/草稿/空) |
| [`+draft`](references/report-draft.md) | 读取待报任务并保存草稿 |
| [`+submit`](references/report-submit.md) | 提交当天日报(必须先确认) |
| `+withdraw` | 撤回已提交日报(询问确认) |
---
## +check:查看今日状态 {#check}
```
1. mcp__huanxi__report_get_today()
2. 展示:
- 提交状态(submitted / draft / 未填)
- 已填任务列表及内容摘要
- 未填/dismissed 任务
3. 若已提交:询问"是否需要撤回修改?"
4. 若草稿:询问"是否继续编辑并提交?"
```
---
## +withdraw:撤回日报
```
1. mcp__huanxi__report_get_today() → 获取各条目状态和 item_id
2. 展示已提交的条目列表,询问用户要撤回哪条(可多选)
3. 等待用户确认(撤回后该条目变为草稿,其他已提交条目不受影响)
4. 对用户选择的每条 → mcp__huanxi__report_withdraw_item(item_id)
5. 告知撤回成功,可重新编辑后用 report_submit_item 重新提交
```
---
## 关键约束
- **禁止自动提交**:Step 6 必须展示内容并等待用户明确确认("确认"/"提交"/"好的"等),不得自动调用 `report_submit_item`
- **逐条操作,不做全量**:提交/撤回必须使用 `report_submit_item` / `report_withdraw_item`(需传 item_id),禁止批量操作所有条目,除非用户明确要求"全部提交/撤回"
- **dismissed 状态**:用户主动标记"今天不汇报该任务",dismiss 的条目不计入汇报,不要提示用户补填
- **非工作日**:检测到非工作日时,明确告知但不中断,询问用户意愿
- **已提交则不重复操作**:Step 2 发现已提交时,不继续 Step 3-6,改为询问是否撤回
- **条目用 `task_id` 定位**,不是条目自身的 id。`report_get_context` 返回里的
`task_id` 就是后续 save/submit/withdraw 都要传的那个。
- **空内容不能提交**:服务端会拒。要么写点内容,要么标 `dismissed`
- **模块杂记**`is_module_misc`)承载零散工作,可以报也可以不报,但它**不计入
「未提交」统计**——用户只写了杂记不算完成当天汇报,提醒他还有别的任务没写。
- **`progress_update` 是任务进度**(0-100),不是完成度描述。填了它会真的改任务进度。
- 免报日(`is_exempt`)不产生未提交统计,也不必催。
@@ -1,64 +0,0 @@
# 保存日报草稿(+draft
> ⚠️ 参数细节以 MCP `report_save_draft` 的 docstring 为准,本文档仅做工作流引导。
## 前置
已通过 `report_get_tasks_to_report()` 获取待汇报任务列表。返回的每个任务条目至少含 `id`task_id)、`title``module_name`**以及 module_id 字段**(保存草稿必需)。
---
## items 字段(与后端签名一致)
| 字段 | 必填 | 类型 | 说明 |
|------|------|------|------|
| `module_id` | ✅ **必填** | string (UUID) | 任务所属模块 ID,从 `report_get_tasks_to_report()` 返回的任务条目里取(不要从任务名推断) |
| `task_id` | 可选 | string (UUID) | 任务 ID;不传则为模块级汇报 |
| `content` | ✅ **必填** | string | 汇报内容(今日进展),支持 Markdown,可为空字符串 |
| `progress_update` | 可选 | int (0-100) | 任务进度百分比(字段名是 `progress_update`,不是 `progress` |
⚠️ **历史踩坑**:曾用错的字段名 `progress``status`,以及遗漏 `module_id`,会触发"参数缺失"错误。
---
## 执行步骤
```
Step 1: 展示待汇报任务列表,引导用户逐一填写内容
格式示例:
┌─────────────────────────────────────────
│ 任务: [前端开发] 完成登录页面 UI 优化
│ 当前进度: 60%
│ 今日进展(请输入): ___
│ 完成百分比(0-100: ___
└─────────────────────────────────────────
Step 2: 收集所有填写内容,构建 items 数组
⚠️ 每个 item 必须含 module_id(来自 Step 0 的任务条目)
Step 3: [可选] 若用户请求 AI 辅助 → mcp__huanxi__llm_polish_report(content)
将润色建议展示给用户,由用户确认采用哪个版本
Step 4: mcp__huanxi__report_save_draft(items=[
{
module_id: "<从任务条目取>",
task_id: "<从任务条目取>",
content: "今日完成 ...",
progress_update: 80
},
...
])
Step 5: 告知保存结果:
"已保存草稿,共 N 个任务条目。是否现在提交?"
```
---
## 注意事项
- `progress_update`**整数百分比**(0-100),不是小数;字段名末尾必须是 `_update`
- 用户未填写 `content` 的任务:询问是否 dismiss(今天不汇报)还是暂时跳过
- `report_save_draft` 是 upsert 操作,多次调用不会重复创建
- 草稿保存成功后,下次调用 `report_get_today()` 可看到 draft 状态
@@ -1,56 +0,0 @@
# 提交日报(+submit
> ⚠️ 参数细节以 MCP `report_submit_item` / `report_get_today` 的 docstring 为准,本文档仅做工作流引导。
## 前置条件
- 草稿已通过 `report_save_draft()` 保存
- 用户已查看并确认内容
---
## 执行步骤
```
Step 1: mcp__huanxi__report_get_today() → 获取最新草稿内容
Step 2: 展示完整草稿给用户审阅:
┌─────────────────────────────────────────
│ 📋 今日日报预览(2026-04-13
│ ✅ 完成登录页面 UI 优化(进度 80%)
│ 今日进展:完成了头部导航栏的响应式改造...
│ 🔄 接口联调(进度 50%)
│ 今日进展:与后端对接了 3 个接口...
└─────────────────────────────────────────
Step 3: 等待用户明确确认("确认"/"提交"/"好的"/"ok"等)
⚠️ 未收到确认前,禁止调用 report_submit_item
Step 4: 对每个需提交的草稿条目(item.status == "draft"):
mcp__huanxi__report_submit_item(item_id=<item.id>)
逐条提交,不影响其他条目状态
Step 5: 告知提交结果:
"✅ 日报已提交!共 N 个任务条目。"
```
---
## 提交失败处理
| 错误 | 处理方式 |
|------|---------|
| 草稿为空 | 提示用户先填写内容(+draft) |
| 已提交 | 告知已提交,询问是否撤回 |
| 网络错误 | 告知用户,建议稍后重试 |
---
## 重要约束
**禁止自动提交**:无论何种情况,`report_submit_item()` 调用前必须经过用户明确确认。
这是强制规则,不得因为"用户已经填好了"或"工作流要求"而跳过确认步骤。
**逐条提交,不做全量**:需先从 `report_get_today()` 获取各条目的 `item_id`,再逐条调用 `report_submit_item(item_id)`,不得批量提交所有条目(除非用户明确要求"全部提交")。