Qiu Yuzhou
7ab774fcfd
chore(legacy): 移除 Legacy/ 旧版源码,归档到 legacy-v1 分支
...
旧版实现已由 shadowsocks/ShadowsocksX-NG 的 legacy-v1 分支跟踪,本仓库不再
保留同一份代码副本。删除 Legacy/ 下 603 个跟踪文件,被 gitignore 的
.DS_Store 一并清理。
删除前核对:Legacy/ShadowsocksX-NG/PACUtils.swift 的 blob hash 与
upstream/legacy-v1 的同名文件完全相同,且工作区在 Legacy/ 下无未提交改动。
配套改动:
- 根 README、AGENTS.md、ShadowsocksX-NG2/README.md:目录结构只留
ShadowsocksX-NG2/;旧版说明改为指向 shadowsocks/ShadowsocksX-NG 的
legacy-v1 分支(含其 README);pre-commit 说明去掉 Legacy/。
- codegraph.json 删除 "exclude": ["Legacy/"];.gitignore 与 .zcodeignore
删除 Legacy 构建产物与依赖条目;.swiftlint.yml 删除 ../Legacy 排除项;
.githooks/pre-commit 头部注释去掉冻结目录表述。
- docs/research 的 4 份历史研究报告(issue 7/11/12/17)中 129 处
../../Legacy/... 相对链接改写为 legacy-v1 的 GitHub blob 链接,正文未改;
把新 URL 反替换回原相对路径后与 HEAD 版本逐字节相同,证明只动了链接。
验证:全仓库不再有指向 Legacy/ 的路径引用;剩余 Legacy 字样均为概念性用法
(Legacy 导入功能、ADR 与术语表、历史报告正文中的冻结陈述)。本次未改任何
NG2 源码或构建配置,暂存区无 NG2 .swift 文件,pre-commit 直接放行。
2026-10-05 21:39:06 +08:00
Qiu Yuzhou
9b6d73e91c
build(signing): 签名身份按 config 注入,Debug 免证书构建
...
证书与 Team 不入库(开源仓库):Debug 基线改为 ad-hoc,新 clone 与 CI 无
需任何证书即可 task build / task test;Release 基线保持 Developer ID,发
布产物仍须真签名。本机身份由 gitignore 的 Configs/Signing.local.xcconfig
注入,打包门槛的 Team 期望值同源,缺失时明确失败而非静默跳过。
project.yml 不能再设置 CODE_SIGN_IDENTITY / DEVELOPMENT_TEAM:pbxproj 构
建设置优先于 project xcconfig,写死会静默盖掉基线(实测)。整条注入链条
由 Tests/Architecture/SigningConfigurationTests.swift 守卫。
ad-hoc 产物不带 Hardened Runtime(Xcode 对 ad-hoc 签名不传 -o runtime),
嵌套 helper 重签与之一致;Hardened Runtime 仍由 DevID 路径与打包门槛断言。
2026-10-05 21:25:12 +08:00
Qiu Yuzhou
aa9d83149b
fix(tasks): add dependency on project generation for build and test tasks
2026-10-05 20:47:12 +08:00
Qiu Yuzhou
3f581d3514
chore(lint): 排除 xcodebuild 落在项目内的 build/ 目录
...
不带 -derivedDataPath 的 xcodebuild 会把构建落进项目内的 build/,其中
DerivedSources/ 下生成的源码(如 GeneratedAssetSymbols.swift)会进 lint 范围,
报出与手写代码无关的 trailing_newline。excluded 原有 DerivedData 与 .build
两条,漏了 build/。
触发案例与效果实测:排除后 lint 从 21 条 warning / 320 个文件降为 19 条 /
318 个文件;消失的 2 条都来自 build/ 下两个 GeneratedAssetSymbols.swift 的
trailing_newline,剩余 19 条全部是内容型规则(file_length、function_body_length、
type_body_length、cyclomatic_complexity、implicit_optional_initialization),
与路径无关。
这同时纠正了此前几轮「与整理前同为 21 条基线」的归因:那 21 条里有 2 条来自
遗留构建产物,手写代码的真实基线是 19 条;各轮前后对比仍成立,只是绝对值
应按 19 条理解。
2026-10-05 20:38:58 +08:00
Qiu Yuzhou
20a62117f2
refactor(tests): 按功能领域重组 Tests/ 目录
...
Tests/ 根层原有 138 个平铺测试文件,无法从目录读出测试覆盖的功能领域。
按功能领域重组为 17 个目录(Catalog/Workflow 与 Rules/Custom 两处嵌套,分别
对应 App/Application/CatalogWorkflow 与 Domain/Rules/Custom):Architecture /
Support / Agent / Activation / Catalog / Subscription / Rules / ProxyRuntime /
ProxyControl / Runtime / Settings / SystemProxy / Plugin / Diagnostics /
Credentials / Workspace / Servers;Smoke/ 保持独立 target 不动。138 个移动中
132 个是 100% 相似度的纯重命名,其余 6 个在重命名之上带路径反推改写(见下)。
本次不是纯搬移:测试代码比生产代码多一层位置耦合,有 7 处用固定层数的
deletingLastPathComponent() 从 #filePath 反推仓库路径(都假定文件就在 Tests/
根层)。这 7 处改走新增的 Tests/Support/TestSourceTree.swift——从调用点沿父
目录上溯找到含 project.yml 的目录,因此不再依赖父目录层数,以后移动测试文件
也不会静默指错。
配套改动:
- 新增 Tests 布局守卫 TestsLayoutTests,断言 Tests/ 根层无平铺 .swift。比
Domain 那条弱一档——根层的 Info.plist(info.path 生成物)与
Fixtures/RuleSnapshots 下的 JSON(folder resource)都必须保留,不能用
「树下只有 .swift」覆盖。
- project.yml:Smoke target 按文件引用的 Tests/AppArtifact.swift 改指
Tests/Support/;两处注释里写死的 Tests/SkeletonTests.swift 随移动更新。
excludes 的裸名 "Smoke" / "Fixtures" 仍匹配 Tests/ 直属子目录,无需改动。
- README 的 Tests 条目展开为目录说明,并修掉 Domain 条目里写死的
Tests/SkeletonTests.swift。
- 顺带删去 DomainLayoutTests 文档注释里「整理前 62 个文件」这类易漂移的数字。
验证:xcodegen generate 后单测 target 为 139 个源文件(全部非 Smoke 文件,0 个
Smoke 文件混入)且仍以 Fixtures/RuleSnapshots 为资源,Smoke target 为 8 个
Smoke 文件加 AppArtifact;依赖路径反推的 6 个测试类全绿(路径指错即失败);
task format 未改写任何被移动文件;task lint 与整理前同为 21 条内容型 warning;
build 0 error;task test 1025 用例全通过(整理前 1024,+1 为新守卫);
TestsLayoutTests 经变异验证(根层投放探针即失败);packaging-gate ALL CHECKS
PASSED。
2026-10-05 20:37:35 +08:00
Qiu Yuzhou
a31e2fa4bf
docs(adr): 记录源码目录即分层与主题及守卫约定
...
App/ 按分层、Domain/ 按主题组织,两个根层只放子目录、不放平铺文件;边界由
Tests/SkeletonTests.swift 的守卫正面圈定断言,而不是禁令加豁免登记。
ADR-0029 只记录组织原则本身:分层与主题划分的依据(Domain 主题名取自
GLOSSARY.md 的章节划分)、四条被否决的备选(平铺加豁免登记、feature-first、
Domain 照搬分层、守卫锁定目录集合),以及两条在代码里不可见的 XcodeGen
约束和跨进程契约按文件引用的代价。
ADR 不维护目录与文件清单——清单由 ShadowsocksX-NG2/README.md 的工程结构
一节维护,避免记录随事实漂移。
project.yml 的两处分层注释与 README 的工程结构一节各加一处引用:前者按该
文件既有写法引用编号,后者用完整链接。
2026-10-05 20:27:11 +08:00
Qiu Yuzhou
67d0afcda1
fix(hooks): 区分 SwiftLint 工具失败与 error 级违规
...
pre-commit 第 2 关只看 swiftlint 是否非零,把任何非零都报成「SwiftLint
发现 error 级违规」。而 SwiftLint 默认要把缓存 plist 写进
~/Library/Caches,写不进去时它自己以退出码 1 失败,于是受限环境下每次
提交都被拒绝、并被指向代码,实际原因在工具环境。
两处改动:
- 加 --no-cache,直接消灭缓存写入这一失败模式(本关只查几十个暂存文件,
代价可忽略;task lint 本来就是这么调的)。
- 按退出码分派:0 放行(有 warning 则提示后放行)、2 报「发现 error 级
违规」、其余报「执行失败(退出码 N)」并点明是工具错误而非代码违规。
不能改用解析输出文本判断:工具错误信息里同样含 "error:"(配置读不了时
输出 error: Could not read file at path ...),只有退出码可靠。退出码映射
(0 = 干净或仅 warning,2 = error 级违规,1 = 内部错误,134 = 配置读不了)
为 swiftlint 0.65.x 实测。
验证:在 /tmp 最小仓库(真钩子 + 真配置 + core.hooksPath)中不解沙箱跑
五个场景——旧钩子对只含 warning 的文件误报为 error 级违规(复现);新钩子
对同一文件放行并提示 warning;error 级违规正确拒绝且 HEAD 未动;配置读不了
时报「执行失败(退出码 134)」而非违规;复原后放行。
根 README 开发钩子一节同步这一区分。钩子只改第 2 关与头部注释。
2026-10-05 20:18:37 +08:00
Qiu Yuzhou
856d6b4272
refactor(domain): 按主题重组 Domain/ 源码目录
...
Domain/ 根目录原有 62 个平铺源文件,无法从目录读出主题划分。
按「目录即主题」重组为 11 个目录(Rules/Custom 为嵌套子目录):Catalog /
Subscription / Rules / Runtime / Activation / Settings / SystemProxy /
Plugin / Credentials / LegacyImport / Diagnostics。纯移动:类型名、模块名
与 import 均未改动,Domain/ 根下不再有散落文件。目录口径取自
GLOSSARY.md 的章节划分(配置与订阅、代理规则、代理控制与网络、设置、
凭据与诊断),而非新造分类。
配套改动:
- project.yml:wrapper 与 helper 两个 target 按文件引用的 15 条显式路径
随目录改名,并补注释固定这一约定——这 15 条指向不存在的文件时,
xcodegen generate 以 "missing source directory" 直接失败(实测,不静默)。
- SkeletonTests 新增 DomainLayoutTests:断言 Domain/ 根下无平铺 .swift、
树下只有 .swift。后者防的是与 App/ 同源的坑——Domain/ 整目录是 app 与
Core 的 source path,任何非源码文件都会被 XcodeGen 收进 Resources 阶段
并封进签名后的 bundle。
- README 工程结构说明同步;docs/design 与 docs/research 属历史文档不改。
验证:xcodegen generate 后 app 164 / Core 163 源文件数与整理前一致;Agent
恰好 9 个、Helper 恰好 6 个 Domain 文件(无缺失无多出);app 与 Core 各覆盖
全部 62 个。clean build 0 error;task test 1024 用例全通过(整理前 1022,
+2 为新增守卫);task format 未改写任何被移动文件(证明纯移动);task lint
与整理前同为 21 条内容型 warning;packaging-gate.sh ALL CHECKS PASSED。
布局守卫已做变异验证:临时投放松散 .swift 与非 .swift 文件时两个用例均
失败并点名违规文件,清理后复验为绿。
2026-10-05 20:13:35 +08:00
Qiu Yuzhou
fb428f12bc
refactor(app): 按分层重组 App/ 源码目录
...
App/ 根目录原有 73 个散落源文件,已无法从目录读出任何分组信息。
按「目录即分层」重组为 Composition / Application / Presentation / UI /
PlatformEffects / Resources 六个目录,UI 层再按子视图分目录(Workspace、
Home、Servers(含 Plugin)、Subscriptions、Rules、Settings、Diagnostics、
StatusMenu)。纯移动:类型名、模块名与 import 均未改动,App/ 根层不再有
散落文件。
配套改动:
- project.yml:Core 测试镜像的 excludes 由裸文件名改为 `**/` 递归形式。
XcodeGen 的 exclude 不跨 `/`,裸名只匹配 App 根层;MainApp.swift 下移后
旧写法会静默失效,把 @main 组合根编进测试镜像。info.path 与
entitlements.path 指向 App/Resources/;并排除 `**/*.md`——App/ 下任何
非源码文件都会被 XcodeGen 收进 Resources 阶段并封进签名后的 bundle。
- SkeletonTests 的架构守卫由「默认扫描全部 App/ + 7 个豁免文件 + 1 个豁免
前缀 + 4 个豁免目录」改为正面圈定 App/UI/,豁免登记全部删除;新增运行时
适配器放进 Application/ 即自动落在扫描范围外,无需再登记。
- README 工程结构说明同步;根 .gitignore 的生成物路径随 Resources/ 归位。
验证:clean build 0 error;task test 1022 用例全通过(含两个架构守卫);
task format 无改动(证明纯移动);task lint 与移动前同为 21 条内容型
warning;packaging-gate.sh ALL CHECKS PASSED,确认 plist/entitlements 归位
后签名与 entitlements 语义不变。
注意:迁移时须先删旧的生成物再 xcodegen generate,否则遗留的 App/Info.plist
会被当作普通资源扫进 Resources 阶段。
2026-10-05 19:56:18 +08:00
Qiu Yuzhou
0f2855f453
fix(ui): 关闭服务器表单密码框的系统密码自动填充
...
系统对 NSSecureTextField 默认提供钥匙串/密码 App 的自动填充入口,且不
取决于字段语义:实测底层字段 contentType 已是 nil,既有
.textContentType(nil) 不足以关掉它,AppKit 也没有公开开关。
改用字段级私有开关 _setPasswordAutofillEnabled:(responds(to:) 守卫,
方法消失时静默回退、不崩溃)。PasswordAutofillOptOut 以同帧背景探针
认领承载密码控件的文本框,只关密码列自己;明文/密文切换换成新实例后
重新认领。
新增 PasswordAutofillOptOutTests 固定认领范围与切换行为;全量单测
1022 通过,人工验证通过。取舍与后果记入 ADR-0028。
2026-10-05 19:23:55 +08:00
Qiu Yuzhou
a6ebb69bbf
feat(servers): add group sharing popover
2026-10-05 16:57:48 +08:00
Qiu Yuzhou
bd68e45ea4
feat(servers): present sharing in a popover
2026-10-05 16:41:18 +08:00
Qiu Yuzhou
13a548193b
ui: improve rules filter layout
2026-10-05 15:49:29 +08:00
Qiu Yuzhou
fd6fa65a8d
feat(share): rework server share as QR sheet
...
- Replace toolbar QR popover with a window sheet per sketch: top hint,
280pt white-backed QR, copy-image / save-image / copy-ss:// actions
and a Done button; all buttons share a 260pt min label width
- Freeze share payload and suggested file name at presentation time;
transient "copied" feedback on copy actions
- Add ImageClipboard seam (PNG normative type + TIFF in AppKit adapter)
and QrImageSaver seam (NSSavePanel PNG, sanitized suggested name)
- Register new typed failures in the presentation whitelist; extend
platform-effects architecture guard and seam tests
- Record spec in docs/design/server-share-sheet.md; GLOSSARY server
share now covers saved QR image files
2026-10-05 13:54:59 +08:00
Qiu Yuzhou
7c44cb4542
fix: retain focus in plugin option fields
...
Remove redundant tap-driven focus writes that redirect plugin input to the server name field.
2026-10-05 13:03:29 +08:00
Qiu Yuzhou
2b4f68f65d
fix(rules): fit custom rule sheet title and adaptive height
...
- Unify editor sheet title with other sheets (.title2)
- Cap preview area so the sheet hugs its content with no blank space
- Keep last preview while recomputing and animate residual size
changes to stop per-keystroke sheet jitter
2026-10-05 12:53:24 +08:00
Qiu Yuzhou
6f81b3fd70
Merge branch 'codex/custom-plugin' into develop
2026-10-05 12:05:42 +08:00
Qiu Yuzhou
86779b63ee
feat(plugins): add settings management UI
2026-10-05 12:03:52 +08:00
Qiu Yuzhou
ca45275810
Merge branch 'codex/custom-plugin' into develop
...
# Conflicts:
# ShadowsocksX-NG2/App/Localizable.xcstrings
2026-10-05 11:18:03 +08:00
Qiu Yuzhou
3d8d56b8e1
test(plugins): cover mapping commit and runtime convergence
2026-10-05 11:13:42 +08:00
Qiu Yuzhou
e74f8dfc01
refactor(plugins): derive server form facts from effective catalog
2026-10-05 00:46:43 +08:00
Qiu Yuzhou
128efcc0d6
feat(plugins): add user plugin catalog and runtime wiring
2026-10-05 00:28:16 +08:00
Qiu Yuzhou
3b3528d232
feat(subscription): show usage and provider dates
2026-10-05 00:10:13 +08:00
Qiu Yuzhou
87701fbacd
fix(ui): prevent sidebar toolbar flicker
...
Keep a hidden, zero-size detail toolbar item across destinations.
Crossing zero detail items triggers a native toolbar background fade,
including persistent sidebar controls.
2026-10-04 22:54:31 +08:00
Qiu Yuzhou
4623dc78aa
Merge commit 'a9a7aed' into develop
2026-10-04 22:26:20 +08:00
Qiu Yuzhou
76f8c9eaad
fix(ui): update import button label and adjust sidebar column width
2026-10-04 22:24:04 +08:00
Qiu Yuzhou
543ae14c53
fix(import): 工具栏按钮文案简化为「导入服务器」并更名 addMenu
...
按钮文案按显示空间收敛为「导入服务器」;构建方法更名 importButton,
与「菜单已收敛为单按钮」的实质一致。
2026-10-04 22:11:49 +08:00
Qiu Yuzhou
a9a7aedc0b
fix(servers): restore direct creation buttons
2026-10-04 22:03:18 +08:00
Qiu Yuzhou
7d5784bb3a
fix(import): 导入面板高度自适应内容
...
去掉 minHeight 钉死的初始高度,拖放区改固定高:初始面板收拢为内容
自然高度,结果区出现时面板随内容长高。
2026-10-04 21:59:06 +08:00
Qiu Yuzhou
83d67eba24
fix(ServerFormFields): update port validation to use closure syntax for clarity
2026-10-04 21:51:43 +08:00
Qiu Yuzhou
b54b50d887
refactor(import): 导入模型拆出独立文件
...
ImportSource/ImportRunOutcome 等统一导入 seam 类型与 LegacyImportAvailability
从 CatalogWorkflowModels.swift 集中到 CatalogWorkflowImportModels.swift,
使其回到 400 行基线以内;纯代码搬移,无行为变化。
2026-10-04 21:49:28 +08:00
Qiu Yuzhou
5968b1fd0b
feat(import): 统一服务器导入入口并支持 SIP-008 文件导入
...
新增统一导入面板(拖放多文件/剪贴板 ss:// 一键/旧版直接导入),来源按内容
嗅探分派(位图→二维码、JSON→SIP-008、其余→文本行),逐来源独立事务与
结果。深模块集中在 CatalogWorkflow.importServers 单一接缝,凭据统一经
journal,退役 ss:// 文本框、二维码预览、Legacy 专属 sheet 与首启主动弹窗。
SIP-008 导入语义见 ADR-0027(文档 ID 只作装配键,目录身份全新生成)。
2026-10-04 21:45:20 +08:00
Qiu Yuzhou
535d62a28a
fix(servers): support root creation and clearing selection
...
Add explicit current-group and root creation menus. Clear the management
tree selection on blank clicks or Escape while focused. Capture creation
parents, retain failed group drafts, and select/reveal created nodes.
Validation: 870 hostless tests (921 executions), 21 Python checks, unsigned
app build, format/lint/diff checks. Standards and spec reviews passed.
Native interaction and visual verification were not performed per request.
2026-10-04 21:36:51 +08:00
Qiu Yuzhou
b5dc43faf8
fix(ui): adjust sidebar column width for improved layout
2026-10-04 19:37:00 +08:00
Qiu Yuzhou
9c9a150ead
refactor(ui): 集中插件参数草稿移动规则
2026-10-04 19:12:14 +08:00
Qiu Yuzhou
85db6cec00
refactor(runtime): 集中收敛意图与恢复策略
2026-10-04 19:01:47 +08:00
Qiu Yuzhou
0164ff75ec
fix: defer plugin mode changes past view updates
...
macOS segmented Picker writes its binding within a SwiftUI update.
Defer the draft mutation to a main actor task to prevent synchronous
Published notifications during that update.
2026-10-04 18:46:25 +08:00
Qiu Yuzhou
1a22af7e62
refactor(forms): 集中服务器装载与失败门禁
2026-10-04 16:46:20 +08:00
Qiu Yuzhou
3d9ca630c5
feat(ui): 工具栏默认「图标和文本」标签风格
...
场景级 windowToolbarLabelStyle 默认 titleAndIcon(绑定 AppStorage,
用户右键工具栏改选可持久化);摘掉服务器区四条目与导入菜单的
iconOnly 条目级覆盖,规则表行内编辑按钮非工具栏保留不动。
2026-10-04 15:56:41 +08:00
Qiu Yuzhou
46185797fe
feat(ui): 边栏菜单改「导入」,添加订阅移回订阅页工具栏
...
- 边栏「添加」菜单改名「导入」,图标换 square.and.arrow.down,与
分享按钮 square.and.arrow.up 成对;菜单收敛为三项导入动作
- 「添加订阅」移回订阅分区自挂工具栏,表单由订阅页自持;窗口壳删
.addSubscription workspace sheet 与 destination 映射
- 空态文案同步:订阅页指向本页按钮,服务器页改称「导入」菜单并删
去从未存在的「创建分组」表述
2026-10-04 15:41:10 +08:00
Qiu Yuzhou
a00a93d5c0
docs: align domain docs with Chinese glossary
2026-10-04 15:19:54 +08:00
Qiu Yuzhou
7bb327ba1d
docs(domain): CONTEXT.md 改名 GLOSSARY.md 并对齐引用
...
domain-modeling skill 升级后单上下文约定文件名为 GLOSSARY.md:
git mv 保历史、内容零改动;AGENTS.md、docs/agents/domain.md 及
NG2 源码注释中的活引用随之对齐。docs/design、docs/research、ADR
中的旧名引用属历史记录,不改写。
2026-10-04 15:06:41 +08:00
Qiu Yuzhou
edaa492257
feat(ui): 服务器工具栏新增删除按钮
...
- 工具栏次序:新建服务器、新建分组、删除、分享;删除钮作用于当前
选中节点,确认弹窗与右键菜单共用 deleteTarget 流(档位见
deleteFacts)。
- 无选中、选择失效或选中项不可删除时禁用;资格判定新增政策缝
CatalogWorkflow.canDelete(节点存在且 manual),订阅节点结构只读
不经此口径,订阅删除仍留在订阅分区。
- CONTEXT.md Vocabulary 增补 Deletable node 术语;新增 canDelete
接口测试。
2026-10-04 14:56:48 +08:00
Qiu Yuzhou
fab2004aa5
feat(ui): 服务器分享上收为分区工具栏按钮
...
- 工具栏最右新增「分享」(square.and.arrow.up),行为复用原二维码弹窗
(220×220 QR + 内嵌复制 ss:// 链接,后台线程生成);详情区底部
「复制 ss:// 链接」「二维码…」两按钮删除
- disabled 单谓词 sharePayload()==nil:空选择/选中分组/凭据不可解析
一律不可用
- 弹窗锚在工具栏按钮;选中变化即收起,生成前清旧图防闪旧二维码
- ServerDetailView 失去 clipboard 参数;ServersView.errors 放宽
internal 供跨文件扩展呈现失败
- CONTEXT.md Vocabulary 新增 Server share 词条(_Avoid_: export,
export 保留给文件快照:分组 SIP-008 导出、诊断报告)
2026-10-04 14:08:56 +08:00
Qiu Yuzhou
b3fa498aaf
test(agent): LaunchAgent manifest 双份 artifact 一致性守卫
...
manifest 字典抽为 SMAppLaunchAgentService.manifestDictionary(programArguments:)
单一构造点,writeUserPlist 消费;新增测试解码 bundle 内打包 plist
(SMAppService 审批用)与代码重建字典,断言 Label/KeepAlive/
ThrottleInterval 逐键相等、ProgramArguments 形状等价(bundle 相对 vs
绝对路径是文档化的刻意差异)。
评审候选⑥ 6d:crash 重放协议的两份 artifact 从此有编译后守卫。
2026-10-04 13:08:09 +08:00
Qiu Yuzhou
4b2ddae99e
refactor(paths): App Support 目录命名权归 RuntimePaths
...
六个 GUI 配置文件位置(catalog/settings/listen-settings/custom-rules/
activation 与 silent-launch 遗留迁移源)自拼 applicationSupport 目录的
写法收敛为 RuntimePaths 的具名函数,各 store 的 defaultFileURL 改一行
委托。RuntimePaths 宪章从「跨进程运行时契约」扩为「App Support 目录
全部文件清单」——目录里有过哪些文件从此一处可答。
评审候选⑥ 6c:目录改名从动六个文件缩为动一处。
2026-10-04 13:02:31 +08:00
Qiu Yuzhou
c1e229c455
refactor(runtime): tmp 暂存命名单一主人归 AtomicFileWriter
...
AtomicFileWriter 暴露 temporaryURL(for:)(.\(name).tmp-<uuid> 约定唯一出处)
与 isResidueName(_:)(残留谓词):write 内部与 RuntimeFileStore 的两处
symlink 暂存(repointActiveLink/restoreLink)改吃 temporaryURL,
deleteRuntimeFiles 的残留识别改吃谓词。staging 泄漏由
deleteRuntimeFiles 兜底清理的隐性链条由此由构造保证。
评审候选⑥ 6b:命名约定一改、残留清理不再静默失效。
2026-10-04 13:00:26 +08:00
Qiu Yuzhou
945ea2b4db
refactor(runtime): 收据写者归一为 Agent wrapper
...
RuntimeFileStore.writeRuntimeReceipt 生产零调用(17 处调用全为测试夹具),
从生产 interface 删除;测试侧经 RuntimeReceiptFixture 的 extension 以同签名
承接,调用点零改动。收据格式知识仍由 RuntimeDeploymentReceipt 类型承载,
GUI 侧只保留 readRuntimeReceipt 读缝。
评审候选⑥ 6a:wrapper 是唯一收据写者,GUI 永不伪造收据。
2026-10-04 12:59:26 +08:00
Qiu Yuzhou
d9460c4d6d
fix(ui): 订阅 URL 预填失败经错误弹窗呈现真实原因
2026-10-04 12:37:56 +08:00
Qiu Yuzhou
bf23d03288
fix(ui): 订阅卡页脚改为现行快照表述
2026-10-04 12:37:51 +08:00