Files
yixiong-claude-marketplace/plugins/huanxi/skills/huanxi-shared/SKILL.md
T
SkyJourneyandClaude Sonnet 5 600c0dd323 feat: 寰汐插件随 v1.0.0 生产切换升级到 v2 技能组,新增独立管理端插件
huanxi 插件的技能内容从 v1 全面替换为 v2(huanxi-org/huanxi-weekly 等
v1 专属技能下线,新增 huanxi-issue/huanxi-lookup/huanxi-meeting),MCP
连接与 Token 获取方式同步更新为个人中心自助生成。

新增独立的 huanxi-admin 插件(管理端 4 个技能,hxa_ Token,普通员工无需
安装),此前一直卡在"v2 未部署到生产域名前不推送"这条约束,今晚寰汐
v1.0.0 生产切换完成后条件满足。

产物由 huanxi-menagement 仓库 skills/sync_marketplace.py 生成,技能源码
单一真相在该仓库的 skills/,本仓库只接收产物、不手工编辑。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018xxRKMuiGR4wYT3QbwCpDc
2026-08-22 02:14:34 +08:00

149 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: huanxi-shared
description: "寰汐 MCP 共享基础:工具命名约定、本地缓存策略与过期检查、状态两层模型、全局确认约定。所有 huanxi-* 技能必须先读本文件。"
---
# 寰汐 MCP 共享规则
所有 `huanxi-*` 技能的**必读前置**。
---
## 一条最重要的约定:参数以工具自身的说明为准
**本文件与各技能文档都不重画参数表。** 每个工具的参数名、必填项、取值范围以它在 MCP
里注册的 docstring 为唯一真相;技能只描述**调用顺序、ID 如何传递、哪里必须停下来等用户
确认**。
> 这条不是洁癖。上一代技能包重画过参数表,结果字段名、枚举值、必填项四类漂移覆盖了
> 全部六个技能——用户侧表现为频繁的「参数缺失」报错。工具签名变了而文档没跟上,
> 是必然发生而非可能发生的事。
---
## 工具命名
Claude Code / Claude Desktop 里工具名带前缀:`mcp__huanxi__task_query`(个人端)、
`mcp__huanxi-admin__report_pending`(管理端)。其他平台通常是裸名 `task_query`
本文档统一写**裸名**,实际调用时按你所在平台的约定加前缀。
两个端点信任边界不同:
| | 个人端 | 管理端 |
|---|---|---|
| Token | `hxp_` 开头 | `hxa_` 开头 |
| 身份 | 你本人,权限与网页端一致 | Token 创建人的管理员身份 |
| 视角 | 我参与的 | 全量,不受角色过滤 |
---
## 状态是可配置的两层模型(v2 起)
**不要硬编码 `"in_progress"`、`"done"` 这类字面量。** 状态由后台配置,分两层:
- `category`:四类固定语义 `not_started` / `in_progress` / `completed` / `cancelled`
用于**判断**(这条算不算完成)
- `status_option_id`:具体状态项的 UUID,用于**写入**
改任何实体状态前,先 `dict_get` 取该 `entity_type`module/task/issue/meeting**必须选对**
下的选项,再传对应的 `status_option_id`。传旧值或错的 entity_type 会被直接拒绝。
---
## 本地缓存
缓存根目录 `~/.claude/huanxi-cache/`**按通道隔离**
```
~/.claude/huanxi-cache/
├── personal/ hxp_ 视角:me.json / my-modules.json / users.json
├── admin/ hxa_ 视角:all-modules.json
└── dict/ 与身份无关的配置字典(两个通道共享)
```
隔离是必须的:管理端看到的是全量模块,个人端只有我参与的——混用会让你把不该展示的
东西展示给用户。
### 分层 TTL
| 类别 | 文件 | 策略 |
|---|---|---|
| 身份 | `personal/me.json` | 永久(身份不变) |
| **配置字典** | `dict/*.json` | **版本戳比对** + 24h 兜底 |
| 人员与模块 | `users.json` / `my-modules.json` | 24h |
| 日历 | `dict/workdays.json` | 按日期 key 永久(查过的不再查) |
| **业务数据** | 任务 / 日报 / 会议 / 议题 / 公告 | **一律不缓存** |
最后一行是硬规则。业务数据随时在变,缓存它只会让你把过期状态当成现状汇报给用户。
### 字典为什么要版本戳而不是只靠 TTL
其余缓存过期了最多是显示旧数据;字典不一样——状态选项可能被后台停用,你拿 24 小时前
的 ID 去改状态会**直接报错**。失败方向从「看到旧数据」变成「操作失败」,值得比对一次。
```
用字典前:
1. 调 dict_version() ← 极轻
2. 与 dict/versions.json 比对
3. 一致 → 用缓存;不一致 → 调 dict_get() 重取该类并更新缓存
```
`dict_get` 的返回里**自带 versions 字段**,直接连内容一起存下来即可——不要分两次调用,
那中间字典若被改动,你会把新内容配上旧版本戳缓存起来,之后再也不会刷新。
### 读缓存伪代码
```
read(file, ttl):
1. 读 ~/.claude/huanxi-cache/{file}
2. 文件不存在 → miss
3. age = now - cached_at
4. ttl 为永久 或 age < ttl → 返回 data
5. 否则 → miss
on_miss(tool, params):
1. 调用工具
2. 写入 { "cached_at": <ISO8601>, "data": <返回值> }
3. 返回 data
```
`workdays.json` 特殊:按日期 key 存 `{ "2026-08-06": true }`,已查过的日期不再查。
---
## 站内消息(M12
寰汐的全部系统通知(任务分配、@提及、报告发布、模块变更…)都落在站内消息中心,
`notification_query` 是它的读入口。
**什么时候主动用它**:用户问「我错过了什么」「有没有人 @ 我」「最近有什么新任务」时。
不要在每次对话开头都拉一遍——那是噪音,用户没问就别塞。
```
notification_query(unread_only=True) # 只看未读
notification_query(scene="comment_mentioned") # 只看 @提及
```
返回里的 `related` 给出关联实体(`{"type": "task", "id": "..."}`),可直接拿去调
对应的 `task_get` / `module_get` 看详情——**不要**把 body 里的名字拿去重新搜索。
**标记已读要用户明示**`notification_mark_read()` 不传 id 是**全部已读**
这是个不可逆的批量动作,跟提交类操作一样先确认再调。
用户说「都看过了」再全清;只是让你念一遍未读的话,不要顺手清掉。
> 这里标的是**站内已读**。用户在飞书点了卡片按钮不算站内已读,两者有意分开——
> 「在飞书看了但站内还是未读」与「误触就被标已读」都是要避免的别扭。
## 全局约定
1. **提交类操作必须先确认**`report_submit` / `leader_report_submit` / `issue_close` 等,
执行前把最终内容展示给用户、等到明确确认(「确认」「提交」「好的」)再调。
不要因为用户说了「帮我写日报」就把提交也一并做了——写和交是两个决定。
2. **删除与指派同样需要确认**`task_set_assignees` 是**替换**语义(传空即清空),
不是追加;覆盖别人的名单前先说清楚会变成什么样。
3. **非工作日不强行中断**`workday_check` 显示非工作日时告知用户并询问是否仍要填写,
不要直接拒绝——补填、调休上班都是真实场景。
4. **先解析 ID 再操作**:需要 module_id / user_id 的操作,先查缓存,未命中再调
`module_query` / `user_search`。不要凭名字猜 ID。
5. **批量优先**:工具的过滤维度基本都收列表,一次查多个比循环调用快得多,也更省上下文。