96 Commits
Author SHA1 Message Date
tokisaki galaxy 43452f1ff9 build: derive a dev version string from version.txt
scripts/dev-build-version.py turns version.txt plus the head commit into
0.7.1-dev.20261019.<hash>: the -dev display string for installer names and
the native settings page, and a YYMMDD stamp for the fourth VERSIONINFO field.

apply_version.py accepts an optional fourth quad field to carry that stamp;
releases leave it at 0, so their behaviour is unchanged. The settings page's
version parser strips the -dev suffix and compares numbers, which is what
keeps the update check quiet on dev installs -- no opt-out flag needed.
2026-10-19 16:00:06 +08:00
Lu Fan(SonnyCalcr) 9b9326f153 feat(scripts): 出厂词库不再带内置快捷短语 (#1057)
本地构建不再读取 msime 的 mix/quick_phrases.txt,quick_parases 只建空表,
K 模式、设置页新增的用户快捷短语和安装回放仍写在这张表里。check_outputs
要求该表存在且为空;--compare-release 不再比对这张表。
2026-10-18 13:33:39 +08:00
Lu Fan(SonnyCalcr) 23bfdd4d51 feat(engine,server): 符号混输放开拼音读音,emoji 混输改为整串精确匹配 (#1050)
- 符号混输不再挡读得成拼音的编码:混输本来就只认整串精确匹配,xi → ξ 也照样混入;单字母编码仍不混。
- 构建器读取 msime-dictionary 新增的 custom/symbols.txt(拼音<TAB>符号),把 dian → · 、、
  shuminghao → 《》 〈〉 等标点读音写进 symbol_code,书名号、引号、括号成对给出。
- emoji 混输改用新的 query_mixed_emoji,只认整串精确等于关键词,不再按前缀带出 emoji;双拼下只查
  展开后的全拼,并和符号一样只在光标位于末尾时查询。Shift+E 的 emoji 模式仍按前缀查。
- 同步更新设置页说明、出厂与开发配置注释和 README。
2026-10-18 11:23:26 +08:00
Lu Fan(SonnyCalcr) 3cd429b19d feat(server): 加入 S 模式符号输入与符号混输 (#1047)
符号数据改用 rime-wanxiang 的符号表与 typst/codex 符号名,源数据放在
msime-dictionary 的 sources/symbols/,替换原来的 piliapp 符号表。

- 建库:新增 symbols_db.py,生成表情面板用的 symbol_catalog(中文分类)和
  S 模式、符号混输用的 symbol_code;剔除 wanxiang-unrenderable.txt 列出的
  Windows 自带字体显示不了的符号,以及与 ① ❶ 看不出区别的 Dingbats 带圈数字
- 新增 scripts/check-symbol-rendering.py,用 Windows 字体生成上面的剔除清单
- Shift+S 进入符号模式,按万象分组码(xl、sx、szq)、数字读音(yi → 一 ① ⑴)
  或符号名(alpha、infinity)检索
- 符号混输:整串精确等于编码时混入,首个紧跟首选;读得成拼音的编码只混数字
  序号写法;双拼先按方案换算成全拼再查(小鹤 sj → san → ③)
- 表情面板符号页:中文分类,搜索把整词命中的符号列在「最佳匹配」
- 配置:utility.symbol_mode(默认开)、general.symbol_mixed_input(默认关)

Refs #795
2026-10-18 02:08:39 +08:00
Jia Suiandfanlusky d414268b5f [Feat] U 模式重构为部件拆字反查 (#973)
* feat(engine,server,windows,ui-html,installer): U 模式重构为部件拆字反查 (#971)

把 U 模式从 Unicode 十六进制码位输入改成部件拆字反查:Shift+U 后输入各
组成部分的拼音连写(晶 = ririri)即可出字,候选上反显注音。

- 引擎:新增 local_modes/radical_query(前缀匹配、字频降序),数据表
  engine/radical/decomposition.txt 与生成脚本;LocalInputMode::Unicode
  改为 Radical;删除 unicode_query。
- Server:g_radical_mode_triggered + IsRadicalCompositionActive + 候选分发,
  用 cpp-pinyin 反显注音;删除 Unicode 码位路径。
- 前端 TSF:删除 U 模式的十六进制/数字特例与影子预判,按普通组合处理。
- 配置:utility.unicode_mode 改为 utility.radical_mode。
- 部署:assets 登记 radical_decomposition,安装器与 CI 拷表。

数据来源 mirtlecn/rime-radical-pinyin (GPL-3.0),授权见 engine/radical/NOTICE.md。

* feat(server): U 模式反显拼音改为带调风格(jīng)

* fix(server,installer): 修复 U 模式 CI(拆字表打包夹具与 clang-format)

* fix(engine,server): 修正 U 模式按键错位、重复候选与配置迁移

- Server 在 U 模式不再吞掉撇号、分号、斜杠、大写字母等键:TSF 已把它们记进按键缓冲,
  吞掉又不重同步会让两侧串和光标错位。照常插入,含非 a-z 的码查不出候选
- 拆字查询全码命中排在仅前缀命中之前,同一个字的几种拆法只出一次
- 升级合并把旧键 utility.unicode_mode 的值带到 utility.radical_mode,读取时也兜底旧键
- 生成脚本只收汉字,重建拆字表去掉 abc 码下的 51 行数字、字母与符号
- 开着 U 模式时在后台预热拆字表与 cpp-pinyin 词典,避开首个按键的冷加载
- Server 按会话的 RuntimePaths 查拆字表,删掉走全局数据目录的便捷重载
- cpp-pinyin 初始化合并到 utils/hanzi_pinyin,设置页导入注音共用;U 模式与快捷短语的收键分支合并

---------

Co-authored-by: fanlusky <1730976608@qq.com>
2026-10-16 01:01:18 +08:00
小莫 fbe64a7ab2 fix(installer): pass test signer switch safely (#924) 2026-10-13 21:31:53 +09:00
小莫 93933602ff fix(installer): avoid certificate store in SignPath test mode (#923) 2026-10-13 21:19:05 +09:00
小莫 4824e1ba9d fix(installer): force noninteractive test certificate import (#922) 2026-10-13 21:09:28 +09:00
小莫 9b2af45111 fix(installer): import SignPath test certificate noninteractively (#921) 2026-10-13 21:02:04 +09:00
小莫 5cec4f4ad2 fix(installer): request SignPath certificate media type (#920) 2026-10-13 20:44:52 +09:00
小莫 d0d87efb53 feat(installer): add SignPath test signing workflow
Adds a manual test_signing dispatch that uses GitHub-hosted runners, test-signing policy, signer verification, and run-summary request links without publishing a release.
2026-10-13 11:43:05 +00:00
luo jiyin 5a5d5dee80 fix(ci): fall back to MSVC when sccache is unavailable (#832)
* fix(ci): fall back to MSVC when sccache is unavailable

* test(ci): build with MSVC after simulated sccache setup failure
2026-10-11 20:39:51 +09:00
Lu Fan(SonnyCalcr) 9495b8b60d feat(installer): 自动安装首次运行所需的依赖 (#823)
* feat(installer): 自动安装首次运行所需的依赖

- pnpm install: 构建 ui-html 时自动安装 node_modules,首次运行不再因缺失 tsc 而失败
- pypinyin: 词库构建自动安装 Python 依赖,无需手动提前装
- 新增 scripts/download-neural-model.ps1: 从 chinese-ime-lm Release 下载神经整句模型
  * 幂等设计,摘要验证正确时直接跳过,首次运行下载 ~30 MB
  * Invoke-LocalTest.ps1 在词库构建后自动调用

优化完整包构建流程(test.ps1),首次运行时自动处理所有依赖安装和下载。

* fix: build-failures 测试允许 pnpm install 成功

mock pnpm 函数现在只让 'pnpm run build' 失败,允许 'pnpm install' 成功。
这样测试可以验证脚本在 build 失败时正确地中止,同时支持首次依赖安装。
2026-10-11 15:33:31 +08:00
Lu Fan(SonnyCalcr) 5e03628a7e feat(installer): build cn-en translations into the local dictionary (#784)
* fix(server): drop part-of-speech labels from Ctrl+Enter translation senses

The machine-translated Chinese-to-English glosses prefix each sense with a
label ("n. silver medal", "proper n. Wanshan District"). The candidate
window keeps showing the whole gloss, but splitting it for Ctrl+Enter now
strips the label so it never reaches the committed text.

* feat(installer): build cn-en translations into the local dictionary

build-dictionary.py gains a cn-en-translations stage that loads
sources/cn-en/machine-translations.txt from msime-dictionary into
zh_en_glosses verbatim, keeping every sense instead of the two the ECDICT
derivation keeps. It runs after english-glosses and before
custom-translations, so it overrides ECDICT and custom/translations.txt
still overrides it.

Local full test packages now always build the dictionary from the sibling
msime-dictionary checkout instead of downloading the product-lock release:
Invoke-LocalTest.ps1 and prepare-package-inputs.ps1 call
build-dictionary.py --if-stale, which skips only when out/ was built from
the current clean source commit by the current builder. CI and releases
still take the dictionary from product-lock.json.
2026-10-10 21:17:03 +08:00
小莫andfanlusky ad78409e3c ci(release): run the SignPath path on GitHub-hosted runners (#709)
* ci(release): run the SignPath path on GitHub-hosted runners

SignPath's open-source plan accepts a signing request only when every job leading up to it ran on a GitHub-hosted runner, and tsf, server and package all ran on the self-hosted release machine. With WINDOWS_SIGNING_PROVIDER=signpath they now run on windows-2025, restoring vcpkg binaries and (for the Server) sccache the way ci.yml does; the certificate path keeps the self-hosted runner unchanged.

The org secret holding the SignPath API token is SIGNPATH_TOKEN, so the workflow and detect-release-signing.ps1 read that name instead of SIGNPATH_API_TOKEN.

AGENTS.md lists what SignPath needs configured, and the code signing policy records the accepted application and the hosted-runner rule.

* fix(ci): let the SignPath action read the run's artifacts

* fix(installer): drop authenticode-sign attributes SignPath Foundation rejects

* fix(ci): fail the hosted SignPath release before signatures are spent

- Probe ISCC with WizardStyle=modern dynamic and run that probe at the start of the hosted package job, so an image ISCC older than 6.6 fails before the payload signing request instead of after it.
- Verify the TSF vcpkg root before installing into it or saving its archives under the -complete key.
- Check the Server job's C:\vcpkg override against the vcpkg the hosted image puts on PATH.
- Code signing policy: drop the stale "once approved" wording and state that the hosted-runner rule applies to SignPath-signed releases.

* docs: list only the configured SignPath approver

---------

Co-authored-by: fanlusky <1730976608@qq.com>
2026-10-08 23:16:34 +08:00
Lu Fan(SonnyCalcr) 2fbe7d69fa feat(installer): 本地从 msime-dictionary 文本源数据构建词库 (#654)
新增 scripts/build-dictionary.py 与 scripts/dictionary_build/:按 msime Rust 构建器
(crates/dict-builder)的规则读取 msime-dictionary 的 sources/ 与 custom/,加上
inputs.lock.json 固定的仓外文件,生成 Windows 端现有的 msime.db / english.db /
others.db / dict_japanese.dat 布局,写到 MetasequoiaImeDict/out/。产品锁的旧词库
先备份到 out.bak/,--compare-release 可与官方 dict-v* Release 逐表对比。

prepare-package-inputs.ps1 遇到带 local-dictionary.json 的 out/ 时只校验(-Force
时重新构建),不再用产品锁的词库覆盖。CI 与正式发布仍按产品锁取词库。
2026-10-07 23:39:48 +08:00
fanlusky 1ae1f1eddb revert(server): 撤回 #576 的 skin.toml 统一规则
This reverts commit c5b0c24c48.

#576 未经评审即被合入 develop,先撤回,待评审意见处理后重新提交。
2026-10-03 18:11:23 +08:00
小莫 c5b0c24c48 feat(server): read skin.toml with the rules every platform shares (#576)
* feat(server): 外部皮肤接受跨平台客户端的 base 与装饰规则,社区皮肤可在 Windows 加载

社区皮肤库按跨平台客户端(msime 的 client-core)的规则校验,base 写的是全局主题 system / shuishan / light / paper / night / ink,而 Windows 只认六个内置皮肤 ID,所以社区里绝大多数皮肤在 Windows 上整包加载失败。

- base 为 system 时按 fluent 加载,配色原样保留。
- base 为五个内置全局主题时按 fluent 加载,并照 theme::resolve 换算配色:主题固定明暗,只取包里那一种明暗的配色,深浅两种模式都画它;读不懂的颜色当作没写,没写的按主题补齐,右键菜单和悬浮工具栏一并补上。包没声明那一种明暗时不生效,与客户端一致。
- 装饰规则与客户端对齐:空表或两个尺寸都为 0 表示无装饰;有尺寸而无 image 时用图片类型的 preview,都没有就不画。
- 复制 msime-cloud 的 client_dialect.json 作测试夹具,新测试要求客户端接受的每个包在 Windows 上都能加载;scripts/sync-client-dialect.py 负责同步,每周的 Skin client dialect 工作流比对上游。

* feat(server): 皮肤清单与跨平台客户端统一为同一套规则

同一个皮肤包现在在每个平台上要么都能加载,要么都被拒绝。规则以 msime client-core 的 load() 为准,共享用例表 client_dialect.json 改为从 msime 同步,测试要求每一条用例的接受与否都与客户端一致。

- 保留 ID 加上全局主题 ID(system、shuishan、light、paper、night、ink、custom)。
- 收紧到客户端的规则:skin.toml 最大 64 KiB;schema_version 必须是整数 1;author、description 写了不能为空;preview 写了必须指向包内已有的文件;toolbar_stylesheet 写了必须是包根目录里已有的 .css 文件;[license] 的各键有长度限制;[candidate] 与其中的 dark、light 必须是表;装饰图与背景图须是图片扩展名。
- 仓库自带的 7 个皮肤、示例皮肤和 msime-skins 里的 4 个皮肤在新规则下都能加载。
2026-10-03 17:39:49 +09:00
Jia Sui 2557ee4a63 docs: 修正 AGENTS.md 与注释中与代码不符的五处描述
spec 校对时逐条核对「文件:行号」锚点发现,五处文档描述与代码现状不符:

- windows/AGENTS.md:格式化遵循的是本目录 .clang-format,仓库没有根目录 .clang-format
- 根 AGENTS.md:engine/... 前缀 include 只对 server/ 成立,windows/ 无仓库根,走相对路径
- scripts/format.sh:注释声称 CI 会跑 generate.py --check,实际没有任何 CI 作业调用
- server/AGENTS.md:测试源文件数与三处行号锚点过期
- server/CMakeLists.txt:注释里的 "eleven add_test()" 实际是 24 个,删去具体数字

纯文档与注释改动,无行为变化。
2026-10-03 08:29:50 +08:00
小莫 8814cd41e7 ci(release): add a SignPath signing path, off by default (#589)
The release job can now sign through SignPath instead of the certificate in the repository secrets. It only does so when the WINDOWS_SIGNING_PROVIDER repository variable is set to signpath, which nothing sets yet, so every release keeps taking the existing certificate path until a maintainer switches it.

On the SignPath path, scripts/ci/signpath-files.ps1 stages only the project's own binaries (the seven Server executables and both TSF DLLs) as the signing request's artifact, because SignPath Foundation does not allow signing the third-party DLLs vcpkg builds for the Server. The signed files are checked for a valid Authenticode signature before they replace the originals, and staging fails if a MetasequoiaIme* binary is missing from the list. The installer goes through a second request after it is compiled. installer/signpath/ holds the reviewed copies of the two artifact configurations to paste into SignPath.

detect-release-signing.ps1 fails the release when the provider is signpath but a SignPath setting is missing, or when the provider value is unknown, instead of falling back to the certificate or to an unsigned build.
2026-10-03 03:45:09 +09:00
Evan Hu fdbbf300a6 docs: add code signing policy for the SignPath Foundation application
SignPath Foundation requires a page titled "Code signing policy" that carries its attribution, names the committers, reviewers and approvers, and links the privacy policy, referenced from the project home page and the release pages.

docs/code-signing-policy.md states what is signed, the team roles taken from the repository collaborators and the maintainers team, the CI release process that SignPath-signed builds will go through, and the current status: releases up to v0.9.3 were built and signed locally with the Certum certificate. Both READMEs link to it, and publish-release.sh appends the link to the release notes it writes.
2026-10-03 03:29:14 +09:00
Jia Sui 72c1d7ddb0 fix(engine): darts-clone 登记为 vendored 副本,脱离格式门禁
0976c307 随octagram 读取端入库的 darts-clone 0.32h 不在 format.sh 的排除名单里,
而它整份文件都不符合仓里的 .clang-format,本分支一旦推上去 CI 的
Check formatting 就会报 1826 处违规。

按精确路径排除 darts.h,不按目录:同目录的 octagram_gram.{h,cpp} 是我们自己的
代码,必须继续受门禁管,目录级排除会连带把它们一起豁免掉。

与上游 v0.32h(87b71afd)比对后确认这份副本并非原样入库,而是带 6 处本地改动
——open() 删掉 256 单元头部校验与两段式读、save() 删掉 offset 参数、
commonLongestPrefixSearch 整体删除、DoubleArrayBuilder 三个常量改为
static const std::size_t、一处注释拼写。这些此前没有任何地方记录,是它掉出
名单却一直没被发现的原因;逐条写进 UPSTREAM.md,升级 darts-clone 时才能重放。
前两条与 mmap 装载自洽(octagram_gram 走 set_array,不经过 open/save)。

两份 AGENTS.md 里硬编码的「那三个上游副本」清单同步为四个。
2026-10-02 22:00:36 +08:00
fanlusky 4b30659fca ci: 单独构建并运行引擎自己的测试
Server 任务以 BUILD_TESTING=OFF 把引擎当库引入(避免 EXCLUDE_FROM_ALL 下的测试
找不到可执行文件),于是引擎的 23 组测试从来没在 CI 里跑过,只在开发机上跑。
server/tests 覆盖不到的行为——比如用户日志的连接管理、关闭它时要放开数据目录里
所有缓存句柄——只有这些测试能发现;#491 的一个回归就是这样在本地才测出来的。

新增 Engine 任务:按 engine/vcpkg.json 单独配置引擎、构建、再用
scripts/ci/test-engine.ps1 在与 Server 相同的锁定词库上跑 ctest。数据目录与
LOCALAPPDATA 都隔离到临时目录,布局与 test-server.ps1 一致。同步更新
server/CMakeLists.txt 里「引擎测试经 server/tests 覆盖」的旧说法。

本地按同样命令(不设 BOOST_ROOT,只靠 vcpkg 清单)配置、构建并运行:23/23 通过。
2026-09-27 16:54:20 +08:00
fanlusky 52af935d41 chore(installer): 新增 prepare-package-inputs.ps1 一键准备模型与词库
本地打完整测试包需要神经整句模型、sc.lm 和词库。该脚本依次调用 fetch-neural-model.ps1、build-language-model.ps1,并按 product-lock.json 从公开 release 直接下载词库、用 product_lock.py verify-dictionaries 校验,免去本机登录 gh。各步骤均幂等。
2026-09-26 01:12:11 +08:00
fanlusky e7f7addd4f feat(engine): 神经网络整句联想与词格 n-best 重排
- 新增 engine/neural:移植 chinese-ime-lm 的字符级 Transformer 推理,在词格解出的最多 12 条
  n-best 里重排挑选整句,desktop / keyboard 两档模型各出一条首选,后台 worker 异步打分
- 词格支持 n-best 输出与重排(quanpin/lattice_rerank),全拼、双拼共用
- 新增 SentenceAssociationOptions,经 QueryRequest 传给各 provider;四个来源默认全关
- 资源契约登记两个 safetensors 与 NOTICE;模型二进制不进仓库,由
  scripts/fetch-neural-model.ps1 按 neural-model/lock.json 下载并校验 SHA256
- 新增 neural_sentence 测试
2026-09-24 14:03:39 +08:00
fanlusky d30d2946e4 feat(installer): 打包时生成并安装词格语言模型 sc.lm
sc.lm 此前只能手工投放,重装即失效,发布包里也没有它。这里把它变成一个被钉住、
可复现、自动参与打包的产品输入。

它不走词库那条路:词库 release 由本仓库之外的构建器产出,资产集合和摘要在产品锁
里逐一钉死,加一项要对方先发新版。改为独立钉住上游语料,与 libime 自己的做法一致。

- language-model/lock.json 钉住上游 URL、语料摘要、转换参数和产物摘要。转换是
  确定性的(已在 MSVC 14.44 与 14.50 两套工具链上验证产物摘要一致),所以产物
  摘要可以像下载摘要一样钉死。
- scripts/build-language-model.ps1 下载、校验、转换、再校验,写临时文件后改名,
  中途失败不会留下摘要对不上的 sc.lm。幂等,摘要对得上直接返回。
- 它只 configure engine/ngram 一个目录,不拉 vcpkg 和 SQLite:转换工具只依赖
  kenlm 自己,而打包机上未必装得起引擎的全部依赖。
- Invoke-LocalTest.ps1 打完整包前自动调用它,轻量包本就不带数据文件,不调。
- 打包脚本只断言文件存在,摘要由构建脚本负责,与词库交给 product_lock.py 校验
  的分工一致。缺模型让打包失败而不是跳过:引擎对缺模型是静默降级的,运行期不会
  暴露,打包是唯一拦得住的地方,package-files.ps1 为此加了反向用例。

模型是 LGPL-2.1-or-later 的第三方数据,声明随之安装为 libime-lm-NOTICE.md。
安装脚本无需改动,它已按通配收集资源目录。产物与语料不进仓库,只进锁与声明。
2026-09-19 10:08:39 +08:00
fanlusky 80b1fc42a1 feat(engine): 词格整句改用 kenlm 三元模型打分
词格原先的整句打分是一份没校准过的启发式 unigram,质量很差。这里内嵌 libime
在用的 kenlm 查询子集,改由它的三元模型 sc.lm 来打路径分。

- engine/ngram 只编 kenlm 的 query / trie-build 路径。不定义 WITH_THREADS,
  parallel_read.cc 因此退化成串行实现,整个子集零 Boost 依赖。
  KENLM_MAX_ORDER=3 必须与建模阶数一致,改它等于读不懂已发布的模型文件。
- ngram::LanguageModel 是唯一 include kenlm 头文件的地方,对外只给出一个纯
  std 的头,_HAS_AUTO_PTR_ETC 和 kenlm 的 include 目录都保持 PRIVATE。
- shared_language_model 按资源路径共享一份 mmap。kenlm 的查询是只读的且把
  上下文放在调用方的 State 里,所以并发会话不需要额外加锁。
- 模型缺失时 valid() 为假,词格退回原来的启发式打分:整句候选只是变差,不会
  停止工作。测试覆盖了缺模型降级与按路径共享。
- 出货的 ARPA 不带 <s>/</s>,所以解码从 null_state() 起算而非 begin_state()。

kenlm 是上游副本,不重排版、不进 clang-format,其 LGPL-2.1+ 与 BSD 例外清单
已补进 THIRD_PARTY_NOTICES.txt。googlepinyinime 那条 Fallback 整句路径不变。
2026-09-19 10:08:39 +08:00
fanlusky 1b9fb0562e feat(installer): add SimplySign packaging scripts 2026-09-14 03:32:42 +08:00
fanlusky b45de7376f chore(installer): 移除协议页并补充图标资产 2026-09-13 21:13:59 +08:00
fanlusky a7779d2b05 refactor(engine): 将 engine 从 submodule 内嵌为仓内一等组件
`vendor/MetasequoiaImeEngine` submodule 改为 `engine/` 目录,导入的是
product-lock.json 原本钉住的提交 c810d201,逐文件核对过 blob,因此这是一次
搬迁而不是引擎升级。引擎自己的嵌套 submodule(googlepinyinime-rev、utfcpp、
miniaudio)按各自 gitlink 一并展开,来源与提交见 engine/UPSTREAM.md。

Windows 专门化裁掉了不属于本产品的部分:whisper.cpp 与本地推理 provider、
macOS 示例宿主、整个 dictionary/ 建库流水线、上游 CI 与 release-please 配置。
词库仍按 product-lock.json 在构建时取发布产物。

引擎不再进 product-lock.json:没有 gitlink 就没有可比对的东西,锁里写一个上游
commit 等于宣称这棵树仍等于上游,而第一个 Windows 专门化改动落地时这句话就假了。
verify-contracts / verify-checkout 随之移除,verify-published 保留。

CI 与工具链:引擎源码并入根 scripts/format.sh(删掉引擎自己的那份,避免两套排除
列表分叉);引擎 voice.yml 里的 silero_vad.onnx 摘要校验移到本仓 lock job;
engine-bump-triage 工作流与其测试删除;gitsubmodule 的 dependabot 频率由 daily
改为 monthly。

README、README.en、AGENTS.md、CONTRIBUTING、docs/product-release.md 及各子目录
文档同步说明新的位置与边界。
2026-09-12 03:40:48 +08:00
fanlusky f91dae7644 fix(ci): stop the pipe probe from handshaking with a leftover Server
release.yml runs the Server job on a persistent self-hosted runner while
ci.yml runs it on a fresh windows-2025 image, so only the release path
kept a MetasequoiaImeServer.exe alive between jobs. That leftover holds
Local\MetasequoiaImeServer_SingleInstance, the Server started by
probe-server.ps1 returns 0 straight out of the guard, and the probe then
completes its handshakes against the older build. Probes 1-4 pass because
they do not ask for CharacterSetShortcut; probe 5 does, the pre-6ff1cff
Server never advertises it, and the run dies on a capability mismatch that
nothing in the tree can explain. v0.6.3 and v0.6.4 both failed this way.

Stop any Server and Watchdog before starting one, and fail loudly if the
Server this script starts exits on its own.

Also stop test-server.ps1 from reporting every non-zero verify-contracts
exit as a lock mismatch. A dubious-ownership git failure on the same
runner surfaced as "The engine submodule does not match the product lock"
while the lock was correct.

Also ignore installer/LICENSE.txt, which Prepare-PackageFiles.ps1
generates from the repository LICENSE on every local packaging run.
2026-09-09 01:29:29 +08:00
Evan 2fb4560d99 fix(release): use beta tags for automatic builds (#252)
* fix(release): separate ci snapshots from stable tags

* fix(release): use beta tags for automatic builds
2026-09-07 17:56:34 +09:00
Evan 560b730ea1 Merge pull request #250 from metasequoiaime/fix/release-vcpkg-lock
fix(scripts): keep automatic releases as prereleases
2026-09-07 17:30:28 +09:00
Evan Hu b777008abb fix(scripts): keep automatic releases as prereleases 2026-09-07 17:25:55 +09:00
Evan Hu 818069f9c3 fix(server): make release probes non-interactive 2026-09-07 13:28:25 +09:00
Neptrue_Lin 4b95c90fde Merge pull request #228 from AaGMix/feat/installer-pdb
feat(installer): include release PDB symbols
2026-09-07 09:46:06 +08:00
Evan ad48153c8e Merge pull request #230 from metasequoiaime/fix/release-vcpkg-lock
fix(server): embed uiAccess manifest before signing
2026-09-07 07:53:08 +09:00
Evan Hu 84de68fd1b fix(server): embed uiAccess manifest before signing 2026-09-07 07:42:14 +09:00
Evan 9bd309e773 Merge pull request #227 from metasequoiaime/chore/contract-sync-issues-47-49
feat(contracts): sync engine product lock contract
2026-09-07 03:23:54 +09:00
AaGMix e9a2c91214 feat(installer): include release PDB symbols 2026-09-07 02:10:38 +08:00
Evan Hu 2ff0509e67 feat(contracts): verify shared product lock primitives 2026-09-07 02:53:50 +09:00
Evan Hu d55a0b17a9 fix(release): publish automatic builds as stable releases 2026-09-07 01:51:44 +09:00
Evan Hu a45a8cbd34 fix(installer): fail when configured signing key is unavailable 2026-09-07 01:28:11 +09:00
Evan Hu 7dc68ff498 fix(installer): sign releases from runner certificate store 2026-09-07 00:32:22 +09:00
Evan Hu 85d462e16c ci: deduplicate release signing targets 2026-09-06 16:58:51 +09:00
Evan Hu a533d5aa2b Merge remote-tracking branch 'origin/main' into chore/oss-hardening
# Conflicts:
#	AGENTS.md
2026-09-06 13:06:54 +09:00
Evan 5bd82e9c5f ci(windows): 在 CI 里执行 clang-format
移植 MSIME-Linux 的 scripts/format.sh,接进已经是 required 的 Workflow validation 作业。
四个组件各自的 .clang-format 一直在仓库里,但此前没有任何一处强制执行。

.git-blame-ignore-revs 指向上一个重排提交,git blame 会跳过它。
2026-09-06 12:17:29 +09:00
Evan Hu d0e7cfdbdf feat(release): separate the automatic build channel from the release channel
Automatic per-merge builds shared one list with deliberately cut releases, and the previous change only made them identifiable rather than separate: both were still prereleases, which is the thing the issue objects to. Labelling was the wrong answer to it.

GitHub has no channel concept, but it has two published states, and there are exactly two kinds of release here. A push-triggered build is now a prerelease; a workflow_dispatch build is an ordinary release and the newest one carries the Latest badge. The Releases page shows two lists instead of one list with two kinds of title in it, and /releases/latest resolves for the first time.

The prerelease flag therefore means "automatic and uncurated" rather than "beta". The product being 内测 is stated in the release notes and in docs/installation.md, which is where a claim about stability belongs; the flag cannot carry that meaning while it is also the only thing separating the channels. docs/installation.md now tells readers to take the Latest badge, describes both channels, and says explicitly that being in the release channel means somebody picked it, not that it is stable.

Already published releases are not touched, so the Latest badge stays empty until the first dispatch after this lands.

Refs MSIME-Windows#167
2026-09-06 12:16:28 +09:00
Evan f70f64acaa fix(ci,ui): 修掉 6 条 CodeQL high 告警,补上发布目标的祖先校验
- validate-draft-release.sh 增加「target_sha 必须在 main 历史上」的校验。此前有 write 权限的人可以
  建一个指向任意 commit 的 draft release 再 dispatch,那份代码就会被编译并签进正式安装包;唯一的
  祖先检查跑在 checkout 之后的不可信工作树里,而负责编译的 TSF job 根本没有这道检查。校验放在
  prepare(默认分支上下文)里,所有构建 job 都 needs 它。
- 字体名引用只转义了 `"` 没转义反斜线,以 `\` 结尾的字体名能吃掉闭合引号让后续内容按 CSS 解析。
  两处(appearance.ts、shared.ts)都改为先转义转义符。
- voice_input_service.cpp: float 平方先提升到 double
- engine-bump-triage.yml 顶层权限从 write 收到 read,写权限下放到 job;runner 与同仓其他 workflow
  统一为 ubuntu-24.04

新增 CONTRIBUTING.md,把散在各 AGENTS.md / 组件 README 里的环境要求、构建顺序、打包步骤和提交前
检查串成外部贡献者能照着走完的一条路径,并从 README 首屏链出。
2026-09-06 12:09:50 +09:00
Evan 4fc16952b3 wip(windows): 补齐隐私与许可交付,修好外部人的构建入口
- 新增 PRIVACY.md:逐项写明每个联网端点、发送内容、默认开关与关闭方式,明确云候选默认开启、
  token 在 config.toml 明文存储、无任何遥测
- 设置页「用户协议」「隐私政策」两个无 handler 的死按钮接上;前者改名为「开源许可协议」指向
  LICENSE,开源产品的用户条款就是许可证本身,不再承诺一份不存在的 EULA
- 安装包随包装入 GPL 正文并在安装向导显示(GPLv3 §4/§6),补上打包测试断言
- release.yml 增加 build provenance attestation,并在发布后向 MSIME-Web 发 repository_dispatch,
  让 msime.app/update.json 不再等两小时一次的 cron
- 所有 CMakePresets 的 vcpkg 路径改用 $env{VCPKG_ROOT},server 的 Boost 回退不再指向个人目录
- ui/README.md 指向本机绝对路径的 markdown 死链改成相对链接
- 新增 check-developer-paths.sh 并接入 required 的 quality 检查,防止路径回潮
- docs/installation.md 不再写死版本号
2026-09-06 12:05:06 +09:00