Skip to content

refactor(desktop): 删除 Core 的 Java 启动规划,run/start 临时文件支持 base64 字节 - #1859

Merged
xiaoyumuxi merged 1 commit into
previewfrom
refactor/desktop-drop-core-launch-plan
Nov 13, 2026
Merged

xiaoyumuxi merged 1 commit into
previewfrom
refactor/desktop-drop-core-launch-plan

Conversation

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator

关联 Issue / Linked issue

PR 类型 / Type

  • feat:新功能或用户可见的改进
  • fix:缺陷修复
  • docs:文档、Agent Note、Skill 等规则文件
  • release:稳定版发布准备

改动说明 / What changes

背景 / Why

以前,插件发起的每个非调试运行都会先经过 Core 的 execution.planLaunchCommand:

  1. Core 判断启动器是不是 JDK 9 及以上的 java;
  2. 如果命令行超过 Windows 上限,Core 把 -cp、--module-path 等路径列表搬进 JDK 参数文件;
  3. 桌面端读取 JDK 的 release 文件得到版本,再按系统 ANSI 代码页写出参数文件。

这让 Core 和宿主都写死了 Java 知识。Core #23 删除了这个命令,所以桌面端也删除整条调用链。之后宿主按原样启动插件给出的命令行。命令行需要缩短时,由插件生成文件,通过 temporaryFiles 交给宿主;需要特定编码或二进制内容时,用新增的 base64 形式。

改动 / Changes

  • 删除 Java 启动规划
    • 删除 desktop/internal/core/launch_plan.go,即 execution.planLaunchCommand 的客户端封装。
    • 删除 desktop/internal/pluginservice/runargs.go:读取 JDK release 版本、写参数文件。
    • 删除 argfile_encoding_windows.go 和 argfile_encoding_other.go:Windows ANSI 代码页编码,其他平台写 UTF-8。
    • pluginservice/runs.go 删除 launchPlanner 分支。非调试运行直接把 start.Arguments 交给 buildprocess.Start。
  • 临时文件支持字节
    • core.RunStartFile 增加 Base64 字段,以及 Bytes() 方法:有 Base64 时返回解码后的字节,否则返回 Contents 的 UTF-8 字节。
    • runs.go 写临时文件改用 Bytes()。解码失败按写入失败处理,删除临时目录,返回 plugin.host.failure。Core 已经校验过 base64 和大小,所以这条路径只在 Core 与宿主对契约理解不一致时才会走到。
  • 测试
    • 新增 TestRunStartWritesTemporaryFilesAsGiven。插件给出三个临时文件:含非 ASCII 字符的文本、含 0x95 0x5c 0x00 0xff 等非 UTF-8 字节的 base64、空的 base64。被启动的进程按 ${temporaryFile:<name>} 读取这些文件,测试确认内容逐字节一致。
    • core/run_start_test.go 不需要改。它回放 Core 的 run-start.json,已经覆盖 fix:修复左侧Git提交文件无法全选问题 #23 新增的三条拒绝用例:同时给出 contents 和 base64、两者都不给、base64 不合法。
  • Core pin:scripts/desktop/build-desktop-core.sh 的 PINNED_CORE_REVISION 升到 fix:修复左侧Git提交文件无法全选问题 #23 的头提交 5a8e67d,注释同步更新。
  • 功能矩阵:run-java-long-classpath 两端都从 implemented / pending 改成 plugin-provided / not-applicable。证据换成 runs.go、run_start.go;验证和备注改为“由 Java 插件实现,宿主只验证 temporaryFiles 写入与清理”。
  • 迁移文档:docs/viva-migration.md 中这一行的扩展点改成 run/start 的 temporaryFiles,并指向 lithe-plugin-java#7。
  • 工作树资源登记
    • scripts/resources/worktree-resources.json 的 java-launch-temporaries 改名为 run-temporary-files。
    • 路径从旧客户端的 <system-temp>/lithe-run/launch-*.argfile|.classpath.jar 改成桌面端实际使用的 <system-temp>/lithe-run-<random>/,说明改成通用的插件运行临时文件。
    • test-reuse-worktree-resources.mjs 和 docs/ci-builds.md 同步更新。
  • Agent Note
    • 新增 .agents/notes/implemented/architecture/2026-11-13-plugin-owned-long-command-lines.md,记录“插件缩短、宿主按字节写入”的决策和被否方案,并保留插件实现时仍要遵守的事实:只搬路径列表、Windows 用 ANSI 代码页、0x5c 尾字节、JDK 8 用 classpath JAR。
    • 旧 Note 2026-09-20-oversized-java-launch-command.md 移到 archived/bug-fix/,加上归档日期和取代说明。

不在本 PR 范围内 / Out of scope


类型专属:fix

复现与根因

  • 复现步骤、实际结果、期望结果:无用户可观察缺陷。这是重构:Core 规则要求对 Java 零特判,Core fix:修复左侧Git提交文件无法全选问题 #23 删除了 execution.planLaunchCommand,桌面端不能再调用它。
  • 根因:Java 启动规划在旧客户端时期放进了 Core(Core lithe 0.1.14 #13),桌面端随后接入(runargs.go、argfile_encoding_*.go)。
  • 影响平台:macOS、Windows 共用的 desktop/internal/pluginservice。

检查项


范围检查 / Scope checks

功能矩阵 / Feature matrix

  • 已更新 shared/platform-feature-matrix/features/run-java-long-classpath.json:两端改为 plugin-provided / not-applicable,证据、验证和备注同步修改
  • 已运行 ./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh 和 ./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD
  • 没有提交 .artifacts/ 下生成的矩阵视图
  • [N/A] 没有更新矩阵的理由:已更新

统一日志系统 / Structured logging

N/A:没有新增或改动日志事件。删除的规划分支没有日志;写入失败沿用原有的 plugin.host.failure 返回。

界面文案 / i18n

N/A:没有用户可见文案。删除的 the run's argument file cannot be written 是返回给插件的宿主错误消息,不是界面文案。

逻辑归属 / Logic placement

  • 可共享的逻辑在 Rust Core:temporaryFiles 的个数、名字、大小、base64 校验都在 Core 的 run.decodeStart,契约和 fixture 在 fix:修复左侧Git提交文件无法全选问题 #23;桌面端只做解码和写盘
  • 修改平台层已有的可共享逻辑时已迁入 Core:本 PR 是反方向,把只属于 Java 的逻辑从 Core 和宿主移给插件
  • 工具或运行时专属的知识放在插件或成熟上游:JDK 版本、参数文件格式和编码都交给 Java 插件,宿主和 Core 不再按 java 分支

性能与内存 / Performance and memory

N/A:没有新增后台功能、子进程或缓存。非调试运行少了一次 Core 调用和 JDK release 文件读取。

设置 / Settings

N/A:没有设置改动。

插件契约 / Plugin contract

原计划编号 方法 用途
API-23 lithe/host/run/start(temporaryFiles[].base64) 插件以 base64 给出临时文件的字节,宿主按原样写入,用于 Windows ANSI 编码的参数文件和 classpath JAR

发行包与资源 / Bundle and resources

  • 运行时不向已安装的 app bundle 或安装目录写入:临时文件写在 os.MkdirTemp("", "lithe-run-") 创建的系统临时目录,运行结束、启动失败或 Core 拒绝后删除;已运行 ./scripts/desktop/verify/verify-runtime-bundle-immutability.sh
  • 已同步 scripts/resources/worktree-resources.json、test-reuse-worktree-resources.mjs 和 docs/ci-builds.md。reuse-worktree-resources.mjs 按注册表里的 excludedResources 统一拒绝,不需要单独路由

无用代码与重构 / Dead code and refactoring


验证 / Verification

所有命令都在 macOS(Apple Silicon)上运行,LITHE_CORE_RUST_DIR 指向 #23 头提交 5a8e67d 的检出。

命令 结果
./scripts/desktop/desktop-go.sh vet ./internal/core/ ./internal/pluginservice/ 通过
./scripts/desktop/desktop-go.sh test -race ./internal/core/ ./internal/pluginservice/ 通过
./scripts/desktop/desktop-go.sh test ./... 55 个包全部通过,0 失败
./.agents/skills/write-stable-tests/scripts/test-stability-macos.sh --package ./internal/pluginservice -- --filter 'TestRunStart' 通过,记录 6 个测试结果
./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh --base origin/preview(静态检查) 通过
./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh 通过
./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD 通过
./scripts/agent-notes/verify-agent-notes.sh 通过,219 份有效 Note
node scripts/i18n/verify-app-language-localization.mjs 通过,中英各 11059/11059
node scripts/i18n/generate-i18n.mjs --check 通过
./scripts/desktop/verify/verify-runtime-bundle-immutability.sh 通过(桌面端 macOS 与 Windows 源码静态检查)
node scripts/resources/test-reuse-worktree-resources.mjs 通过

未能执行的检查和原因:

  • Windows:本机是 macOS,没有在 Windows 上运行 desktop-go.sh test。argfile_encoding_windows.go 删除后,pluginservice 没有剩下 Windows 专属代码。Draft 状态只跑 Linux 检查,标记 ready 后的完整 CI 会覆盖 Windows 编译和测试。
  • 整机工作流:没有启动 Lithe 做真实的 Java 运行验收。在 Java 插件实现 lithe-plugin-java#7 之前,这条路径无法端到端验证。

提交前确认 / Final checks

  • 分支从最新的 preview(170ad19e6)创建,目标分支 preview
  • 以 Draft 提交,本地验证通过后才标记 ready
  • 没有无关改动,没有提交产物、凭据、个人路径
  • 本次没有启动 Lithe 应用;测试启动的子进程(测试二进制本身)都由测试清理

宿主按原样启动插件给出的命令行,不再调用 Core 的 execution.planLaunchCommand,
也不再读取 JDK 版本、按系统代码页写参数文件:
- 删除 core/launch_plan.go、pluginservice/runargs.go、argfile_encoding_*.go,
  以及 runs.go 里的规划分支;
- core.RunStartFile 增加 Base64,宿主解码后原样写入,文本仍按 UTF-8 写入;
- 新增测试:进程读到的临时文件与插件给出的文本、字节逐字节一致;
- PINNED_CORE_REVISION 升到 Lithe-core-rust#23;
- 功能矩阵 run-java-long-classpath 改为插件提供,资源登记改名为
  run-temporary-files 并修正路径;
- 新 Agent Note 记录决策,旧的超长 Java 启动命令 Note 归档。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant