wangjia
|
8937044f55
|
fix(client/macos): 最小化托盘后点 Dock 图标唤回窗口(1.0.48+49)
windowManager.hide() 走 orderOut: 后主窗口不可见,点 Dock 图标系统只发
applicationShouldHandleReopen(hasVisibleWindows=false),AppDelegate 未接管 →
点了没反应。AppDelegate 实现该回调,无可见窗口时 makeKeyAndOrderFront +
activate 唤回 mainFlutterWindow。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-02 10:50:40 +08:00 |
|
wangjia
|
6bcdbbe752
|
revert(macos): killswitch 回退 L0(低优先级暂缓)
用户判定 killswitch 优先级低、暂不做:
- includeAllNetworks 实测堵死整机网络;退化方案 enforceRoutes+on-demand
几乎等于没做(核心 fail-closed 没拿到),on-demand 还对免费版配额造成
重连 churn —— 性价比低
- VpnChannel.swift 恢复到 L0 stub(setKillSwitch→result(nil));
PacketTunnelProvider.swift 已是原样
- docs §6.5 改为「尝试与暂缓」记录,状态表 macOS 回 L0
- local_test.sh 的 ks-* 漏测子命令保留(将来重拾 killswitch 时可用)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-01 06:38:47 +08:00 |
|
wangjia
|
a32d87c9c0
|
fix(macos): killswitch 撤掉 includeAllNetworks(堵死整机网络) — 改 enforceRoutes+on-demand
实测 includeAllNetworks=true 把所有流量(含 sing-box 连服务器握手、app 调控制面
请求)在隧道建起前就塞进隧道 → 握手出不去 → 连接失败 + on-demand 死循环 + 整机
断网(连「我的」页账户信息都拉不到、显示 —)。
改为不会误伤握手/控制面的组合:
- configureKillSwitch:includeAllNetworks 恒 false;保留 enforceRoutes(连接期防漏)
+ excludeLocalNetworks + NEOnDemandRule 常开(兜重连)
- 撤回 start() 的 killSwitch option 及扩展侧 includeAllNetworks 透传(回 false)
- 诚实标注:当前 L1→L2 之间,未到 includeAllNetworks-L3;要拿「扛进程被杀」须先
在扩展内放行服务器/控制面连接,留待真机验证
docs/killswitch-design.html: §6.5 加踩坑修正、状态表 macOS 改「L1→L2 之间」
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-01 06:09:04 +08:00 |
|
wangjia
|
680f1af205
|
feat(macos): KillSwitch L0→L3 — NE includeAllNetworks+enforceRoutes+on-demand
macOS 走原生 NE,strict_route 不生效。补齐断网保护到天花板 L3:
VpnChannel.swift
- 缓存 killSwitchEnabled(默认 true,与 Dart AppSettings.killSwitch 对齐)
- setKillSwitch 落地:存标志,manager 已装配则即时重写 NE 配置+保存
- configureKillSwitch:includeAllNetworks+enforceRoutes(L2 OS 强制、扛崩溃)
+ NEOnDemandRule 常开(L3)+ excludeLocalNetworks 放行 LAN
(enforceRoutes/excludeLocalNetworks 为 macOS 11+ API,#available 守卫)
- stop() gotcha:on-demand 常开时先关 isOnDemandEnabled+save 再 stop,
否则手动断开被 OS 立刻拉回
- start() options 带 killSwitch 传扩展
PacketTunnelProvider.swift
- startTunnel 读 killSwitch 选项(OS on-demand 自启时 nil→默认 true)
- libbox 回调 includeAllNetworks() 返回该值,与 NE 层对齐
docs/killswitch-design.html: 新增 §6.5 实现方案,状态表 macOS L0→L3
验证:xcodebuild CODE_SIGNING_ALLOWED=NO 两 target SwiftCompile 通过;
端到端 fail-closed/on-demand 需真机手测(NE 难单测)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 23:54:32 +08:00 |
|
wangjia
|
7add0259b4
|
chore(client/macos): 清理延迟排查的诊断打点 + debug 注入(最终干净版)
延迟显示已修通。移除排查期的临时诊断:扩展侧 Log 客户端/klog 捕获、log.level=debug 注入、
diag 字段/setDiag;主 app StatsClient 每5帧的 dl/ul/urltest 打印;Dart 侧 [Stats]/[Ping] 打点。
保留全部修复:clash_api 注入取 urltest、sendProviderMessage 统计通道、/proxies history+active
缓存、共享广播流、_onStats 回退 effectiveNode、连接态跳过直连实测。
CURRENT_PROJECT_VERSION 52→53。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 18:03:30 +08:00 |
|
wangjia
|
e3fb5239a6
|
diag(client/macos): 抓 sing-box urltest 内核日志,定位探测为何失败
确认 urltest 为空是内核探测 100% 失败(传输/读取链路均正常)。本次注入 log.level=debug,
StatsCollector 新增 Log 命令客户端,抓取内核日志里 urltest/gstatic 相关行(失败原因:
DNS/连接/超时),塞进 stats 的 klog 字段经主 app 可读日志透出 —— 直接看到内核报错。
CURRENT_PROJECT_VERSION 51→52。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 14:58:07 +08:00 |
|
wangjia
|
03dbbf8db9
|
fix(client/macos): urltest 延迟改走注入的 clash API(对齐 Windows),内核侧打点
诊断:即便专开 Group client,扩展回的 urltest 数组恒空——根因是服务端下发配置无
experimental.clash_api,sing-box 不暴露出站组/urltest 历史,libbox Group 命令拿不到。
修复(与 Windows 完全同法):扩展内向配置注入 clash_api(127.0.0.1 本地监听)+ cache_file,
StatsCollector 经本地 HTTP 查 /proxies 找 URLTest 组、/group/<name>/delay 取真实延迟。
速率仍走 libbox Status。新增内核侧 NSLog 打点 kernel delay(<group>)=<tag:ms>,并把该值
塞进 stats 的 diag 字段经主 app 可读日志透出——一眼分清「内核有没有算出延迟」vs「外面没拿到」。
扩展代码变更 → CURRENT_PROJECT_VERSION 46→47。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 12:54:40 +08:00 |
|
wangjia
|
a43f8a93de
|
diag(client/macos): StatsClient 每5帧打印收到的 urltest 延迟,排查连接页延迟为 —
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 12:25:33 +08:00 |
|
wangjia
|
6c19b1bd92
|
fix(client/macos): 实时统计改走 sendProviderMessage,根治容器路径死局
上一版试图让 root 扩展把 command.sock 建到用户容器,反而让 startTunnel 抛错、隧道连不上
(root 在用户 home 建 socket、属主/路径与无 root 的 app 对不上,且方向本就错)。回退该路子。
正解:用 NetworkExtension 官方跨进程通道,绕开「root 扩展容器 vs 用户 app 容器」死局——
- 扩展内新增 StatsCollector:连本进程自己的 command.sock(同容器、root 可达),订阅
status/group 缓存最新上下行 + urltest;handleAppMessage 收到 "stats" 即回最新 JSON。
- 主 app StatsClient 改为每秒 NETunnelProviderSession.sendProviderMessage("stats") 拉取、
解析后推 onStats(不再直连 socket);VpnChannel 三处启动点改传 session。
- 扩展代码变更 → CURRENT_PROJECT_VERSION 44→45,让 sysextd 重装。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 12:05:43 +08:00 |
|
wangjia
|
4f727beb60
|
fix(client/macos): 启动即激活 sysext + command.sock 打点
旧 sysext(on-demand/常驻)会在 app 启动前自动重连,app 走 primeExistingConnection
而非 start() → 永不提交 OSSystemExtensionRequest → bundle 内的新版 sysext 永远装不上,
运行的还是旧版(无 CommandServer)→ command.sock 不存在 → StatsClient 断流(— KB/s + 旧延迟)。
- VpnChannel.register 阶段调 activateOnLaunch():同开发者高版本静默 replace 运行中的旧扩展。
- StatsClient 连接前打点 command.sock 路径与存在性,直接暴露「旧 sysext 没起 CommandServer」。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 10:50:23 +08:00 |
|
wangjia
|
cf19ca2d34
|
feat(client/macos): 开机自启用 SMAppService + LoginItem helper(学 Tailscale)
根因:launch_at_startup 0.5.1 在 macOS 无自带实现,需宿主接 MethodChannel,而我们 Runner
从没实现 → enable() 抛 MissingPluginException 被 try/catch 吞掉 → 登录项从未注册,自启失败。
学 Tailscale(LoginItemHelper-macsys + SMAppService):
- 新增无界面 LoginItem helper(macos/login_helper,LSBackgroundOnly),登录时带 --autostart
拉起主 app(→隐藏到托盘);
- build_login_helper.sh 构建期编译+签名+嵌入 Contents/Library/LoginItems/(新 Run Script 阶段);
- MainFlutterWindow 接 launch_at_startup MethodChannel → SMAppService.loginItem 注册/注销。
构建通过:helper 嵌入+签名,主 app --deep --strict 校验过。Windows 自启(schtasks)不变。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 10:25:27 +08:00 |
|
wangjia
|
15133b8a72
|
feat(client/macos): 开机自启隐藏到托盘(--autostart),与 Windows 对齐
macOS 登录项(launch_at_startup)注册时带 args:['--autostart'];main() 读该参数
windowManager.hide();MainFlutterWindow.awakeFromNib 检测到 --autostart 时 orderOut
兜底(避免 storyboard Visible At Launch 闪窗)。常规启动无参数,正常显示窗口。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 01:27:30 +08:00 |
|
wangjia
|
bf84492eef
|
feat(client/native): stats-overhaul Phase1 — 四端实时统计采集端
各原生侧把 libbox/Clash 的实时上下行/延迟经冻结的 pangolin/vpn/stats channel
生产真实帧:
- iOS/macOS 新增 StatsClient.swift(LibboxNewCommandClient,statusInterval 1s,
uplink/downlink/总量 + urltest 延迟映射契约字段),VpnManager/VpnChannel 状态
观察驱动 start/stop,pbxproj 登记。
- Android PangolinVpnService.kt 延迟修复。
契约字段 uploadBytes/downloadBytes/uploadSpeed/downloadSpeed/urltestResults 不改。
真机验证(连接后实时跳动)为运行时步骤,见计划 Phase1 待办。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-28 18:13:48 +08:00 |
|
wangjia
|
447f3f494e
|
feat(client/macos): P1 原生隧道——PacketTunnel 系统扩展可加载 + libbox 运行
经长链路排查(同机对照可工作的 Tailscale),修复 macOS 系统扩展 realize
失败(OSSystemExtensionErrorDomain code=4)与 libbox 运行时崩溃,使内嵌
sing-box 的系统扩展能在 macOS 15 上激活并启动隧道。
系统扩展 realize(三个叠加根因):
- 扩展自包含:PacketTunnel 加 OTHER_LDFLAGS="" 切断对项目级 CocoaPods 链接
标志的继承(原会把 flutter_secure_storage 链进扩展);Libbox.xcframework
改纯 Link(静态),从 Embed Frameworks 移除冗余内嵌
- bundle 名 = 标识符:PRODUCT_NAME 设为 com.pangolin.pangolin.PacketTunnel
- 扩展 Info.plist 补 NSSystemExtensionUsageDescription(网络扩展类别强制要求)
- App Group 改 macOS 原生格式 BYL4KQHMTN.com.pangolin.pangolin;NEMachServiceName
以其为前缀;扩展补 network.client/server;get-task-allow=false + 签名加 --timestamp
- CFBundleVersion 随构建递增(否则 sysextd 视为同版本不更新)
libbox 运行时:
- startOrReloadService(options:) 传 nil 致空指针 SIGSEGV → 传 LibboxOverrideOptions()
- 默认接口监控阻塞到首个 path 更新再返回,修 "no available network interface"
配套:
- scripts/local_test.sh:build/sign/notarize/copy/run 一条龙(Developer ID + 公证)
- client/macos/sign_libbox.sh:构建期以 Developer ID 重签内嵌 Libbox
- VpnChannel:401 自动刷新 token、详尽 os_log;auth/api 统一走 kApiBaseUrl
- docs/macos-sysext-realize-troubleshooting.html:完整踩坑复盘
WIP / 临时(后续清理):
- 隧道运行时仍在排查:剥离远程 rule-set 后 sing-box 启动卡点未定位
- 含临时诊断代码:main.swift stderr 重定向、box.log 输出、rule-set 剥离、debug 日志
- api_config 仍指向联调节点,发版前还原
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEHzjEcFzvGwgbxT6Wbt6c
|
2026-06-21 21:18:33 +08:00 |
|
wangjia
|
fb1ef9ba01
|
feat(client/macos): OSSystemExtensionRequest 激活 sysext
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
VpnChannel.activateSystemExtensionIfNeeded 实装:start 前请求系统加载/更新
PacketTunnel sysext;首启弹「隐私与安全性」待用户允许(await 阻塞到批准,
扩展没加载隧道起不来)。SysExtActivationDelegate 处理 finish/fail/replace。
至此 macOS 原生 VPN 栈构建完整:Runner 嵌入 sysext 到
Contents/Library/SystemExtensions,编译全过。运行待:sysext 签名放行 +
systemextensionsctl developer on(或 Developer ID 公证)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 15:54:14 +08:00 |
|
wangjia
|
6a9a7c424e
|
feat(client/macos): 主 app VPN 接线编译通过 — VpnChannel 入 Runner target
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
- VpnChannel.swift 加入 Runner target(Compile Sources)
- Logger→NSLog(Runner 部署目标 10.15,os.Logger 需 11)+ 去掉未用的
SystemExtensions import
- 至此原生 VPN 控制链路全编译通过:主 app(NETunnelProviderManager 启停/
状态)+ 扩展(libbox)。kUseNativeVpnMacOS 仍 false(待隧道能跑切换)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 15:43:42 +08:00 |
|
wangjia
|
c8df031741
|
feat(client/macos): 解开 VpnChannel 注册(主 app 接 NETunnelProviderManager)
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
MainFlutterWindow 启用 VpnChannel.register —— Flutter 经 pangolin/vpn 通道
启停 PacketTunnel(NETunnelProviderManager)。需 VpnChannel.swift 已入 Runner
target 的 Compile Sources。kUseNativeVpnMacOS 仍为 false(待隧道能跑再切)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 15:36:38 +08:00 |
|
wangjia
|
07272f5610
|
fix(client/macos): P1 骨架修正 — bundle id 统一 PacketTunnel + Info.plist 精简
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
- VpnChannel/Provider: 扩展 bundle id 统一为 com.pangolin.pangolin.PacketTunnel
(对齐 Xcode 新建 target 的实际 id)
- PacketTunnel/Info.plist: 去掉重复 CFBundlePackageType + 多余 NEMachServiceName,
只保留 NEProviderClasses(其余标准键由 GENERATE_INFOPLIST_FILE 合并)
- .gitignore: 忽略 Frameworks/Libbox.xcframework(204MB,build-libbox.sh 产出)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 13:50:51 +08:00 |
|
wangjia
|
b25c8bbc2c
|
feat(client/macos): P1 方案B 骨架 — System Extension + NETunnelProviderManager 接线
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
把 PoC 的 sudo sing-box 外部二进制换成自包含、免 root 的 NEPacketTunnelProvider
(System Extension)+ 嵌入 libbox 的生产架构铺好骨架(不破坏现有 PoC 构建)。
- PacketTunnel/:扩展 target 源 — PacketTunnelProvider(LibboxSetup→NewService→start,
openTun 建 NEPacketTunnelNetworkSettings)、Info.plist(NEProviderClasses)、
entitlements(packet-tunnel-provider-systemextension + App Group)
- Runner/VpnChannel.swift:主 app 经 NETunnelProviderManager 启停 + 状态/速率回传,
对齐 Dart 侧 VpnNativeBridge 的 pangolin/vpn channel 契约
- vpn_bridge_provider.dart:kUseNativeVpnMacOS 开关(默认 false,联调通过后置 true)
- docs/p1-macos-system-extension.md:文件清单 + Xcode/签名步骤 + 待办
(Team BYL4KQHMTN;Network Extensions 已确认自助开通、无需 Apple 审批)
非破坏:新源文件未入 build target、注册行/app-group entitlements 均注释、gate 默认 false。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 11:07:36 +08:00 |
|
wangjia
|
3f62d54d23
|
fix(client): 关窗口缩托盘不退出 + 单实例(一机一进程)
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
- 关窗口托盘也消失:根因是 AppDelegate.applicationShouldTerminateAfterLast
WindowClosed 返回 true → 关窗口即终止 app。改 false:关窗口只隐藏到托盘
(配合 window_manager preventClose+hide),app 留在托盘。
- 单实例:main 启动先 ensureSingleInstance()——loopback 47654 端口锁;已有实例
时连过去唤起其窗口显示,本进程 exit(0)。保证一机仅一个 pangolin 进程,
重复启动只会前置已有实例。
flutter analyze 0 error;测试通过。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 09:34:12 +08:00 |
|
wangjia
|
748a3b8a45
|
chore(client/macos): bundle id 改为 com.pangolin.pangolin
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
去掉 Vpn 后缀:macOS 主 app + RunnerTests + Debug/Release entitlements 的
keychain-access-groups 统一为 com.pangolin.pangolin(便于 Apple 签名注册)。
iOS/Android 暂未改(iOS 涉 App Group + PacketTunnel 扩展,需统一时单独处理)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-18 08:57:35 +08:00 |
|
wangjia
|
f3cc2dfc2d
|
fix(client): 去 dev 旁路 + 修 macOS keychain -34018 [tsk__bm21nctbhWF]
1. 去 dev 旁路:删除 auth_screen.dart 中 test@pangolin.dev 预填 + devLogin
跳过后端分支,以及 auth_provider.dart 的 devLogin() 方法。
2. 修 keychain -34018(errSecMissingEntitlement):
在 DebugProfile.entitlements / Release.entitlements 中添加
keychain-access-groups($(AppIdentifierPrefix)com.pangolin.pangolinVpn),
使 flutter_secure_storage 的 Data Protection Keychain API 获得正确 entitlement。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 13:21:38 +08:00 |
|
wangjia
|
4dc4127252
|
feat(client): 三端布局架构 + macOS 桌面端 + app 图标
三端布局(mobile/tablet/desktop):
- core/responsive/form_factor.dart 形态判定 + shell/ 分发器(home_shell→desktop/mobile)
- desktop_shell 对照 ui_kits/desktop/dapp.jsx: 侧栏204·6项 + 套餐卡 + 顶栏(标题/状态/主题切换) + 连接页居中单列
- 新增组件 nav_sidebar / plan_badge_card / content_top_bar / bottom_tab_bar
- 新增一级页 contact_page / settings_page; navigation_provider(NavView)
- 删除旧 widgets/home_shell.dart(逻辑迁入 shell/)
macOS 桌面端:
- 窗口默认 920×600 + 最小 720×560(MainFlutterWindow.swift)
- app 图标替换为穿山甲(AppIcon.appiconset 全套, 由 app-icon.svg 渲染)
其余(本会话):
- Phase2 接线: auth_api/token_store/auth_provider/vpn_bridge_provider + 真实 connection/nodes
- lucide_icons 兼容补丁(packages/lucide_icons_patched) 修复 IconData final 报错
- 测试修复: connect_passthrough(UTF-8) / harness / golden @Skip
- l10n 新增 settingsTitle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 09:23:20 +08:00 |
|