Skip to content

修复 Windows 桌面 CI 基线:Pillow、工具结果鉴权与三处测试环境 - #16

Open
KuramiWan wants to merge 5 commits into
eleckoi:mainfrom
KuramiWan:fix/desktop-ci-pillow
Open

KuramiWan wants to merge 5 commits into
eleckoi:mainfrom
KuramiWan:fix/desktop-ci-pillow

Conversation

@KuramiWan

@KuramiWan KuramiWan commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Desktop Change(桌面端改动)

What changed(改了什么)

修复当前 main 上桌面 CI 的红。desktop-ci 的 pnpm test 在 windows-latest 上自 10-08(PR #13)之后就没有绿过;本 PR 覆盖 Pillow、三处基线失败、一处 Windows 产品缺陷,以及浏览器探针的三处 CI 环境问题。

五个提交:

  1. b2340f8 Pillow:scripts/android-runtime/tests/android-apk-resources.test.js 用内联 Python 导入 PIL,runner 没有 Pillow;在 pnpm test 前加 python -m pip install pillow。
  2. 0926e77 产品修复:fork 继承工具结果的读取鉴权。官方 Session fork 读取祖先会话溢出的工具结果时,鉴权拿 realpath 得到的原生路径去继承到的工具文本里做子串匹配;Windows 的溢出提示把 file_path 写进 JSON,反斜杠被转义成两个字符,匹配必然失败(报「该工具结果不属于当前会话可读取的内容」)。现在归属记录额外写入保存时的 locator,鉴权对 realpath 路径与 locator 各取原生、正斜杠、JSON 转义三种写法,任一命中即通过;仍然要求同一次工具调用的 callId 命中且文本出现在继承事件里,不放宽可见范围。
  3. ef8bce7 三处测试环境失败:
    • native-author-docs:示例正文与卡片 JSON 内嵌正文比较前归一化 CRLF,并给 packages/examples/native-author/** 加 text eol=lf(Windows 检出 core.autocrlf 会把前者变成 CRLF)。
    • windows-installation-integrity:断言改为「异常退出且没有产出结果」,不再绑定具体 NTSTATUS(runner 镜像与 Chromium 版本会给出 0xC0000005 而不是 0x80000003)。
    • mobile-editor-layout:Electron 启动遇到 EBUSY/ETXTBSY/EPERM 时退避重试两次(1s、2s),其他错误照旧上抛。
  4. 6ae3166 浏览器探针的两处 CI 环境问题:
    • side-panel-motion:runner 的操作系统可能报告 prefers-reduced-motion: reduce,shell 的 grid 过渡在 reduce 下是 none,probe 等不到动画。probe 现在在页面加载后、第一次点击前用 DevTools Emulation 固定 no-preference,减少动效用例仍显式切 reduce。
    • 浏览器测试在 Windows CI 上偶发 spawn EBUSY(刚安装的 Electron 镜像被杀软/句柄锁住):vitest 的 browser 项目加 retry: 2,覆盖所有探针;mobile-editor-layout 的内联重试保留,恢复更快。
  5. b04d614 side-panel-motion 的模拟视口:GitHub Windows runner 的屏幕只有 1024 宽,窗口被宿主限制,useSidePanelLayout 按 min-width 把侧栏压到 325(期望 328)。probe 用 Emulation.setDeviceMetricsOverride 显式模拟 1400/960 视口,布局不再依赖宿主屏幕。

Architecture route(架构归属)

  • Main 新文件仅承担桌面壳职责,位于 host / modules / platform / i18n(无新增 Main 文件)
  • Shared 新文件位于闭合集合:contracts / foundation(无新增 Shared 文件)
  • 产品跨 Host/Client 查询与命令使用生成的 Typert Remote;会话事件、分页与 projection 使用 DSH Connection 正式协议,未新增业务 IPC 或私有桥
  • Renderer 未直接访问 Electron、Node、SQLite 或 DSH SDK(无 Renderer 改动)
  • 官方运行时装配隔离在 @eleckoi/dsh-runtime;Host/Client 插件使用同版本公开合同,上游包仍是同一个精确版本批次(无版本变化)
  • 新业务进入 DSH Host/Client 插件;产品数据库与 Repository 由 @eleckoi/dsh-product-data 独占,跨模块依赖只使用对方 index.ts 公开面(产品改动在 dsh-client-roleplay Host 插件内部)
  • 长生命周期资源已注册为 Host/Cordis Plugin,并能反向释放(无新增长生命周期资源)

Data and compatibility(数据与兼容)

  • Schema 改动附带新的向前迁移,没有重写已发布迁移(无 Schema 改动)
  • 没有把会话、消息、角色或模型配置写入 localStorage
  • 旧数据、取消、失败或异常退出路径已考虑

产品兼容说明:工具结果归属记录新增 locator 字段。旧记录没有这个字段——POSIX 不受影响(原生路径就是 JSON 安全形式),Windows 上修复前写下的旧记录在跨 fork 读取时仍可能失败;修复后写下的新记录带 locator。

回滚与影响面

  • Door: two-way。revert 五个提交再重跑 pnpm build 即可;没有数据迁移,产品数据库与 Session 日志都不动。
  • Blast Radius: ci + roleplay-tool-results。产品改动只影响跨 fork 读取工具结果的鉴权路径,不改变正常同会话读取。

Verification(验证)

Windows 本机复跑(维护者机器):

  • tests/integration/tool-result-recovery.test.js:24/24 passed(修复前 desktop-ci 上 2 个 fork 用例失败)。
  • tests/integration/native-author-docs.test.ts:把 packages/examples/native-author 的 10 个文本文件转成 CRLF 模拟 Windows 检出后,2/2 passed;临时去掉归一化后复现 CI 的原断言 expected { type: 'script', … } to match object { enabled: false, … }。
  • side-panel-motion.probe.cjs:node --check 通过;vitest.config.ts 用 vite 加载确认 8 个 project、browser 的 retry 为 2。

CI:由本 PR 的 desktop-ci 执行全量。本机 Electron 44 GUI 启动即崩(0xC0000005,官方 dist 同样),浏览器与安装完整性用例无法本地复跑,由 CI 验证。

Review scope(审查范围)

  • .github/workflows/desktop-ci.yml
  • packages/client/features/dsh-client-roleplay/src/host/tool-result-store.mjs
  • .gitattributes
  • tests/integration/native-author-docs.test.ts
  • apps/desktop/tests/windows-installation-integrity.test.js
  • apps/web/tests/browser/mobile-editor-layout-browser.test.js
  • apps/web/tests/browser/side-panel-motion.probe.cjs
  • vitest.config.ts

解决的问题:

1. desktop-ci 的 pnpm test 在 windows-latest 上失败:scripts/android-runtime/tests/android-apk-resources.test.js 用内联 Python 脚本导入 PIL,runner 没有 Pillow,报 ModuleNotFoundError,job 在 pnpm build 之前中止。

怎么解决:

1. 在 pnpm test 之前加一步 python -m pip install pillow。
解决的问题:

1. 官方 Session fork 读取祖先会话溢出的工具结果时,鉴权拿 realpath 得到的原生路径去继承到的工具文本里做子串匹配。Windows 的溢出提示把 file_path 写进 JSON,反斜杠被转义成两个字符,匹配必然失败,报「该工具结果不属于当前会话可读取的内容。」;Linux 的分隔符不经 JSON 转义,所以只有 Windows 复现(desktop-ci #48 的两个 fork 用例)。

怎么解决:

1. 归属记录额外写入保存时的 locator;鉴权对 realpath 路径与 locator 各取原生、正斜杠、JSON 转义三种写法,任一在继承文本中出现即通过。
2. 仍然要求同一次工具调用的 callId 命中、且文本出现在继承事件里,不放宽可见范围;顺带覆盖 8.3 短名被 realpath 展开导致 locator 与 path 不一致的情况。

验证:

- 在 Windows 上按溢出提示的实际拼装方式验证:旧判定 false,新判定 true;换成同目录另一个文件仍为 false。
- POSIX 下三种写法彼此相同,行为不变。
解决的问题:

1. native-author-docs 把示例 .js/.html 的磁盘正文与卡片 JSON 内嵌正文直接比较;Windows 检出(core.autocrlf=true)把前者变成 CRLF,后者仍是 LF,断言必失败。
2. windows-installation-integrity 断言被破坏沙箱的崩溃码恰好是 0x80000003;runner 镜像与 Chromium 版本不同会变成 0xC0000005,用例与实现无关地失败。
3. mobile-editor-layout 浏览器用例直接启动 Electron 探针,Windows CI 上偶发 spawn EBUSY(镜像文件被杀软或残留句柄占用),布局断言根本没跑到。

怎么解决:

1. 示例正文比较前归一化 CRLF,并给 packages/examples/native-author/** 加 text eol=lf,避免重新检出又变回 CRLF。
2. 断言改为「异常退出且没有产出结果」,不再绑定具体 NTSTATUS;code === 1 的诊断路径保持原样。
3. 启动失败且错误码为 EBUSY/ETXTBSY/EPERM 时退避重试两次(1s、2s),其他错误照旧上抛。

验证:

- 用真实 git 复现检出行为:无该属性时 character.js 检出为 CRLF,加属性后为 LF(core.autocrlf=true)。
- 本机没有 Windows 依赖,受影响的桌面/浏览器用例未本地复跑,由 desktop-ci 运行验证。
@KuramiWan KuramiWan changed the title 修复桌面 CI:为 Android 资源测试安装 Pillow 修复 Windows 桌面 CI 基线:Pillow、工具结果鉴权与三处测试环境 Oct 18, 2026
解决的问题:

1. side-panel-motion 在 desktop-ci 上确定性失败:runner 的操作系统可能报告 prefers-reduced-motion: reduce,titlebar.css 在 reduce 下把 grid 过渡设为 none,probe 等不到动画。probe 只在最后显式模拟 reduce,默认路径没有固定偏好。
2. 浏览器测试在 Windows CI 上偶发 spawn EBUSY:刚安装的 Electron 镜像被杀软或残留句柄锁住;上一轮只给 mobile-editor-layout 加了内联重试,这次同一个错误换到了 chat-bottom-control-layout。

怎么解决:

1. side-panel-motion.probe 在页面加载后、第一次点击前用 DevTools Emulation 固定 prefers-reduced-motion: no-preference;减少动效用例仍显式切成 reduce。
2. vitest 的 browser 项目加 retry: 2,覆盖所有浏览器探针的启动锁;mobile-editor-layout 的内联重试保留,恢复更快。
解决的问题:

1. 固定动效偏好后,用例继续跑到宽度断言:GitHub Windows runner 的屏幕只有 1024 宽,窗口被宿主限制,useSidePanelLayout 按 min-width 把侧栏压到 325(期望 328),确定性失败。

怎么解决:

1. 用 DevTools Emulation.setDeviceMetricsOverride 显式模拟 1400/960 视口,布局不再依赖宿主屏幕;resize 用例同步覆盖 960/1400。
KuramiWan added a commit to KuramiWan/ElecKoi that referenced this pull request Oct 18, 2026
并入上游 PR eleckoi#16(b04d614)的 5 个提交:Pillow、工具结果 fork 鉴权、
CRLF 比对、浏览器重试与视口/动效模拟、安装完整性退出码。
理由:0.2.13 基线在 windows-latest 上本来就红这 7 条;不并它,本 PR 的
Windows CI 无法反映错误处理改动的真实结果。等 eleckoi#16 落到上游后这些提交是 no-op。

验:真机(CAMEL-PC,Node 24.20.0)上 unit / ui / host / tooling 与关键
integration 用例共 258 文件 / 1907 用例全过;闸测试在 CRLF 检出下 8/8。

This branch has not been deployed

No deployments
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