22 Commits
Author SHA1 Message Date
Qiu Yuzhou f3ba330cf4 refactor: centralize subscription automatic update transitions 2026-10-25 22:06:39 +08:00
Qiu Yuzhou 34caebf322 feat: add GUI-scoped subscription automatic updates (#1516)
* feat: add GUI-scoped subscription automatic updates

* fix: drain newly due subscription updates during a batch

* style: use segmented subscription update pickers
2026-10-25 20:21:06 +08:00
Qiu Yuzhou b6b9349d64 style: resolve SwiftLint violations 2026-10-23 01:10:40 +08:00
Qiu Yuzhou f9e95474e5 refactor: adopt age configuration storage
Replace the custom encrypted container with AgeSwift 0.1.0 so standard
age tools can inspect sensitive configuration independently of the app.

Use independent Keychain X25519 identities for catalog.age and
proxy-listening.age. Preserve atomic commits and confirmed recovery;
reject historical NG2 formats without migration or cleanup.
2026-10-21 14:31:32 +08:00
Qiu YuzhouandDeepSeek Harness 5872015ca0 test: drop dead scaffolding assertions
Six sites re-asserted the predicate waitUntilRuntimeSettles already checks,
with no suspension point in between, so they could never fail; their intent
messages are folded into comments where one was not already stated.

Two commit-failure cases asserted the fake's bookkeeping (updateCalls stays
empty) which the fake guarantees by throwing before recording; the outcome
and committed-snapshot assertions already prove the real behavior.

Also drop a no-op loop that mutated a discarded struct copy, a duplicated
isWellFormed line, two WorkspaceRoute cases subsumed by the constructor and
the publish-count case, a duplicated presentation-message assertion, and the
round-trip halves of two payload-shape cases already covered case-by-case.

Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
2026-10-21 02:23:28 +08:00
Qiu YuzhouandDeepSeek Harness 78bafea90f test: drop assertions that restate the language or a fixture
Each removed assertion holds by construction and can never fail:

- jsonData() compared with itself cannot detect cross-run byte stability;
  bindAddress and mode are literal-returning computed properties
- RuleAction/RuleSourceKind allCases assertions pin synthesized enum order
  (neither allCases list is used in production); the persisted action tokens
  stay pinned by the kept rawValue assertions and source-kind tokens by
  fixture decoding through RuleSnapshotStore
- memberwise-constructor echo in RuleSourceIdentity, fixture-guaranteed
  name == id rows, a share draft field pair built from one string, and a
  local struct compared to its own assignment
- the synthesized-Codable round trip through literal JSONEncoder/JSONDecoder

The duplicate-import assertion becomes a real check: Set of node ids instead
of a count that restated roots.count, which is what its comment claims.

Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
2026-10-21 02:04:21 +08:00
Qiu YuzhouandDeepSeek Harness 26ecc5a11e test: drop assertions that cannot fail and the doubles they exercised
Three tests claimed coverage they could not deliver:

- subscription URL credential cleanup asserted a lookup derived from the
  already-empty subscription list, so it held even on a leak; production has
  no separate URL credential store (SubscriptionRecord.url is a plain field)
- the runtime log event sweep planted no secret values, so its secret half
  could never fail; keep the live JSON-dump check and rename the test to match
- clipboard and QR saver tests exercised only in-memory doubles that live in
  production source and have no other caller; delete the six tests and the
  three doubles (AppKit adapters stay untested, as before)

Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
2026-10-21 00:45:44 +08:00
Qiu Yuzhou 003e40d809 refactor(ng2): encrypt proxy listening configuration 2026-10-19 14:31:18 +08:00
Qiu Yuzhou 0f3454602f refactor: separate proxy preferences from listening configuration 2026-10-19 12:10:48 +08:00
Qiu Yuzhou b1b00d78b1 test(ng2): isolate import workflow key storage 2026-10-18 22:53:16 +08:00
Qiu Yuzhou 507917ab67 refactor(ng2): store secrets directly in server library records 2026-10-18 17:58:30 +08:00
Qiu Yuzhou d8a11f7b6b feat: encrypt persistent server library 2026-10-18 07:57:10 +08:00
Qiu Yuzhou 82672d6e10 refactor(ui): remove top-level subscriptions page 2026-10-15 00:47:19 +08:00
Qiu Yuzhou 2f0c0d7676 feat: separate local and LAN proxy listeners 2026-10-13 03:58:03 +08:00
Qiu Yuzhou c49d605a5b chore(ng2): remove fork issue references from comments 2026-10-13 00:38:06 +08:00
Qiu Yuzhou dc64349702 feat(plugins): bundle Cloak v2 client 2026-10-12 12:38:32 +08:00
Qiu Yuzhou 84c292eb7f feat(plugin): support aliases and local startup arguments 2026-10-11 21:04:59 +08:00
Qiu Yuzhou e50f671975 feat(servers): add ordered favorites 2026-10-09 23:20:11 +08:00
Qiu Yuzhou 801348c5b6 refactor(servers): use three-column table navigation 2026-10-09 19:07:44 +08:00
Qiu Yuzhou ac476d3764 fix(servers): number existing duplicate names 2026-10-06 13:42:15 +08:00
Qiu Yuzhou 0dc8775641 feat(servers): duplicate servers and groups 2026-10-06 13:36:12 +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