wangjia
|
ac0fc774cb
|
Merge branch 'main' into feature/windows
|
2026-06-22 14:17:19 +08:00 |
|
wangjia
|
322d806876
|
fix+build(client/windows): 复查修缮——一键构建脚本 + 修 README dart-define 漏项 + 清 lint
- 新增 client/windows/build.ps1:拉内核→带 --dart-define 构建→出安装包一键串联,
规避 Release 漏 --dart-define 导致默认连 localhost、登录「网络请求失败」的坑。
- README:Release 命令补回 --dart-define 并加显式警告,指向一键脚本。
- 清 4 个 lint warning:desktop_vpn_bridge 多余 cast→pattern match、去多余非空断言;
nav_sidebar 删未用 import;vpn_bridge_mock 加 killSwitchEnabled getter。
- 同步 window_manager/tray_manager/screen_retriever 插件注册生成文件(win+macos)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-22 14:17:13 +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
|
7827660a36
|
fix(client): 登录页 tab 滑块塌陷 + 滚动弹性(design-distill 校准)
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
- 胶囊 tab 活动滑块高度塌成 0(FractionallySizedBox 缺 heightFactor)→ 活动态
不可见、和背景糊一起。补 heightFactor:1.0,滑块正常填满。
- 列表无弹性回弹:SingleChildScrollView 改 ClampingScrollPhysics,大窗口放得下
就不滚(无上下拖动/滚动条),仅窗口过矮才滚。
- 加 auth_redesign golden(900x700 明/暗),按 design-distill 截图 diff 校准:
与原型 design/preview/auth_redesign.html 对比,结构/位置/尺寸零偏移
(残余差异为 headless 测试缺 CJK 字体的豆腐块,真 app 字体正常)。
flutter analyze 0 error;测试通过。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 08:25:56 +08:00 |
|
wangjia
|
9de3a6c743
|
feat(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
- auth_screen.dart 整体重排:暖色径向光晕背景 + 居中卡片;hero 用 clay 渐变
app-icon(带光晕)+ 品牌 + 标语;胶囊分段 tab(滑块)替下划线;输入框聚焦态
(accent 边 + ring 光环);主按钮微光;进入错落淡入动效。全部走 token。
- 注册第二步:已验证邮箱胶囊 + 「改邮箱」返回 + 设密码;验证码框无占位点。
- 逻辑零回归:登录/注册两段式、发码、邮箱预填、密码显隐、错误提示全保留。
- design/preview/auth_redesign.html:HTML 视觉原型(评审用,不进构建)。
flutter analyze 0 error;114 tests passed(auth 不在 golden 集,无 golden 变化)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 08:10:33 +08:00 |
|
wangjia
|
aee9ba7b72
|
feat(client): 登录体验 — 记住邮箱 + 密码显隐 + 7天免登陆
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
1. 记住邮箱:登录页预填上次邮箱(TokenStore.saveLastEmail,登录/注册成功时存,
退出登录不清除)。
2. 密码显隐:登录/注册密码框加眼睛按钮切换明文(PangolinIcons.eye/eyeOff)。
3. 7天免登陆:RootFlow 改为响应 authProvider——启动时有有效会话直接进主界面;
AuthNotifier.refresh() 在服务端拒绝(refresh 过期/超 7 天)时 logout 回登录页,
网络错误则保留会话。会话恢复期间显示极简启动屏。
flutter analyze 0 error;114 tests passed。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 06:28:49 +08:00 |
|
wangjia
|
f35bbea0a0
|
fix(client): 连接后延迟用内核 urltest 实测 + 侧栏套餐到期日接真
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
- 延迟:TCP 探针在隧道开启时会被路由进隧道而测不到(显示 —)。改为连接后
(phase==on)取内核 statsStream 的 urltest delayMs 最小正值(代理真实 RTT),
未连接时仍用节点 TCP 探针。连接页 _SpeedRow/_NodePill/_CurrentNodeCard
与统计页平均延迟统一此口径。
- plan_badge_card(侧栏)接 me.expiresAt 显示真实到期日(原只显示「有效期至」
无日期);account_page 之外漏改的最后一处。
flutter analyze 0 error;114 tests passed。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 00:44:46 +08:00 |
|
wangjia
|
93ec421c41
|
fix(plans): /v1/plans 500 修复 — plans 表无 name_zh/name_en 列
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
ListPlans 历来 SELECT name_zh/name_en,但 plans 表从未有这两列(各迁移/seed
均无)→ 该端点一直 500(无 live 测试故未暴露)。改为不查名称列(套餐名是 UI
文案,客户端 PlansScreen 按 code 取 l10n:free/pro/team)。价格等真实字段保留。
已在节点实测:/v1/plans 200,返回 free ¥0 / pro ¥25 / team ¥99。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 00:32:40 +08:00 |
|
wangjia
|
f20eddad55
|
feat(client): P4 节点实测延迟/设备/套餐价/兑换/统计接真(#6 6D)
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
- latency_probe.dart:并行 TCP 握手实测各节点 per-client RTT(服务端无法代知)。
- nodes_provider:解析 /v1/nodes 的 host/port,后台测延迟回填 Node.ping;智能选择
按实测最小;去掉 8 个伪造演示节点(空列表用中性占位,不再伪造服务器)。
- Node:+host/port/copyWith/pingLabel(未测显示 —);各端 ping 显示改 pingLabel。
- account_screens:PlansScreen 接 /v1/plans(价格 priceLabel + me 标当前档);
DevicesScreen 接 /v1/me/devices + 移除 DELETE + last_seen;RedeemScreen 接
/v1/redeem(成功刷新 me,失败显示后端文案)。
- stats_page:周柱接 me.weekly_gb,本月流量/时长接 usage(30),延迟用生效节点实测。
- 顺带补登记早前 log_time.dart 的删除(log.dart 重构遗漏 stage)。
flutter analyze 0 error;115 tests passed;受影响 4 golden 重生成。
本机设备高亮 + 真实 device id 随 P6(device_info_plus)落地。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 00:04:25 +08:00 |
|
wangjia
|
d341c1c6e5
|
fix(client/auth): 验证码字段去掉点状占位(hintText 改空)
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
'······' 占位被误以为是已填/遮蔽;验证码本就明文输入,清空占位更清晰。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-18 09:23:12 +08:00 |
|
wangjia
|
6979411c1d
|
feat: 档2 接真后端 — mac app 真注册/登录/拉节点
dev 本机置备(新增 dev/):
- docker-compose.yml: MySQL :13306 + Redis :16379(避让本机已占的 3306/6379)
- run-local.sh 一键: 起容器→openssl 生成密钥(dev/.local gitignore)→migrate→
seed→启动 server :18080(避让 8080);LogMailer 把验证码打日志
- seed.sql(1 provider + 1 HK 节点)、run-local.md 手册、.gitignore
后端两处修复(本地无 gRPC 场景,注释意图与代码不符的 bug):
- main.go: 无 gRPC 时真正构造 Hub-only nodeSvc(原只建 hub 没赋值),/v1/nodes 才能挂
- main.go: /me 改 Route 子路由根 Get,修 Get("/me")+Route("/me") 冲突致 404
客户端接真后端:
- token_store: MacOsOptions(useDataProtectionKeyChain:false) 修 keychain -34018
- auth_screen: 删 dev 旁路(test 账户内存登录),所有登录走真 API
验收: 后端 curl 端到端全通(验证码→注册→登录→/nodes→/me);
server go build/vet/test 通过, client analyze 0 + test 84
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 13:27:58 +08:00 |
|
wangjia
|
fe16f89bc3
|
feat(client): 账户子页 desktop 内容区下钻(档1)
- desktop 上套餐选择/兑换购买/设备管理改为内容区下钻(侧栏保留、shell 顶栏带
返回箭头),不再全屏 push 盖住侧栏;mobile/tablet 仍全屏 push
- _SubScaffold 加 embedded 参数(true 只返回内容),PlansScreen/DevicesScreen/
RedeemScreen 透传;NavView 加 devices + kAccountSubViews 集合
- desktop_shell 渲染子页(embedded) + 顶栏 onBack→account;account_page 按
formFactor 选下钻(切 navView)或 push
- desktop 整页 golden 补 套餐/兑换/设备 三子页(共 8 页)
测试: flutter test 84 通过(+3 子页 golden), analyze 0 error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 12:36:14 +08:00 |
|
wangjia
|
281a6261fb
|
feat(client): tablet 外壳 + 视觉 diff 工作流文档
- tablet_shell: 侧栏 232·4 项触控(minHeight 48, 字号 15) + 顶栏无主题切换 + 连接页双栏
对照 ui_kits/tablet/tabapp.jsx;home_shell 分发 tablet→TabletShell
- nav_sidebar 加 dense 参数(desktop 紧凑 / tablet 触控)
- content_top_bar 加 showThemeToggle + titleSize 参数
- tool/visual-diff.md: 截图 diff 工作流(design-distill 工具)+ 实现侧三路径
现状(golden 被 google_fonts 阻塞 / screencapture 受 macOS chrome 限制)+ 推荐
注: tablet 形态在 macOS 桌面平台不触发(只 desktop/mobile),运行验证需 iPad。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 09:38:18 +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 |
|
wangjia
|
bf1717a369
|
merge: 控制面联调 M6 [tsk_nuoKSM4Vt-zK]
# Conflicts:
# .gitignore
# client/lib/widgets/home_shell.dart
# client/lib/widgets/server_tile.dart
# client/pubspec.yaml
|
2026-06-13 17:32:26 +08:00 |
|
wangjia
|
6f6cb97509
|
merge: Flutter 逐屏还原 + iPad 断点 [tsk_gpPXi-icyeOE]
# Conflicts:
# client/lib/widgets/connect_button.dart
# client/lib/widgets/home_shell.dart
# todo/todo.html
# todo/todo.json
|
2026-06-13 17:30:36 +08:00 |
|
wangjia
|
c84b6ea7da
|
merge: maestro/tsk_iP5-_Ztq5THx [桥接 API 面 Channel 契约 + 三端原生骨架] [tsk_rcNKc3GQHBUd]
合并冲突补救:原分支从 merge base 7871512 分叉,仅修改 client/ 目录,
与 main 新增的 server/(apierr/idgen/CONVENTIONS.md) 完全不重叠,
无真实文件冲突,手动应用 feature branch 的全部 client/ 改动。
client 侧新增:
- lib/bridge/vpn_bridge.dart — Dart↔原生通道契约(冻结)
- lib/bridge/vpn_bridge_mock.dart — 假内核,UI 联调用
- lib/bridge/kernel_process.dart — 桌面子进程管理接口
- ios/PacketTunnel/{Info.plist,PacketTunnelProvider.swift} — NEPacketTunnel 骨架
- ios/Runner/VpnManager.swift — NETunnelProviderManager 封装
- android/.../PangolinVpnService.kt — VpnService 骨架
- android/.../VpnEventBus.kt — Application 级状态总线
- test/bridge/vpn_bridge_mock_test.dart — 桥接层单元测试
client 侧修改:
- android/.../MainActivity.kt — 注册三通道(MethodChannel + 2×EventChannel)
- android/.../AndroidManifest.xml — 声明 FOREGROUND_SERVICE + PangolinVpnService
- ios/Runner/AppDelegate.swift — 注册通道 + VpnManager 初始化
- ios/Runner/Info.plist — 新增 NSVPNUsageDescription
- ios/Runner.xcodeproj/project.pbxproj — 添加 PacketTunnel extension target
- lib/widgets/connect_button.dart — VpnStatus 迁移到 bridge/vpn_bridge.dart
- lib/widgets/home_shell.dart — error 状态 UI 分支补全
|
2026-06-13 14:58:38 +08:00 |
|
wangjia
|
f97ae8186b
|
feat(client): Flutter 逐屏还原 + iPad ≥900 断点 (tsk_gpPXi-icyeOE)
对照 design/ui_kits mobile+tablet 原型逐屏补齐 Flutter 客户端:
- l10n 资源层(strings_zh/en,单显)+ Riverpod 状态层(连接状态机/免费额度/
节点选择/语言/主题),UI 与数据解耦,mock 数据接 API 不动 UI。
- 连接键严格三态(off 虚线轨道环 / connecting 旋转弧 / on 满环+计时+光晕),
状态来自 connectionProvider,点击只派发事件——禁止乐观显示。
- 节点页置顶「智能选择」推荐卡(clay 渐变 zap + 推荐胶囊,默认选中);
免费额度卡(剩余分钟+进度条 ≤3 分钟切 warning + 看广告解锁变绿)。
- Tab 左右滑动切换(手势竞技场仲裁,子页滚动不误触发,200ms 方向感知滑入)。
- iPad/宽屏 ≥900 LayoutBuilder 切侧栏分栏(导航行高 ≥48,连接页双栏/节点双列网格),
复用同一批原子组件,不 fork 页面。
- 语义 token 零硬编码;文案全部走 l10n;套餐数字对齐 §7;无支付表单/emoji 国旗。
- CI 红线词扫描扩展到 client/lib;新增 Flutter analyze+test CI 任务。
- 测试:连接状态机/额度/节点单测、连接键三态与卡片组件测试、
golden(连接键三态/推荐卡/额度卡 × 明暗)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-13 14:32:36 +08:00 |
|
wangjia
|
bd8f974a25
|
feat(M6): 控制面联调 — mock connect server + 客户端 ConnectApi 透传
tsk_nuoKSM4Vt-zK
## 服务端(server/cmd/mockserver)
- `main.go`(79 行):独立 mock HTTP server,实现 POST /v1/nodes/:id/connect
- 路径/请求体/响应体字段名与 §3.1 契约逐字一致
- Bearer token 鉴权(-token 参数,空值跳过,不入库)
- 缺少 device_id → 400;未授权 → 401;非 POST → 405
- 返回完整 sing-box config JSON(tun + REALITY/Hy2 outbound + urltest + route/dns)
- 注:mock 联调;待 #5/#6 真实 connect 接口就绪后替换
- `main_test.go`:6 项单测,覆盖 §3.1 结构校验、auth、method、path
## 客户端(client/)
- `lib/services/connect_api.dart`:ConnectApi 类
- fetchConfig(nodeId, deviceId) → 原始响应体字符串(不做任何修改)
- 错误路径:HTTP 非 200 / 超时 / 非法 JSON → ConnectApiException(含双语 message)
- `lib/services/vpn_bridge.dart`:VpnBridge stub(M6 联调,libbox 绑定待 11C)
- start(configJson) 原样存储,不修改;stop() 清空
- `lib/widgets/home_shell.dart`:_toggle/_pick 替换为真实 API 流程
- ConnectApi.fetchConfig → VpnBridge.start(透传,无中间变换)
- 错误路径:ConnectApiException → SnackBar,status 回 off,无残留半开隧道
- API URL/token/deviceId 由 --dart-define 注入(不入库)
- `lib/widgets/server_tile.dart`:ServerInfo 新增 nodeId 字段
- `pubspec.yaml`:新增 http: ^1.2.1 依赖
- `test/connect_passthrough_test.dart`:4 项透传断言单测
- 核心:fetchConfig 返回字符串 === VpnBridge.start 接收字符串(逐字节相等)
- 空格/格式原样保留(不经 jsonEncode 重序列化)
- HTTP 错误、非法 JSON 错误路径覆盖
## 运行方式(M6 联调)
```
# 启动 mock server(无 auth)
go run ./server/cmd/mockserver -addr :8081
# 启动客户端(指向 mock server)
flutter run \
--dart-define=PANGOLIN_API_URL=http://localhost:8081 \
--dart-define=PANGOLIN_API_TOKEN=dev-mock-token \
--dart-define=PANGOLIN_DEVICE_ID=demo-device-001
```
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-13 14:16:29 +08:00 |
|
wangjia
|
526e7f2f33
|
feat(tsk_iRa5iBC4v7Tu): Flutter 客户端工程搭建(演示态)
基于 design/flutter/ 起步包在 client/ 下建立 Flutter 工程:
- pubspec.yaml:flutter_svg / lucide_icons / google_fonts 依赖;
SVG 资产注册;字体由 google_fonts 运行时加载,无需本地 ttf
- lib/pangolin_theme.dart:完整设计令牌(色阶 / 间距 / 圆角 /
动效 / 文字阶),PangolinText 改用 GoogleFonts getter,
PangolinTheme.light / .dark 开箱即用
- lib/main.dart:runApp + 明暗主题 + 登录 → 引导 → 主框架 RootFlow
- lib/widgets/:全套组件雏形
pangolin_icons Lucide 图标映射
pangolin_button 胶囊按钮四态
country_code 国家码块 + 信号条
status_pill 色点胶囊
connect_button 核心连接键三态(off/connecting/on + 动画)
server_tile 服务器列表行
plan_card 套餐卡(专业版渐变高亮)
auth_screen 登录 / 注册(邮箱验证码 + 设密码)
onboarding_screen 首次引导 PageView(3 屏可滑动 + 进度点)
home_shell 底部 4 Tab(连接/节点/统计/账户 + 状态机)
account_screens 套餐选择 / 设备管理 / 兑换 / 联系我们
pangolin_logo PangolinMark / BrandLockup / AppIcon(SVG)
- assets/:logo-mark / logo-mark-white / logo-wordmark / app-icon(SVG)
- android/:Kotlin 主 Activity + Manifest + Gradle 配置
- ios/:Runner.xcodeproj + xcscheme + Podfile + AppDelegate + storyboard
运行方式(cd client/):
flutter pub get && flutter run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-13 02:15:42 +08:00 |
|