用户在数据目录 shuangpin\custom\ 下放 TOML 文件,在设置页以 custom/<文件名> 选用。零声母规则从 o、a、first_letter、full_pinyin 四种里选,声母和韵母 映射由文件指定,可用 [zero_initials] 覆盖个别零声母音节。 - 引擎:新增 CustomShuangpinLayout 与 BuildCustomShuangpinProfile,校验缺键、 声母撞键,并对全部音节做往返解码,冲突时给出可读的错误信息;新增运行时 方案注册表,按需加载。 - Server:扫描并解析自定义方案,配置快照带上方案列表与目录;文件缺失或无效 时回退到小鹤。 - 设置页:仿照自定义辅助码,新增打开目录和刷新按钮;无效方案列出但禁用, 悬停时显示错误。 - 安装器:覆盖安装与迁移数据目录时保留 shuangpin 目录。 - 文档:docs/custom-shuangpin.example.toml 提供带详细注释的示例。
WebView messages
messages.json owns the message envelope, payload shape, and allowed sender windows.
Change it here, run python3 generate.py, and re-sync the copy under ui-html/ in the same
commit. The generated TypeScript union and embedded C++ schema must pass generate.py --check.
runtime.js and validator.h implement the documented schema subset and run the same
fixtures.json compatibility cases. The standalone CMake test requires Boost.JSON;
the input engine itself does not acquire that dependency.
New messages carry protocolVersion: 1. A missing version is accepted as legacy v1
for existing skins; an explicit unknown version, unknown message, invalid payload,
or message sent from the wrong window is rejected before dispatch. This is envelope
validation, not a replacement for domain checks such as dictionary key validation,
allowed configuration values, or the host's HTTPS URL policy.
ui-html/scripts/sync-contracts.py materializes these bindings into
ui-html/webview2/shared and checks byte equality; CI runs it with --check, which
now compares against this directory directly rather than against a pinned submodule.
Settings imports the typed serializer and checks incoming messages. Classic candidate,
toolbar and menu pages load the same runtime from the host's https://msime-contracts/
virtual mapping; packaging must include webview2/shared.
Server-to-page candidate rendering currently uses the existing view functions; this contract covers WebMessage actions and settings responses. Candidate view model ownership is documented separately from transport envelopes.