用内核的 sub-rules 机制:listener 写 rule: 指向顶层 sub-rules 里的表 (listener/inbound/base.go:96,tunnel.go:713-721)。两个硬约束决定了 形态:proxy 优先级更高且完全短路规则匹配(tunnel.go:318-325),有附加 规则时 listener 只能写 rule;子规则表没命中时兜底是 DIRECT 而不是这一 路的出站(tunnel.go match 循环末尾),表底那条 MATCH,专属组 是承重的, 由 Patchbay 自动维护、界面上单独画不参与编辑。不变式:附加规则空 ⇔ proxy 直连专属组,非空 ⇔ rule 形态。 三处既有逻辑教会认 rule 形态:applySetup 不再无条件写 proxy(会把附加 规则静默短路掉);referencesTo 扫 sub-rules 里的规则——表底 MATCH 是 rule 形态下专属组活着的唯一理由,不数它就会被当孤儿清掉;pruneGenerated 清理没有 listener 引用的生成表。panelGroups 和 syncGenerated 的「是否 由 Patchbay 接线」收敛成一个 managedWiring。 listener 的 rule 指向不存在的表时内核静默退回全局规则(getRules 的 else 分支),-t 和重载都不拦,自检里补上这条(vendor 本地改动,记入 ORIGIN.md)。界面:详情列新增附加规则区块,逐条增删改和排序复用 RuleForm,带内网直连预设;生成形状过了 mihomo -t 实测。
2.1 KiB
2.1 KiB
config-editor 的来源
复制自 metacubexd(GitHub MetaCubeX/metacubexd,MIT 许可),路径 packages/config-editor/src/,取自版本 1.271.0。
采用它的理由和已知缺陷记在决策记录 0002。决策记录不在本仓库里,它们放在仓库外面的工作区目录 docs/adr/(与 patchbay/ 平级)。
本地改动
对照上游逐条记录,方便将来同步上游修复时区分「我们改的」和「上游变的」。
| 文件 | 改动 | 原因 |
|---|---|---|
index.test.ts |
测试框架的导入从 vitest 换成 bun:test |
本项目用 Bun 自带的测试运行器,不引入 vitest。两者的 describe / it / expect 接口一致,用例本身一行没动 |
index.ts |
stringifyTouched 结尾的 String(doc) 换成 doc.toString({ flowCollectionPadding: false, lineWidth: 0 }) |
上游用默认输出参数,会把 [a, b] 改写成 [ a, b ],并且在超过 80 列时折行——目标机器的订阅地址就够长。这两样都会让没被改动的段落出现在 diff 里 |
index.ts |
validateDocument 末尾新增:listener 的 rule: 指向不存在的 sub-rules 表时报 missing-reference |
内核对这种引用静默退回全局规则(tunnel.go getRules 的 else 分支),mihomo -t 和重载都不会拦,只有这层自检能拦住 |
配套的本项目代码
shared/yaml-cosmetics.ts 里的 restoreInlineCommentAlignment 不属于上游,是本项目补的一步。yaml 库把行尾注释的文字存在节点上,但不存注释前的对齐空格,所以重新输出时 interval: 86400 # 说明 会变成 interval: 86400 # 说明。那个函数在写回之后逐行比对,把只差对齐空格的行还原成原文。
加上这两处之后的实测结果记在决策记录 0002 的「实测」一节。要自己重跑一遍:bun run scripts/roundtrip.ts <配置文件> <输出目录>,再拿输出跟源文件比对。
同步上游
上游修了 bug 想同步时:拉取 metacubexd 对应版本的 packages/config-editor/src/index.ts,与本目录的同名文件比对,把上表里的本地改动重新应用一遍。