Commit Graph
696 Commits
Author SHA1 Message Date
Qiu Yuzhou f2e9cff69d feat(proxy): add ACL-backed global mode with local bypass
Global mode now deploys a minimal proxy_all ACL carrying only the fixed
local safety rules, so public targets default through Shadowsocks while
loopback/RFC1918/link-local/ULA/localhost/*.local/no-dot hosts stay
direct for SOCKS, HTTP, and LAN-sharing clients. System proxy exceptions
include that fixed scope; IPv6 system-exception limits are documented
with the ACL as the routing guarantee. Mode switches keep the
full-restart and rollback path.

Closes #62
2026-09-26 12:33:35 +08:00
Qiu Yuzhou 39e25477bb feat(proxy): add ACL-backed direct mode 2026-09-26 11:46:45 +08:00
Qiu Yuzhou 41379bb1cb fix(ng2): review fixes for agent/system-proxy switch split
- setAgentEnabled(true) 在意图已开启且未达健康态(off/启动失败/服务
  失败)时执行重收敛,成为失败态的显式重试入口;健康运行中不做无谓
  的注销重拉
- StatusMenuModel.Summary 增加 systemProxyStateLabel 短标签,去掉
  HomeView 对呈现文本的字符串剥离耦合
- 控制器头注释改为如实描述:launchd/契约动作序列在 ProxyRuntimePlan,
  系统代理门禁收敛决策留在控制器(issue #60)
- 新增重试路径测试
2026-09-26 00:55:52 +08:00
Qiu Yuzhou 398e8d84b6 feat(ng2): split agent and system proxy switches
实现 #60(ACL 1/8):agent 意图与系统代理意图拆为两个独立开关,
首次运行默认 agent 开、系统代理关;显式关闭 agent 持久化并在 GUI
重启后生效;关闭系统代理只恢复 NG2 持有的系统设置,本地 SOCKS/HTTP
继续监听;关闭 agent 先恢复系统设置再停止监听。无活动目标时 agent
以空服务器列表契约提供本地监听(isWellFormed 放行空 servers,上游
sslocal v1.25.0 接受);需要代理出口的模式在活动目标缺失或端点不健
康时系统代理保持待应用,条件恢复后随下次收敛自动应用。首页、状态菜
单与侧栏状态卡经同一代理控制快照展示/操作 agent 意图/运行状态与系
统代理意图/实际应用及 typed 错误。测试覆盖启动顺序、持久化、健康门
禁、ownership 冲突、无效活动目标与 GUI 重同步(含真实 sslocal 空监
听回环证据);替身测试不表述为真实系统写入验证。
2026-09-26 00:38:28 +08:00
Qiu Yuzhou 76b19ba935 feat(ng2): remove HTTP proxy toggle, inbound always on
The toggle only gated a convenience endpoint: system proxy never used
the HTTP port, which serves the terminal export line and LAN proxy.
Stored httpProxyEnabled:false is silently ignored, no migration.
Proxy-endpoint settings rows lose their subtitles; glossary term is
now the permanent "HTTP proxy inbound".
2026-09-25 03:57:06 +08:00
Qiu Yuzhou 2400c7c81d feat(ng2): window title follows active destination
- window.title tracks the destination via composition-root wiring
  into WorkspaceWindowOpeningAdapter.bindTitle; drop the static
  "ShadowsocksX-NG 2.0" title
- delete the 28pt shell destinationHeader; subscription and
  diagnostics actions move into the unified toolbar
- settings save/reset stay with the form as a top action row in
  SettingsView; form-level commit actions read wrong in a toolbar
2026-09-25 03:18:59 +08:00
Qiu Yuzhou be48a39f64 fix(ng2): restore workspace window chrome
ad74b23 的手动创建的 NSWindow 省略了 Window scene 提供的 chrome。
如果没有真实的 NSToolbar,NavigationSplitView bridge 会安装一半:
工具栏玻璃覆盖了部分标题,且没有安全区域插入(safe-area inset)。
默认的 titlebar 会将标题截断为 "ShadowsocksX-N…"。添加空的统一
toolbar 以及 fullSizeContentView 和透明 titlebar,以匹配 scene
的外观。
2026-09-25 01:38:29 +08:00
Qiu Yuzhou 1c5e4e5e23 feat(docs): add research on sslocal password handling via environment variables 2026-09-25 00:51:05 +08:00
Qiu Yuzhou 4fcfa1242c fix(ng2): disable SwiftLint identifier name warnings in SubscriptionRefreshStatus 2026-09-25 00:05:22 +08:00
Qiu Yuzhou b8f80492e7 style(editorconfig): add configuration for Swift files 2026-09-25 00:02:07 +08:00
Qiu Yuzhou ad74b23cb6 fix(ng2): AppKit-owned workspace window opens at launch
三重根因,逐一实测排除:①MenuBarExtra 菜单内容视图首次点开才挂载,
launch intent 挂在内容上等于从不执行(此前 legacy 导入自动开窗同样从未
生效),改挂到启动即挂载的标签视图;②SwiftUI openWindow 在 MenuBarExtra
上下文实测不创建场景窗口,且 LSUIElement 应用无场景启动呈现机制——主窗
口改为 AppKit 直控 NSWindow(NSHostingView 承载主 workspace),关闭仅
orderOut 复用,开窗不依赖场景时序;③resyncOnLaunch 的 launchd 往返
await 挡在开窗前,改为先开窗后 resync。装配抽成 AppComposition(init
体量回到 lint 基线)。真机验证:启动即出现主窗口,进程前台形态,
SwiftLint/全量测试通过。
2026-09-24 23:51:48 +08:00
Qiu Yuzhou a0137651fa fix(ng2): present workspace window on every launch
登录启动判定没有可靠的系统 API,uptime 启发式与 launch-at-login 语义
不严格对应(logout/login 不重启时检测不到,启用登录项后开机超窗口期的
手动启动会被误判静默)。按产品决定简化:不再区分启动来源,每次启动都
开主窗口;混合形态(开窗 .regular / 关最后一个窗 .accessory)不变。
2026-09-24 23:07:12 +08:00
Qiu Yuzhou cb4ad5a87d feat(ng2): hybrid app form with foreground workspace window 2026-09-24 22:53:11 +08:00
Qiu Yuzhou ab6acf8912 refactor(ng2): remove UDP relay preference 2026-09-24 22:00:58 +08:00
Qiu Yuzhou 620c929450 docs(research): survey proxy rule sources 2026-09-24 21:41:33 +08:00
Qiu Yuzhou fb6be460b8 docs(research): assess sslocal ACL as PAC alternative
Document routing, reload, DNS, UDP, and compatibility boundaries
before considering an NG2 runtime migration.
2026-09-24 21:40:51 +08:00
Qiu Yuzhou 3842bdc97c fix(ng2): remove obsolete settings menu item 2026-09-24 21:03:28 +08:00
Qiu Yuzhou f7edceee30 feat(ng2): restyle diagnostics and move export to header (#58)
摘要卡(代理状态/活动目标,来自 DiagnosticsWorkflow.summary 安全投影)+
日志卡(来源 segmented + 复制 + 等宽日志区与空态)+ 脱敏说明行;状态摘要
侧栏删除;导出诊断迁分区头(DiagnosticReportExportAction 入口不变,「诊断
已导出」alert 移至壳层);分区包装视图归位 WorkspaceDestinations.swift。

地图 #52 · 票 #58;五分区 hermetic 冒烟验收通过,task build + test 全绿。
2026-09-24 19:37:16 +08:00
Qiu Yuzhou 1d34c0b3b3 feat(ng2): regroup settings into card sections with header actions (#57)
常规/代理端点/高级三张分组卡,行式「主文案 + 次说明 + 行尾控件」;监听范围
改 segmented + 「不会自动换端口」徽标,LAN 警告与防火墙指引保留;端口行
issues/占用/建议空闲端口不变;保存/恢复默认迁入分区头(确认弹窗仍由本视图
alert 呈现);保存失败横幅置代理端点卡顶,dirty/占用提示置高级卡尾。

地图 #52 · 票 #57;task build + test 全绿,hermetic 冒烟通过。
2026-09-24 19:35:40 +08:00
Qiu Yuzhou f556c5fdb6 feat(ng2): rework subscriptions into cards with header actions (#56)
每订阅一卡片:图标 + 名称 + 地址隐藏副题 + 状态徽标三态(已同步/刷新失败/
尚未刷新)+ 更新/重试 + 「…」菜单(编辑 URL/删除);三列元数据(固定分组/
服务器/上次成功刷新)+ 失败详情行 + 脱敏说明行;失败卡警告色描边。底部操作
栏移除,添加订阅/更新全部迁入分区头动作槽位(sheet 与错误呈现由壳持有)。

地图 #52 · 票 #56;task build + test 全绿。
2026-09-24 19:34:03 +08:00
Qiu Yuzhou 139944dba2 feat(ng2): restyle server detail and catalog rows (#55)
ServersView 扁平双栏承接目录与详情;ServerDetailView 重排为详情头(图标 +
名称 + 来源说明,活动目标由父视图传入)+ 两列 Grid 表单 + 底部取消/保存,
插件区拆 ServerPluginSection、分享/二维码拆 +Share 扩展;SidebarRow 分组行
加「手动/订阅分组 · N 项」副题;GroupDetailView 加同款详情头。行为语义不变。

地图 #52 · 票 #55;task build + test 全绿。
2026-09-24 19:32:24 +08:00
Qiu Yuzhou 75de3fbac9 feat(ng2): add home view with mode, target tree and quick actions (#54)
代理模式卡(PAC/全局 segmented + 说明 + 当前徽标,走 snapshot 可用模式)、
当前服务器卡(只含有服务器的分组,双击激活,活动目标勾选与无效警示)、
快速操作卡(更新全部订阅、复制终端 HTTP 导出行);Legacy 首启询问保留。

地图 #52 · 票 #54;task build + test 全绿,hermetic 冒烟通过。
2026-09-24 19:30:49 +08:00
Qiu Yuzhou 678bea6d3b feat(ng2): rebuild main window shell with sidebar navigation (#53)
NavigationSplitView 侧栏:五项导航与 WorkspaceRoute 双向绑定 + 服务器/订阅
行尾数量角标;底部常驻代理状态卡与状态菜单同口径(ProxyControlWorkflow
snapshot 经 StatusMenuModel.summary);分区大标题外壳与动作槽位。
ServersView 内层 NavigationSplitView 换扁平双栏(#55 再重排)。

地图 #52 · 票 #53;task build + test 全绿,hermetic 冒烟通过。
2026-09-24 19:29:08 +08:00
Qiu Yuzhou a70165f5fb feat(ng2): isolate clipboard and diagnostic export effects (#51) 2026-09-24 13:32:15 +08:00
Qiu Yuzhou 0a1aa9a725 feat(ng2): add workspace route module 2026-09-24 09:45:08 +08:00
Qiu Yuzhou 63dac7a01b refactor(ng2): deepen CatalogWorkflow into application module
Issue #49: introduce CatalogWorkflowDependencies as the composition-only
adapter bundle and stop exposing implementation collaborators as workflow
properties. MainApp now assembles all production adapters explicitly (the
workflow creates no production defaults); tests assemble hermetic fakes via
a shared fixture in CatalogFixtures. Subscription tests swap fetch behavior
on the injected fake instead of mutating the workflow. An architecture
deletion check fails when UI source files reference implementation
collaborators or raw catalog/credential storage types, and a hermetic
assembly test proves the workflow runs entirely on injected fakes.
2026-09-24 01:44:01 +08:00
Qiu Yuzhou c76ba93221 feat(ng2): finalize settings workflow persistence boundary 2026-09-24 00:20:42 +08:00
Qiu Yuzhou 7951d5aa65 feat(ng2): add proxy control workflow as unified UI seam
Issue #47: application-layer ProxyControlWorkflow wrapping the existing
ProxyRuntimeController with a whole-published ProxyControlSnapshot (typed
runtime facts, current mode, available modes, active-target facts with
safe path summary, skipped-invalid-server count, HTTP export capability)
and typed async commands (enable/disable/mode) that republish the full
snapshot on completion. Production runtime adapter delegates to the
controller without duplicating generation, health gating or system-proxy
ownership; catalog target facts arrive through a narrow seam
(CatalogTreeSnapshot.pathSummary) that never exposes the tree.

Status menu now reads runtime state and issues proxy commands only via
the workflow snapshot; catalog tree, activation and subscription actions
stay on CatalogWorkflow. MainApp wires the production adapters once as
composition root. No change to persistence order, failure taxonomy,
mode-availability policy (#46), catalog commit sync (#40), settings
(#44) or diagnostics (#43) seams.

Tests: fake-adapter snapshot/command/boundary contract tests plus
real-controller integration matrix (enable failures, approval, system
proxy, mode persistence failure and no-op) and an integration-level
status-menu model test proving the menu derives everything from the
workflow. Unavailable-mode no-op and runtime-stop-failure items of the
spec matrix are vacuous after ADR-0007 (no constructible unavailable
ProxyMode; controller stop path has no distinct failure category).
2026-09-23 20:54:08 +08:00
Qiu Yuzhou dc7f3d5b61 test(ng2): clean up Keychain records after tests 2026-09-23 19:32:44 +08:00
Qiu Yuzhou 9fc6446237 refactor(ng2): remove manual and external PAC 2026-09-23 18:47:15 +08:00
Qiu Yuzhou e65d7112f1 refactor(ng2): unify committed catalog source 2026-09-23 16:47:13 +08:00
Qiu Yuzhou 6c98930999 refactor(ng2): unify runtime facts and proxy mode availability 2026-09-23 11:48:13 +08:00
Qiu Yuzhou fe4c3e166e refactor(ng2): centralize typed failure presentation 2026-09-23 10:51:26 +08:00
Qiu Yuzhou 9d0001cfdc refactor(ng2): move CredentialWriteJournal to Domain
- rollback() returns CredentialRollbackOutcome and updateServer wraps
  commit failures in CommitError carrying it, so tests assert through
  the seam instead of poking credential store state
- hoist pluginNotManaged into form validation: form rejections stay
  bare ServerFormError and never touch credentials
2026-09-23 08:46:40 +08:00
Qiu Yuzhou 713c627deb refactor(ng2): deepen settings draft projection for new settings UI (#44)
加深 SettingsWorkflow,让平坦 UI 形状草稿成为编辑态唯一 source of truth,把
字段问题、端口占用事实、保存门禁、脏态、PAC 失效确认与重置确认收进 seam,
为重写设置 UI 提供稳定访问面。

- UI-facing interface 只含 UI 形状投影与 typed command:平坦 SettingsDraft
  (监听范围 = 布尔开关 + 公布地址文本,端口/超时为整数,不含持久化的当前
  模式)、按字段归位的 SettingsFieldIssue(端口问题用端口标识变体,每条载带
  点名文案)、按 SettingsPortID 索引的端口 field state(草稿值/类型化占用
  事实/字段问题/运行中端口例外/可否建议空闲端口)、保存门禁·脏态·提交中·
  失败点名文案投影、统一确认事实 SettingsConfirmation;离散动作走具名 typed
  command(save、reset、suggestFreePort(for:)、confirmPACNotice、
  cancelPACNotice、confirmReset、cancelReset、reloadFromCommitted)。
  module 不依赖 SwiftUI。
- 写入侧收窄为窄 seam SettingsCommitting(已提交快照、代理是否在跑、两个
  提交入口),ProxyRuntimeController 薄扩展即生产实现,测试注入 fake。
- 平坦草稿与 ProxySettings 互转集中在 SettingsDraftAdapter,校验错误归位与
  端口标识映射同属字段清单并收在同文件;Domain 快照类型只出现在后端缝与
  adapter。Domain 点名校验、端口互异/建议算法、PAC 失效判定与占用探测缝
  原样复用,行为不改写。
- 设置视图只绑投影与 typed command:删除 ListenScope 枚举拆装、探测层占用
  翻译、门禁推导与确认文案。重置确认摘要来自 seam 的范围裁定,并补齐重置
  事务的实际范围(全部偏好回出厂值、运行中代理停止);端口互异问题归位到
  冲突双方端口;隐藏的地址残留不再误报未保存修改。

用户可见变化:校验红字改为按字段归位显示;重置确认摘要由 seam 裁定。其余
行为与现状一致。

测试:新增 SettingsWorkflowInterfaceTests(30 项,fake 写入缝 + fake 探测)
覆盖校验归位、端口 field state、运行中端口例外、建议端口、保存门禁、脏态、
PAC/重置确认裁决、提交中与失败点名、占用探测代际;SettingsWorkflowTests
收敛为真实 ProxyRuntimeController 提交路径集成(5 项)。全量 427 项通过。
2026-09-22 22:28:39 +08:00
Qiu Yuzhou cdf1c8ab8f refactor(ng2): deepen catalog policy into workflow seam
New UI must bind projections and send typed commands only.
Views were re-deriving delete confirm, move destinations,
activation eligibility, and drag payload from domain state.

Empty manual-group delete is no longer instant — always one confirmation.
2026-09-22 20:41:18 +08:00
Qiu Yuzhou fd9be86149 refactor(ng2): add diagnostics workflow module as single UI-facing seam
诊断区收敛为 DiagnosticsWorkflow 深 module(Candidate 03,issue #43):事实
采样、轮询代际、raw 日志投影、报告准备与导出完成登记集中一个 seam,视图只
负责生命周期触发、呈现、剪贴板、保存面板与报告文件写入。侧栏与详情共享同
一份安全摘要;收集只读,不触碰目录、凭据、runtime 与系统代理设置。

目录不再把原始 ConfigurationCatalog 写入诊断快照:CatalogWorkflow 只输出
domain-neutral 聚合事实(计数 + 已知无效数),报告 builder 只接受已裁剪的
report facts。事件导出改为显式白名单派生(diagnosticReportLine):自由
detail、主机公布地址与 runtime 错误原文一律清洗,数量/端口/领域点名原因
保留;新增事件漏 case 无法编译。raw GUI 事件行与 wrapper agent.log 尾部仅
经显式查看/复制提供,永不进入报告(ADR-0006)。导出完成事件只在用户选择的
文件实际写入成功后登记。

RuntimeEventStore 事件改为携带封闭枚举原值,渲染发生在呈现边缘(白名单清
洗只可能作用于原值)。测试:新增 workflow interface 覆盖投毒导出、白名单、
raw/报告分离、缺失标注、只读、代际覆盖与取消;ADR-0006 与 CONTEXT.md 术语
同步入库。
2026-09-22 19:22:31 +08:00
Qiu Yuzhou 3df1624d91 refactor(ng2): add settings workflow module as single UI-facing seam
建立设置工作流深 module(App/SettingsWorkflow/),把设置编辑的编排从视图
收拢到一个 seam,镜像 #41 的目录工作流模式:

- UI-facing interface:可编辑 draft 投影(binding 直连)、占用/校验/门禁/
  保存中/待确认 PAC 失效提示/错误等只读投影,与 suggestPort、save、
  confirmPACNotice、cancelPACNotice、reset、reloadFromCommitted 等 typed
  command;登录启动项是独立偏好域(ADR-0005),视图直连其控制器,不经本
  module。
- implementation(灰置):端口占用探测的 Task.detached 编排(代际去竞态)、
  保存门禁(validationErrors+占用)、「当前运行端口」例外、PAC 失效确认
  流、重置事务与 ProxySettingsStoreError 文案映射。
- isOn 判定从 StatusMenuModel 迁至 ProxyRuntimeController.ProxyState 扩展,
  菜单摘要与设置工作流共用同一事实来源;设置视图不再持有
  ProxyRuntimeController 与探测缝,组合根在 MainApp 接线一次,设置窗口
  scene 的显式触达路径不变。

测试:设置编辑 workflow 不经 SwiftUI 即可全测——占用反应与门禁阻塞、
运行端口例外放行、PAC 失效确认/取消、校验阻塞、提交失败保留旧值并点名、
重置回出厂、建议端口只写草稿(8 项;全量 376 项通过)。

Out of scope:设置视觉重设计、ProxyRuntimeController 拆分、独立编译
target。
2026-09-22 17:36:40 +08:00
Qiu Yuzhou e242bbf426 feat(ng2): persist proxy mode selection and drop enabled-modes
模式选择(菜单唯一入口)随设置快照持久化,GUI 重启恢复所选模式;持久化
失败保留旧模式并点名呈现,不静默切换。外部 PAC 模式下保存设置时,模式从
新快照解析后与 URL 一起作为一个逻辑变更提交(清空 URL 回落 PAC 并同步
持久化),校验失败先于写入。重置偏好把模式回 PAC。

enabledModes 自 ADR-0002 停止偏好迁移后无任何写入方,且 2.0 无编辑 UI,
按死状态删除:内置三模式恒可选,外部 PAC 仍以已配置的有效 URL 为门槛
(ADR-0004)。

测试:模式持久化与重启恢复、持久化失败保留旧值、外部 PAC 一个逻辑变更
回落;makeController 的 proxyMode 参数改为可选以便测试走恢复路径。
2026-09-22 17:36:24 +08:00
Qiu Yuzhou 376b648ac4 refactor(login): independent opt-in login item
Drop the UserDefaults intent mirror and read the toggle state only from the
system login-item registration status (approval-pending counts as enabled);
default to off until the user enables it, and stop resetting it with proxy
preferences (ADR-0005).
2026-09-22 17:32:46 +08:00
Qiu Yuzhou a7b1b1629a refactor(settings): remove proxy mode selector
Keep mode switching in the status menu as the common control.
2026-09-22 16:31:14 +08:00
Qiu Yuzhou 3dc6043dc6 refactor(ng2): remove system-level shortcuts
Keep proxy controls explicit and leave existing shortcut preferences untouched.
2026-09-22 16:16:58 +08:00
Qiu Yuzhou 46ebe1d835 feat(ng2): simplify Legacy import and isolate default ports (#42) 2026-09-22 14:26:58 +08:00
Qiu Yuzhou 2fe401cd50 feat(ng2): add catalog workflow module as single UI-facing seam (#41)
建立目录工作流深 module(App/CatalogWorkflow/),收窄主窗口与配置 UI 对
配置目录、凭据存储、订阅快照、Legacy 导入与运行时收敛的访问:

- UI-facing interface:非敏感树/编辑面/订阅 projection、opaque NodeID 查询、
  typed command(ServerEditDraft 等)、typed error 与 structured outcome
  (BatchImportOutcome 逐行点名、RemovalOutcome selection invalidation);
  秘密值只在显式编辑/分享/订阅 URL 命令中出现。
- 服务器编辑:配置与凭据作为一个逻辑变更,CredentialWriteJournal 保证目录
  持久化失败时旧配置与旧凭据都保持有效(story 12/13,含测试)。
- 提交与收敛分离:目录提交成功与 runtimeSync 收敛阶段是独立观察面,运行时
  失败不回滚已提交目录(story 38/39,含测试)。
- 订阅:创建/刷新/换址/删除沿用原子快照、last-good 保留与凭据回滚;卡片
  projection 只含 host,结构化刷新状态由呈现层本地化。
- Legacy 导入端到端编排:不驱动运行时收敛、不自动重复、显式再导入创建独立
  分组;handoff 仍经组合根注入的独立边界。
- Deletion test:删除 CatalogViewModel/Types/+Subscriptions 旧 facade,全部
  视图与状态菜单迁移到新 seam;选择、pane、sheet、alert 状态收归 UI 持有
  (ErrorAlertPresenter)。导入失败行以行号点名,不再回显 ss:// 行内容。

测试经 module interface 观察(395 项全部通过):持久化失败凭据回滚、提交/
收敛阶段分离、收敛失败不回滚、导入不触发运行时等新增场景;既有 Domain、
协调器与运行时测试保持不变。

Out of scope(spec #41):设置编辑、ProxyRuntimeController、Legacy handoff、
新视觉设计、独立编译 target。
2026-09-22 11:39:07 +08:00
Qiu Yuzhou 374f0da4d7 feat(ng2): decouple catalog commit from proxy runtime sync (#40)
Add an application-layer CatalogCommitCoordinator as the single commit
entry for normal configuration changes: copy -> mutate -> atomic persist
-> publish committed state -> async runtime convergence toward the just
committed in-memory snapshot. Commits complete at persist; convergence
reports structured outcomes (converged / revalidated / failed /
clearedAndStopped) and never blocks or rolls back the commit. Each commit
bumps a generation; superseded syncs end before starting or have their
late results discarded, so only the latest snapshot can win. No automatic
retry.

CatalogRuntimeSyncing is the one new replacement seam: the production
ProxyRuntimeSyncAdapter drives the existing ProxyRuntimeController via a
snapshot-based catalogDidCommit; tests use a deterministic fake. When no
active target exists a commit no longer touches the runtime at all.

CatalogViewModel stays as a compatibility facade with unchanged published
state; the optional postCommit callback and the per-scene callback wiring
in MainApp are removed - the composition root wires the coordinator,
adapter and the (independent) Legacy import boundary exactly once.
2026-09-22 09:48:38 +08:00
Qiu Yuzhou ea801d5f38 feat(catalog): remove node enable state
Migrate legacy enabled fields to v3 without preserving their semantics.
Keep recoverable invalid imports visible and filter them during activation.
2026-09-22 08:40:13 +08:00
Qiu Yuzhou fc571f2862 refactor(ng2): remove deprecated LaunchAgent plist file 2026-09-21 22:17:11 +08:00
Qiu Yuzhou 00fcd61a99 refactor(ng2): change bundle id to ShadowsocksX-NG2
Distinct id from Legacy (com.qiuyuzhou.ShadowsocksX-NG) lets NG2 own
~/Library/Application Support/ShadowsocksX-NG2/ directly; the v2/
subdir prefix is removed from all runtime paths.

- app/agent/tests targets + LaunchAgent plist renamed accordingly
- keychain service, queue labels, and Vendor signIdentifiers follow
  the new bundle id; embedded helpers re-sign at build time
- Legacy handoff/import constants keep pointing at the old id

Migration: dev data under ShadowsocksX-NG/v2/ is not carried over
(fresh catalog/activation); old LaunchAgent registration and old
keychain entries must be cleaned up manually.
2026-09-21 20:33:37 +08:00
Qiu Yuzhou c03db6c04a fix(ng2): allow handoff without Legacy jobs
Enable confirmation when no Legacy launchd actions remain, since
handoff still performs proxy cleanup, port checks, and 2.0 startup.

Refs #37
2026-09-21 15:35:38 +08:00
Qiu Yuzhou f16feb5f0c fix(ng2): open settings from status menu
Use an explicit settings window because the menu bar app has no application menu.

Refs #33
2026-09-21 15:17:21 +08:00