Explorar el Código

docs(boot): clarify patch path conversion ownership

Tianyi Cui hace 1 mes
padre
commit
4826e0c2a3

+ 6 - 0
.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.md
+2026-09-05-patch-plugin-file-urls.md: 48112483b4a3eef1fefcb774c2d19a2c901ccbdb
+2026-09-05-patch-plugin-file-urls.zh.md: 775a576324dd2856f490cf3ce3ba907965737fc2

+ 27 - 0
.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.md

@@ -0,0 +1,27 @@
+# Agent Note: File URLs for inserted patch plugins
+
+Status: implemented
+
+English | [中文](2026-09-05-patch-plugin-file-urls.zh.md)
+
+## Problem
+
+Node ESM interprets a Windows drive prefix as a URL scheme and treats filename fragments as URL syntax. Passing filesystem paths directly to plugin imports therefore fails for Windows absolute paths and filenames containing `#` or `%`.
+
+## Decision
+
+Patch-file parsing converts native absolute paths and patch-relative `./` or `../` names to file URLs inside `insert` rows and their nested groups. Package specifiers, existing URLs, existing-entry name assertions, and replacement `config` values retain their meaning. Parsing owns this conversion because it knows the originating patch directory before layers are composed.
+
+The optional `HostResolvedRootInclude` import override separately converts absolute paths for callers selecting an installed-host resolver base. Ordinary CLI profiles do not select that override; it cannot substitute for patch-file conversion.
+
+## Alternatives considered
+
+**Convert only the Python fixture with `Path.as_uri()`.** This avoids one failure but leaves user-authored profile and overlay patches exposed.
+
+**Change the shared Loader base.** This loses per-patch provenance and changes bare-package resolution. File URLs preserve the selected local file without changing the resolver base.
+
+## Consequences
+
+Optional and required patch readers share the conversion. Direct Loader imports and children introduced through replacement group configs remain outside its scope; extending those paths requires their own semantics and coverage.
+
+The patch-reader tests verify conversion and real activation. The built SDK acceptance loads an absolute-path overlay plugin with URL-sensitive filename characters and verifies its filesystem marker, initialization, and shutdown.

+ 27 - 0
.agents/notes/implemented/bug-fix/2026-09-05-patch-plugin-file-urls.zh.md

@@ -0,0 +1,27 @@
+# Agent Note: 插入补丁插件的文件 URL
+
+Status: implemented
+
+[English](2026-09-05-patch-plugin-file-urls.md) | 中文
+
+## Problem
+
+Node ESM 会把 Windows 盘符前缀解释为 URL scheme,并把文件名中的片段字符视为 URL 语法。因此,直接将文件系统路径传给插件导入会使 Windows 绝对路径以及包含 `#` 或 `%` 的文件名加载失败。
+
+## Decision
+
+补丁文件解析将 `insert` 条目及其嵌套分组中的本机绝对路径、相对于补丁文件的 `./` 或 `../` 名称转换为文件 URL。包标识符、已有 URL、已有条目的名称断言及替换用的 `config` 值保持原有含义。解析阶段负责转换,因为在合并各层之前它掌握来源补丁的目录。
+
+可选的 `HostResolvedRootInclude` 导入覆写会另外为选择安装宿主解析基址的调用方转换绝对路径。普通 CLI profile 不选择该覆写,因此它不能代替补丁文件转换。
+
+## Alternatives considered
+
+**只在 Python fixture 中使用 `Path.as_uri()`。** 这能避开一次失败,但用户编写的 profile 和 overlay 补丁仍会遇到问题。
+
+**修改共享 Loader 基址。** 这会丢失逐补丁来源信息并改变裸包解析。文件 URL 保留选定的本地文件,无需修改解析基址。
+
+## Consequences
+
+可选与必需补丁读取器共用该转换。直接 Loader 导入及替换分组 config 引入的子条目不在其范围内;扩展这些路径需要各自的语义与覆盖。
+
+补丁读取器测试验证转换与真实激活。构建后 SDK 验收加载文件名含 URL 敏感字符的绝对路径 overlay 插件,并验证其文件系统标记、初始化与关闭。

+ 2 - 2
packages/boot/app-boot/README.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write packages/boot/app-boot/README.md
-README.md: 3f0f5fe369eb8965dbd9d606f5eaf4065e4e450a
-README.zh.md: 35a507d57aec1a189128a8be9666ebec74976e4c
+README.md: 72b10524b6632f90d3bf7852b0504718518a5c33
+README.zh.md: bbbae612a6fdc9c1060902691f4349ca0b9ae806

+ 1 - 1
packages/boot/app-boot/README.md

@@ -54,7 +54,7 @@ Your machine-local preferences also live in the Harness home:
 
 Profiles with `patchReload: live` watch both user patch files: a valid edit recomposes without restart, while a rejected edit leaves the last good app running. A `startup` profile installs neither those watchers nor the launcher's watch-only HMR fallback.
 
-Inserted plugin names may be absolute filesystem paths, file URLs, or package specifiers. Patch loading converts absolute paths and patch-relative `./` or `../` paths to file URLs, including nested group entries; existing-entry name assertions remain literal.
+Inserted plugin names may be absolute filesystem paths, file URLs, or package specifiers. Patch loading converts absolute paths and patch-relative `./` or `../` paths to file URLs within `insert` rows and their nested groups; existing-entry name assertions and replacement `config` values remain literal.
 
 ### Previewing the effective configuration
 

+ 1 - 1
packages/boot/app-boot/README.zh.md

@@ -54,7 +54,7 @@ profile 是同一套 dsh 安装提供不同应用界面的方式:`web`、`head
 
 带 `patchReload: live` 的 profile 会监视两份用户 patch 文件:有效编辑无需重启即可重新组合,被拒绝的编辑则让最后一个可用应用继续运行。`startup` profile 既不安装这些监视器,也不安装 launcher 的仅监视 HMR 回退。
 
-插入条目的插件名可以是绝对文件系统路径、文件 URL 或包标识符。patch 加载会把绝对路径以及相对于 patch 文件的 `./` 或 `../` 路径转换为文件 URL,嵌套分组条目也适用;对已有条目名称的断言保持原样。
+插入条目的插件名可以是绝对文件系统路径、文件 URL 或包标识符。patch 加载会把 `insert` 条目及其嵌套分组中的绝对路径以及相对于 patch 文件的 `./` 或 `../` 路径转换为文件 URL;对已有条目名称的断言及替换用的 `config` 值保持原样。
 
 ### 预览生效配置