wangjia
4e8d928350
feat(ci): macOS + iOS 客户端 CI 脚本(照 jiu + 系统扩展)+ 自动更新 manifest 推送接线
...
Deploy Client / build-android (push) Failing after 1m16s
Deploy Client / build-macos (push) Failing after 3s
Deploy Client / build-ios (push) Successful in 2s
Deploy Client / build-windows (push) Has been cancelled
Deploy Client / release-deploy (push) Has been cancelled
compile-macos.sh(Developer ID 签名+公证+staple, 2 描述文件+libbox 重建+CFBundleVersion 递增,
早期 fail-fast 缺 secret 不浪费构建)、compile-ios.sh(TestFlight, 缺 secret 优雅跳过)。
deploy-client.yml 加 build-macos/build-ios(runs-on mac, continue-on-error+release-deploy 不 needs
它们 → 不拖挂 android/windows)。release-client.sh 兼容自动更新 manifest 推送 + macos zip。
+ url_launcher 的 macos/windows 生成插件注册。代码就绪, 待 Apple secret 才能真跑 macOS/iOS。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 00:20:00 +08:00
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
211fda37e3
fix(client/macos): urltest 完全照搬 Windows 策略——读 /proxies history + active 刷新
...
Windows(kernel_process.dart)的策略:显示源是 /proxies 各 URLTest 成员的 history.last.delay
(每拍读、缓存住、稳定);/group/<name>/delay 只为让内核重测并写进 history,其结果不直接用。
我之前直接用 active 结果,拥塞链路上 active 恒返回 {} 就全空了。
本次照搬:主显示读 /proxies history(extractUrltestResults 字段与 Windows 一致),active
/group/delay 既刷新 history 又顺手缓存(双保险);非空才更新,单次失败不覆盖旧值。
CURRENT_PROJECT_VERSION 50→51。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 14:45:14 +08:00
wangjia
e8e6a0dc24
fix(client/macos): urltest 回到 active /group/delay 取值(v48 验证可行),跳过 GLOBAL
...
v49 改读 /proxies history 后为空:sing-box 的 /proxies 不带 member history。回到 v48 验证
可行的 active 取法——/group/<name>/delay(跳过 GLOBAL 选择器组),成功就缓存,超时/空不
覆盖旧值,显示稳定。移除无效的 extractUrltestResults。
扩展代码变更 → CURRENT_PROJECT_VERSION 49→50。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 14:22:52 +08:00
wangjia
a228a1d221
fix(client/macos): urltest 主源改读 /proxies history(稳定),修连接页延迟
...
v48 验证延迟已打通(urltest=reality-out=576 到达主 app),但 active /group/delay 在拥塞
链路上常超时返回 {}。改为与 Windows extractUrltestResults 完全一致:主源读 /proxies 里各
URLTest 组成员的 history 缓存延迟(稳定,active 探测超时也不丢),并对 URLTest 组(跳过
GLOBAL 选择器)主动跑 /group/<name>/delay 刷新 history。延迟显示由此稳定。
扩展代码变更 → CURRENT_PROJECT_VERSION 48→49。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 14:13:58 +08:00
wangjia
70e8f67702
diag(client/macos): 把 /group/delay 原始响应塞进 diag,定位 urltest 为空
...
v47 诊断:clash 注入生效(组名 auto 已识别),但 /group/auto/delay 返回无数字延迟。
本次把该接口原始响应体(含 HTTP 状态码)透出到 diag,并兼容嵌套 {tag:{delay:ms}} 形态,
一眼区分:内核探测失败(raw={} / 错误消息)还是返回结构不符(解析问题)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 13:28:55 +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
783687d7c2
fix(client/macos): StatsCollector 用独立 client 订阅 Group,修 urltest 延迟为空
...
诊断确认:连接页延迟显示 — 是因为扩展回给主 app 的 urltest 数组恒为空(speeds 正常)。
根因:libbox command 协议是「一连接一命令」,把 Status 与 Group addCommand 到同一 client
只有 Status 生效,Group 永不回调 → 无 urltest。对齐 sing-box-for-apple:每命令各开一个
client。新增 groupClient 专订 Group + 跑 urlTest,延迟即随统计帧回到连接页(与 Windows 同源)。
扩展代码变更 → CURRENT_PROJECT_VERSION 45→46,让 sysextd 重装。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 12:33:00 +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
71132df669
fix(client/macos): sysext 把 command.sock 建在登录用户容器并 chown,修实时统计断流
...
根因:系统扩展以 root 运行,其 App Group 容器是 /var/root/Library/Group Containers/...,
而用户 app 的是 /Users/<user>/...(容器 home 相对)。libbox 把 command.sock 建在 basePath
下 → 落在 root 容器;无 root 权限的 app 永远 connect 不上 → 连接页 — KB/s + 延迟不刷新。
(经 sudo ls 实测确认:socket 在 /var/root 容器,用户容器里没有。)
- PacketTunnelProvider 用 SCDynamicStoreCopyConsoleUser 取登录用户,把 libbox basePath/
workingPath 指向该用户的同名容器(root 可写),command.sock 即落在 app 查找的路径。
- server.start() 后 chown 容器/work/command.sock 给登录用户:Unix socket connect() 需写
权限,仅 owner 满足,否则 app 仍 EACCES。拿不到登录用户时回退 root 容器(隧道可用、仅统计不可用)。
- sysext 代码改动 → CURRENT_PROJECT_VERSION 43→44,让 sysextd 重装新扩展。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 11:43:41 +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
77f31c90ec
fix(client/macos): 递增 PacketTunnel CFBundleVersion 23→43,让 sysextd 重装新 sysext
...
根因:PacketTunnel 的 CURRENT_PROJECT_VERSION 写死 23(其配置无 baseConfig、拿不到
FLUTTER_BUILD_NUMBER 自动递增)→ 每次构建出的 sysext 都是 v23 → sysextd 视为同版本拒绝
重装 → 跑的一直是老 v23 sysext(没有 LibboxCommandServer)→ App Group 容器无 command.sock
→ 主 app StatsClient 连不上(no such file)→ 实时流量/urltest 全失效(连接页 0 B/s + 延迟 1ms)。
bump 到 43(高于主 app 的 42)→ sysextd 重装带命令服务的新 sysext。
注:sysext 代码改动后须手动递增此值(CLAUDE.md 铁律)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-30 10:34:15 +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
c0c4b94e29
feat(devices): P1 设备注册打通 —— 登录/注册即写 devices 表
...
ci-pangolin / Lint — shellcheck (push) Successful in 8s
ci-pangolin / OpenAPI Sync Check (push) Successful in 16s
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Successful in 7s
ci-pangolin / Flutter — analyze + test (push) Successful in 26s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (push) Successful in 5s
ci-pangolin / Codegen Drift — token 生成物未漂移 (push) Successful in 5s
ci-pangolin / Go — build + test (push) Failing after 10s
ci-pangolin / E2E Smoke — L4 进程级端到端 (push) Successful in 15s
ci-pangolin / Go — integration (mysql/redis testcontainers) (push) Failing after 4m10s
ci-pangolin / Golden — 视觉回归 (components + auth) (push) Successful in 14s
后端:auth.Service 加 DeviceMeta + DeviceRegistrar 接口(consumer-side 解耦),
Login/Register 成功签发后 best-effort 注册设备(不强制设备上限,避免免费档重装
churn 锁死用户);handler 加 device 请求体;main 用 authDeviceRegistrar 适配
devices.Service 注入;normalizePlatform 加 linux。
客户端:新 device_identity.dart(SecureKV 接缝 + 稳定 UUIDv4 device_id 持久化 +
名称/平台/版本);弃用硬编码 'mac-001';auth_api login/register + connect 携带
device 元数据。加 uuid + device_info_plus 依赖。
测试:auth 设备注册(触发/best-effort/空 meta) + device_identity(生成/持久/
读失败不重生成/UUIDv4 形态);normalizePlatform linux=true。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-29 00:28:13 +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
cebc9a1c4f
fix(client/macos+server): 隧道运行时打通——DNS 劫持 + 死锁/空指针修复
...
接续 447f3f4(系统扩展可加载),修复"扩展能起但连上无法上网"的运行时问题,
现已在 macOS 15(cara)端到端连通:出口=节点 IP、国外站可达、DNS 经隧道解析。
服务端(clientconfig.go):
- route.rules 首条加 {"action":"hijack-dns","port":[53]}(排在 LAN 直连规则前)。
否则发往隧道 DNS(172.19.0.2:53)的查询被 172.16.0.0/12 吞去直连,域名解析失败。
sing-box 1.13 按端口劫持(protocol:dns 需先 sniff,不稳)。
客户端——保留三个真 bug 修复:
- startTunnel 的 libbox 启动移到后台队列:避免在 provider 队列同步阻塞,与
openTun→setTunnelNetworkSettings 回调三方死锁(隧道永远卡 connecting)。
- startOrReloadService(options:) 传非空 LibboxOverrideOptions():传 nil 致空指针 SIGSEGV。
- startDefaultInterfaceMonitor 阻塞到首个 path 更新再返回:修 "no available network interface"。
- 清除排障期临时诊断代码;CFBundleVersion 递增(sysextd 按版本去重)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01JEHzjEcFzvGwgbxT6Wbt6c
2026-06-22 08:57:55 +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
2a4d6c9648
build(client/macos): Runner 开启 Hardened Runtime(公证前置)
...
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
PacketTunnel 已有 ENABLE_HARDENED_RUNTIME;给 Runner 的 Debug/Release 也补上。
Developer ID 分发 + 公证要求 Hardened Runtime。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 16:04:53 +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
f2a4290602
feat(client/macos): PacketTunnel 转 System Extension(构建通过)
...
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
macOS 站外加载隧道必须 sysext(appex 仅 App Store 可加载)。转换:
- productType app-extension→system-extension;产物 .appex→.systemextension
- 嵌入路径 PlugIns→Contents/Library/SystemExtensions(SYSTEM_EXTENSIONS_FOLDER_PATH)
- main.swift 入口(NEProvider.startSystemExtensionMode + dispatchMain;sysext 是
可执行程序,需显式 main 而非 appex 的 NSExtensionMain)
- Info.plist 加 NEMachServiceName;entitlement 换回 packet-tunnel-provider-systemextension
CFBundlePackageType 自动 SYSX,Build Succeeded(关签名)。运行还需 Developer ID
签名 + systemextensionsctl developer on + OSSystemExtensionRequest 激活。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 15:51:29 +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
665d4a949d
build(client/macos): PacketTunnel appex target + libbox/系统框架链接
...
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
Xcode 工程持久化:
- 新增 PacketTunnel App Extension target(嵌入 Runner,Packet Tunnel provider)
- 链接 Libbox.xcframework(Embed & Sign)+ SystemConfiguration/AppKit/
libresolv(Do Not Embed,libbox 内部系统代理/网络监控/DNS 依赖)
- NetworkExtension 改 Do Not Embed(系统框架不可嵌入重签)
至此 P1 隧道扩展编译+链接+签名全通(Build Succeeded)。Libbox.xcframework
本体不入 git(gitignore),按 scripts/build-libbox.sh 重编。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 15:33:15 +08:00
wangjia
b621d1754a
feat(client/macos): PacketTunnelProvider libbox 集成(编译+链接通过)
...
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
CommandServer 装配(LibboxSetup→NewCommandServer→start→startOrReloadService)+
完整 LibboxPlatformInterface:openTun(TunOptions→NEPacketTunnelNetworkSettings,
getpeername+utun ctl_id 取 fd)、默认接口监控(NWPathMonitor)、接口枚举、socket
绑定;LibboxCommandServerHandler 回调。
gomobile 桥接要点:实现接口用 XxxProtocol、接口型参数/返回用 (any XxxProtocol)、
三个方法被 Swift 重命名(autoDetectControl/send/usePlatformAutoDetectControl)、
CTLIOCGINFO 按 _IOWR 定义计算。
链接需补系统框架:SystemConfiguration + AppKit + libresolv(libbox 内部
系统代理/网络监控代码引用)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 15:20:50 +08:00
wangjia
8367984e23
fix(client/macos): PacketTunnelProvider 改用 completion-handler 绕开 Swift 6.2 编译器崩溃
...
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
Swift 6.2.3 在为 async 重写的 startTunnel 生成 ObjC 桥接 thunk 时崩溃
(emitInjectLoadableEnum)。改用 completion-handler 形式(直接是 @objc 原型)
绕开。startTunnel/stopTunnel/handleAppMessage 三个 override 同步改。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 14:30:11 +08:00
wangjia
7e92a9a711
fix(client/macos): PacketTunnel 开发期用 appex NE 变体 packet-tunnel-provider
...
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
Xcode 把 target 建成 App Extension(.appex);sysext 变体 -systemextension 在
Apple Development 自动签名下签不了。开发期改用 appex 变体能编/签/本机调试;
上线转 System Extension + Developer ID 时再换回 -systemextension(注释已记)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 14:20:21 +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
6ee7114ff8
feat(client): P6 设置项落地真实行为( #6 6F,本地部分)
...
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
- settings_provider:三开关 shared_preferences 持久化 + 副作用落地:
killSwitch→VpnBridge.setKillSwitch(on:);autostart→桌面原生登录项
(launch_at_startup);smartRoute 持久化为偏好(连接时作 split_cn,见 #5 )。
- settings_page → ConsumerWidget,开关接 settingsProvider;协议标签
WireGuard→REALITY/Hysteria2;版本号取 pubspec(package_info_plus)。
- 新依赖:shared_preferences / package_info_plus / launch_at_startup。
flutter analyze 0 error;114 tests passed;settings golden 重生成。
待办:#5 智能分流的 server 端 geoip-cn 下发 + autostart 真机验证(需 release .app)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 00:13:41 +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