Skip to content

Add chinese-divination: Plum Blossom divination Mini App - #13

Open
weekbin wants to merge 1 commit into
MiniMax-AI:mainfrom
weekbin:feat/chinese-divination
Open

weekbin wants to merge 1 commit into
MiniMax-AI:mainfrom
weekbin:feat/chinese-divination

Conversation

@weekbin

@weekbin weekbin commented Oct 3, 2026 •

Copy link
Copy Markdown

是什么

梅花易数占卜 Mini App。时间、数字、铜钱摇卦、每日一卦四种起法,按体用生克、京房八宫、纳支、
旬空月破、爻之合与爻之刑等传统规则断吉凶,把结论落到所问的那件事上,给应期与宜忌。
内置六十四卦全文(卦辞、彖传、384 条爻辞与 384 条小象传)与干支时辰历法。

两种用法:打开页面起卦;或在对话里由 Agent 经 MCP 端点主动起卦并讲解。

包目录 plugins/weekbin/chinese-divination/,插件 ID chinese-divination,版本 1.1.0。

安全与边界

  • 不联网。 Node 进程无任何出站请求,不调模型 API,不 spawn 子进程;页面不加载任何远程资源、
    字体或脚本。唯一网络行为是 MCP 端点在 Host 分配的回环地址上监听,且只接受 POST。
  • 不读包目录以外的文件。 只读 miniapp/client/index.html 与本包 Node 载荷。
  • 状态只写 dataDir。 readings.json 存卦历(最新在前,上限 500 条),临时文件写入后改名,
    中断不会留半份文件。解析不出的落盘文件被改名另存为 readings.json.corrupt-<时间戳> 而非删除,
    手写批注仍可找回,卦历按空表继续而不是全线 500。
  • 回环防护。 请求的 Host 头,以及存在时的 Origin 头,都必须是回环名。Host 挡 DNS
    rebinding(攻击者域名解析到 127.0.0.1 后浏览器视作同源),Origin 挡直接打端口的跨源简单请求。
    被拒时返回 403 且不回显请求方。
  • 日志不带路径。 只记错误码,不记 error.message——Node 的 fs 报错会把完整绝对路径连同
    操作系统用户名写进 message,而 dataDir 按契约是不透明的,那串路径不该跟着日志离开进程
    (日志会被贴进 issue、传进工单、上传)。
  • 无密钥。 不读也不持有任何凭据,无 Host connector 访问。
  • 页面渲染。 卦历里的所问与批注用 textContent 渲染,其余插值一律过 escapeHtml。
  • 客户端不写 localStorage / cookie / IndexedDB。

测试环境与结果

三个平台均已实跑:Windows、macOS、Linux。 三边都装好后经 Agent 打开,页面渲染正常,四个分区
可操作,掷钱、卦历与 MCP 各条路径一并查过。

macOS 那一轮是脚本化的,每一步都记在这里:

  • 单元测试 228 项,全部通过。 在 America/New_York、UTC、Asia/Shanghai、
    Pacific/Kiritimati(UTC-8 到 UTC+14)四个时区下各跑一遍,另加 LC_ALL=C LANG=C 极窄 locale
    一遍,每种组合都是 228 通过 0 失败——本包不依赖本机时区与 locale。
  • 冒烟测试 83 项,全部通过。 拿临时 dataDir 真起 start(context),覆盖:页面与四种起法、
    掷钱、六十四卦全表、历法、卦历增删查、同秒起卦 id 撞车(曾致删一条连带删另一条)、故意写坏的
    readings.json、MCP 的 initialize / tools/list / 三个 tools/call / 通知 / 未知工具 /
    非法事类、以及 dispose 真的关掉监听且可重复调用。
  • 路径审计 0 问题。 可移植路径规则、Windows 保留设备名、UTF-8 无 BOM 无 CRLF、无仅大小写
    不同的文件、每条相对 import 都能在磁盘上找到;最坏形态的 dataDir 全路径 112 字符,
    离 MAX_PATH 260 还远。
  • 仓库门禁 npm run check 55/55 通过;npm run validate 对本包报 OK(0 错误 0 警告)。

两条平台相关的设计决定,由静态核查托底:路径一律用 node:path 拼;无 __dirname(ESM 里不存在),
import.meta.url 只在测试文件里以 new URL(相对, import.meta.url) + fileURLToPath 出现,即
ESM 跨平台的正解,且测试文件在运行时载荷之外。落盘用「临时文件 + 改名」,在 Windows 上遇到杀毒扫描
或索引器占用导致的 EPERM/EACCES/EBUSY 会退避重试四次(约 400ms)——这是 Windows 独有的行为。

尚未核对的一项: 760px 断点以下的窄屏版式,三个平台都未在实机看过。收窄内容区替代不了——
那两处容器查询反应的是区块自身宽度而非视口宽度,只有真实窄视口才走得到那条路。

几个值得一提的实现选择

  • 起卦 id 带进程内计数器。 数字起卦只取决于两个数,同一对数在同一秒内起两卦会得到逐字节
    相同的 id,而卦历按 id 过滤,删一条就会连带删另一条。现在同卦同时刻的 id 必不相同。
  • 起卦有在途闸。 铸卦动画要持续四秒多,期间所有起法按钮都可点,普通双击会发出两次起卦请求。
    现在 cast() 在第一个 await 之前同步置位 casting 并锁住触发器,解锁按状态计算而不是
    清空 disabled——成卦解卦 另有「满六次才能点」的规则,一刀切会留下一个看得见却点不动的按钮。
  • 掷钱按钮只有一处写 disabled。 原先 renderToss() 算完可用态,末尾又无条件全部启用,
    两者互相覆盖,六次之后两个按钮同时可点。现在可用态集中在 syncTossButtons(),只由已掷次数决定。
  • MCP 的事类交给 Agent 判。 页面没有「替用户读问题的对象」,只能用关键词表;Agent 读过
    用户原话,由它填 topic 更准。九类之外的值直接报错而不是静默忽略——静默忽略会让 Agent
    以为自己已经定过了。
  • 免责段随每次起卦返回,MCP 的 instructions 与 SKILL 都要求转述时必须带上。

许可

MIT,见 LICENSE。


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

梅花易数起卦与解卦。时间、数字、铜钱摇卦、每日一卦四种起法,按体用生克、京房八宫、
纳支、旬空月破、爻之合刑等传统规则断吉凶,落到所问之事上给应期与宜忌;内置六十四卦
全文(卦辞、彖传、三百八十四条爻辞与小象传)与干支时辰历法。既能在页面起卦,也能由
Agent 经 MCP 端点在对话里主动起卦。

安全与边界:

- 全部计算在本机完成:不联网、不调模型、不 spawn 进程,不读包目录以外的任何文件
- 卦历存在 Host 分配的 dataDir,原子写入,上限 500 条;坏盘另存而非删除
- 请求只认回环 Host/Origin,挡住 DNS rebinding 与跨源读取;403 不回显请求方
- 日志只记错误码,不记 error.message——fs 报错会把绝对路径与系统用户名带出去

平台与验证:

- 三个平台(Windows / macOS / Linux)均已实跑:安装、经 Agent 打开、四个分区走通
- 路径审计 0 问题:可移植路径、Windows 保留名、UTF-8 无 BOM 无 CRLF、大小写、
  import 解析、最坏 dataDir 路径 112 字符(MAX_PATH 260 内)
- 228 项单元测试,在 UTC-8 到 UTC+14 四个时区与 C locale 下均为 228 通过 0 失败
- 冒烟脚本真起 start(context),83 项覆盖页面、四种起法、卦历增删查、同秒 id 撞车、
  坏盘恢复、MCP 全路径与 dispose 幂等
- 尚未核对的一项:760px 断点以下的窄屏版式
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant