21 Commits

Author SHA1 Message Date
wangjia f37f1f3b59 feat(web): 修语言下拉漂移(class 化)+ 主页登录态用户中心按钮 + 用户中心返回主页
ci-pangolin / Lint — shellcheck (pull_request) Successful in 10s
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (pull_request) Successful in 29s
ci-pangolin / OpenAPI Sync Check (pull_request) Successful in 32s
ci-pangolin / Cleartext Scan — Android 禁明文 (pull_request) Successful in 21s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (pull_request) Successful in 24s
ci-pangolin / Flutter — analyze + test (pull_request) Failing after 21s
ci-pangolin / Codegen Drift — token 生成物未漂移 (pull_request) Successful in 10s
ci-pangolin / DS-flow — 原型/跨端同源/代码色单源闸 (pull_request) Successful in 8s
ci-pangolin / Go — build + test (pull_request) Successful in 10s
Deploy Site / deploy-site (push) Successful in 2m33s
ci-pangolin / Go — integration (mysql/redis testcontainers) (pull_request) Failing after 4m33s
ci-pangolin / Golden — 视觉回归 (全量:components/auth/desktop/tablet) (pull_request) Successful in 19s
ci-pangolin / E2E Smoke — L4 进程级端到端 (pull_request) Failing after 13m16s
#1 官网语言下拉漂移:根因=官网 CSP 无 unsafe-inline,Header.jsx 下拉全用内联
style= 被浏览器拦→菜单飘视口右边。修:搬进 website.css 的 .langwrap/.langsel
/.langmenu/.langmenu a(全走 var(--token),right:0 锚按钮下方,min-width 160
加宽),Header.jsx 删净内联 style。

#2 主页登录态右上角「用户中心」按钮:Header.jsx 读同源 localStorage
'pg_uc_refresh',有则 .linklogin 位显「用户中心」(→ /user/)、无则「Log in」。
i18n nav.center 6 语言。

#3 用户中心「返回主页」按钮:UserCenter.tsx 顶栏加 <a href="/">(home 图标),
i18n backHome 6 语言。

顺带堵同源闸漏洞:check-l1-sync ③ 原只匹配带引号图标键('refresh-cw'),漏了
裸标识符键(home),导致新加的 home 未被校验就通过。修解析器匹配裸键;并按
ds-flow 把 home 登记进 design/prototype/icons.js。同源闸复跑绿(裸键现全受检)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 09:16:13 +08:00
wangjia 14a9836882 feat(ds-flow): Phase 5.1-5.2 — Flutter 裸色闸 + 原型校验闸
5.1 client/tool/check_ds_code.mjs(照 jiu):禁 Flutter 业务代码裸 Color(0x)/
具名 Colors.x;豁免 token 生成层(pangolin_tokens.gen.dart)+ 实现层
(pangolin_theme.dart);--changed(pre-commit)/--strict(CI)/全量三模式;
剥行尾注释防误报。现状 --strict 通过(0 违规,UI 层零裸色)。

5.2 design/prototype/tools/check-ds.mjs:原型单源守门,5 道——硬编码色(仅严格
扫 atoms.css)/未定义 token/font-family 走 var(--font*)/图标走 icons.js sprite/
组件原子在 index.html 登记;剥 CSS+HTML 注释防误报,SVG fill/stroke 豁免。
现状通过(serve.mjs 改动时自动跑)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 01:39:44 +08:00
wangjia 39324c46a7 feat(ds-flow): Phase 3 — Web 硬编码色清零 + 原子台账收敛
「各自实现 + 同源闸」决策落地(不建跨端组件包):

- website.css 页脚恒暗区灰阶就近吸附主题无关 sand 原色阶(cfc6b8→sand-300、
  a89e8e→sand-400、8a8070→sand-500),消除 5 处硬编码。
- check-l1-sync 白名单加品牌 logo 色 f4efe8(Brand.astro 内联 SVG fill)。
- usercenter 13 处硬编码全为 #fff(白名单),已干净。
- CONTRACT.md 增「§6 ds-flow Web 原子清单 + 屏级三态台账」:公用原子两端映射表、
  图标三端⊆原型、L2 屏级三态(Flutter 快照/Web 代码先行/原子层同步)、硬编码白名单。

同源闸 4 道全绿(token 值 · 图标⊆原型 · Web 无硬编码色 · 幂等零 diff)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 01:09:16 +08:00
wangjia f69696daae feat(ds-flow): Phase 2 — Web token 同源闸 check-l1-sync.mjs
tools/check-l1-sync.mjs:L1 跨端同源闸(纯 Node 零依赖),4 道:
① website tokens.gen.css token 值 ≡ 原型 tokens.css(:root+dark)
② usercenter public/colors_and_type.css 同上
③ 三端图标 ⊆ 原型 icons.js sprite(usercenter LUCIDE 键+路径、Flutter
   _byName 键)
④ Web 硬编码色扫描(白名单 #fff/#000+品牌 logo 色,ds-allow 行内豁免,
   排除生成的 token 定义文件)

现状:①②③ 全过(Web token 与原型一致、Web token 幂等零 diff、图标已收敛);
补原型 icons.js 的 'chart' 别名(Flutter barChart 用,先登记原型)。
④ 余 6 处 website.css 页脚灰阶/Brand.astro 近白 —— Phase 3 清理 worklist。
CI 接线见 Phase 5。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 01:03:36 +08:00
wangjia 83fce75c8c docs(ds-flow): Phase 1.6-1.7 — ui_kits 标 DEPRECATED + 真源指针收敛
用户定:ui_kits 暂留(整屏布局尚无 HTML 替代,重建属 L3 不在本轮),标废弃
不删。

- design/CLAUDE.md:顶部加「真源对照」横幅(令牌→prototype/tokens.css、原子
  →atoms.css+index.html、图标→icons.js、Flutter→client/lib/widgets、Web→
  web/*;colors_and_type.css 降级别名、design/flutter 已删、ui_kits DEPRECATED、
  _ds_manifest/_ds_bundle 历史派生物);§6「修改设计系统时」重写为 ds-flow 流程。
- design/ui_kits/DEPRECATED.md:醒目废弃标记 + 真源指引 + 暂留理由。
- 1.7:确认无构建/CI 消费 _ds_manifest/_ds_bundle/_adherence,登记职责交
  index.html,旧工具产物标历史派生物(不删,无消费者)。

Phase 1(原型单源三件套)完成。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:59:26 +08:00
wangjia ad845328fb feat(ds-flow): Phase 1.5 — 原型活登记页 index.html
design/prototype/index.html:设计系统组件登记簿(照 jiu 骨架,light/dark 双主题)。
顶栏主题切换(持久化 localStorage)+ 左侧 dnav scrollspy 导航 + 分区:
① 色板(clay/sand 色阶 + 语义 token,data-swatches 声明式随主题刷新)
② 字号梯度(display-xl→caption,中英分行不并排)
③ 圆角/间距/阴影比例尺
④ 公用组件(atoms.css 每个 class 一张展示卡,全变体全态含 disabled)
⑤ 图标库(icons.js 全 57 图标网格)

链 tokens.css + atoms.css + icons.js(相对路径,自包含)。
验证:每个 atom 类均登记、57 图标全展示、主题切换正常、文案脱敏无红线词。
评审:node design/prototype/serve.mjs → http://localhost:5180/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:16:47 +08:00
wangjia 6def3edaed feat(ds-flow): Phase 1.4 — 原型图标 SVG sprite 单源 icons.js
design/prototype/icons.js:57 个 Lucide 图标的 SVG sprite 单源(零依赖,注入
隐藏 <svg> + <symbol id="i-*">,用法 <svg class="ic"><use href="#i-power"/>)。

路径全部来自权威来源、零手写:35 个取自 usercenter icons.tsx 内联路径、
22 个从 web/website/node_modules/lucide-react 包提取。覆盖三处并集
(usercenter 全键 ∪ Flutter pangolin_icons.dart ∪ website lucide 用量);
别名(loader-circle/chart-no-axes-column/play-circle/more-vertical 等)已解析。

供 Phase 2 check-l1-sync ③「三端图标 ⊆ 原型 sprite」同源闸校验。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:10:57 +08:00
wangjia 56f673791e feat(ds-flow): Phase 1.3 — 原型公用组件原子层 atoms.css
design/prototype/atoms.css:把分散在 preview 规格 / usercenter shared.tsx /
website css / Flutter widgets 的组件样式沉淀成 canonical 原子类,只引
var(--token)。含 .btn(primary/ghost/subtle/danger + 尺寸)、.card、.input
/.field、.pill/.badge(success/warning/danger/neutral 状态 + accent/outline)、
.langsel/.menu(对齐刚统一的自控语言下拉)。

明暗双主题靠语义 token 自动适配,文件内无 [data-theme] 分支。
验证:零硬编码色;45 个 token 引用全部在 prototype/tokens.css 有定义。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:04:52 +08:00
wangjia 805bf8e2ca feat(ds-flow): Phase 1.1-1.2 — 原型单源目录 + tokens.css 迁为真源
- design/prototype/serve.mjs:零依赖热重载预览服务器(照搬 jiu,check-ds
  存在性守护,Phase 5 前静默跳过)
- design/prototype/tokens.css:token 真源(现结构已满足 ds-flow 的
  base :root + [data-theme=dark],字节迁移保证 codegen 零 diff)
- design/colors_and_type.css:退化为薄 @import 别名(供历史 preview/*.html
  浏览器内引用;codegen 不再读它)
- 三个 codegen(Flutter gen_flutter_tokens / website+usercenter build-tokens)
  + drift 检查全部重指向 prototype/tokens.css
- 生成产物 diff 仅头注释源路径行,token 数值零变化(已验证)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:00:38 +08:00
wangjia 277d1c6e97 feat(client): toast 限定主显示区/自适应宽/上限80%/超长多行居中(1.0.26)
按真相源新规:toast 改为自定义 Overlay 实现(widgets/pangolin_toast.dart),完全控制布局——
不覆盖左侧栏(left=侧栏宽 desktop204/tablet232/mobile0)、宽度自适应内容上限主区80%、超长文本
多行、主区内水平居中贴底、淡入轻起;仍走语义 token 明暗适配。自动连接改用 showPangolinToast。
同步 design/CONTRACT.md §2 toast 规格(canonical=showPangolinToast)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 19:50:33 +08:00
wangjia 143104b861 docs(design): toast 规格入真相源 + 铁律14「UI 组件必须取自真相源」
- design/CLAUDE.md §1 加铁律 14:新增/改 UI 组件必须用真相源已定义的组件与令牌;
  真相源没有的先补规格再用,绝不在业务代码凭空造样式(如 Material 默认外观);须符合当前设计。
- design/CONTRACT.md §2 加 Toast/SnackBar 组件规格(surface 底/fg1 字/border 描边/md 圆角/floating,
  明暗自动适配),canonical 实现=pangolin_theme snackBarTheme。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 19:43:54 +08:00
wangjia b98ad9dce4 chore(design): stats-overhaul 设计 WIP — CONTRACT + ui_kits 统计页规格
stats-overhaul 的设计稿(CONTRACT.md + mobile/tablet/desktop ui_kits)。

注:这批 ui_kits 描述的是统计页「上聚合·下分设备」原方案;统计页后续已
重设计为「月/周/日 周期卡 + 设备下拉 + 两周折线」(见 client/lib/screens/
stats_page.dart)。设计稿与新页布局有出入,待更新到新布局(单列 TODO 跟踪)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 18:13:49 +08:00
wangjia e25649cd27 feat(client/ios): iPad tablet 正式适配——断点≥900 对齐设计源 + tablet golden 回归闸
- form_factor 触屏 tablet 阈值 600→900,对齐 design/ui_kits/tablet(1180×820 横屏
  侧栏):iPad 横屏/12.9″竖屏走侧栏,标准/11″竖屏回落 mobile 底 Tab,避免双栏挤压
- form_factor_test 补全断点边界(900/899)与各 iPad 尺寸用例
- 新增 tablet_pages_golden_test:四视图×明暗×中英 12 张 golden,注入演示数据
  (6 节点/周流量/30 天用量)让 2 列网格与周柱满渲染,作回归闸
- design/CONTRACT.md:tablet 像素契约(取自 tabapp.jsx)+ 逐屏验收清单
- 真机 iPad mini 6 视觉签核通过;141 测试全绿

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 10:00:14 +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 b2cb20be47 chore(design): 删除 design/flutter fork,更新 .gitignore
删除 design/flutter/(21 个文件):
- Flutter token/组件的 canonical 实现已在 client/lib/
- Token 数值层改由 design/codegen/gen_flutter_tokens.mjs codegen
- 设计规格由 design/preview/ specimens + SKILL.md 表达

.gitignore 新增:
- client/android/local.properties、client/android/app/src/main/java/
- client/ios/Flutter/ephemeral/、client/pubspec.lock
- .claude/worktrees/(临时工作目录)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:11:01 +08:00
wangjia b04cef3cc4 chore(design): 建立 token 单源管线,删除 design/flutter fork
- 新增 design/codegen/gen_flutter_tokens.mjs:
  从 colors_and_type.css codegen 出 client/lib/pangolin_tokens.gen.dart
  覆盖 PangolinColors/Spacing/Radius/Motion/Shadow(纯数值层)
- 重构 client/lib/pangolin_theme.dart:
  删除手抄数值,import+export pangolin_tokens.gen.dart
  保留实现层 PangolinScheme/PangolinText/PangolinTheme/PangolinContext
  19 个引用方零改动,对外 API 完全不变
- 新增 web/usercenter/scripts/build-tokens.mjs:
  仿 website 样板,prebuild/predev 自动从 css 生成 public/colors_and_type.css
  去除 usercenter 手抄副本的漂移风险
- 更新 CLAUDE.md:补 token codegen 使用说明与单源模型
- 更新 design/SKILL.md:移除已删 flutter/ 引用,补 codegen 入口

验证:改 clay-500 → 三端 codegen 同步变化;flutter analyze 无新增 error。
注:design/flutter/ fork 手动删除(git rm 需用户执行)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:27:22 +08:00
wangjia d88c1ae647 merge: maestro/tsk_x7wrlA87orsY [devices + 订阅校验中间件] (tsk_VRzw-af__qWx)
手动合并 tsk_x7wrlA87orsY(设备管理 + 订阅校验中间件)到 main:

冲突解决:
- server/internal/apierr/apierr.go:保留 tsk_GXDoc3Cs07Rn 版本(New/StatusFor/
  Middleware/ErrConflict/改善文档),并入 tsk_x7wrlA87orsY 新增的 ErrAccountBanned
  及对应 StatusFor case(→ 403)。

新增文件(来自 tsk_x7wrlA87orsY):
- server/internal/devices/doc.go       package 文档(替换占位 stub)
- server/internal/devices/context.go   CtxKeyUserID / Plan / WithPlan / PlanFromCtx
- server/internal/devices/handler.go   GET /v1/me/devices · DELETE /v1/me/devices/{id}
- server/internal/devices/middleware.go SubscriptionMiddleware · CheckDeviceQuota · RequirePaidTier
- server/internal/devices/service.go   RegisterIfAbsent / DeleteDevice / ResolvePlan + 纯函数 resolveEffectivePlan
- server/internal/devices/store.go     MySQL 数据访问层
- server/internal/devices/service_test.go          15 个单测(全通过)
- server/internal/devices/devices_integration_test.go  testcontainers 集成测试

OpenAPI 更新(来自 tsk_x7wrlA87orsY):
- server/api/openapi.yaml:SubscriptionInfo.source 枚举补 free
- design/server/openapi.yaml:SubscriptionInfo.source 枚举补 admin, free

测试:go build ./... ✓;go test ./internal/apierr/... ✓(8 tests);
      go test ./internal/devices/... ✓(15 tests)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 15:09:51 +08:00
wangjia 37b18d4293 merge: maestro/tsk_9uMrd9kUpmVA [tsk_9uMrd9kUpmVA] 数据面定稿 + 修订 ARCHITECTURE.md connect 契约 2026-06-13 02:57:25 +08:00
wangjia ab2bbaf683 tsk_9uMrd9kUpmVA: 数据面定稿 + 修订 ARCHITECTURE.md connect 契约
决策:libbox 统一承载 REALITY/Hy2 outbound(方案 C),弃用 WireGuard peer 注册。
现网 deploy/ 基础设施(singbox Hy2 + xray REALITY)已验证,零改动复用。

变更文件:
- design/server/ARCHITECTURE.md v0.2:
  · §0 数据面描述改为 sing-box libbox (REALITY/Hy2)
  · §1 拓扑图更新(wireguard+agent → singbox+agent,客户端标注 libbox 内嵌)
  · §2 devices 表移除 pubkey;nodes 表改为 reality_public_key/short_id/uuid/hy2_password
  · §3 connect 响应由 WireGuard 配置改为完整 sing-box config JSON
  · §3.1(新增)connect 契约详细规范:四块 inbounds/outbounds/route/dns、
    客户端透传原则、字段与 deploy/ 模板逐字段对照、占位符替换说明
  · §4.3 连接流程更新(peer 注册 → config JSON 渲染下发)
  · 附录 A(新增)v0.1→v0.2 变更汇总
- doc/plans/11-libbox-bridge.md(新建):
  完整决策记录(背景/备选/结论/影响面),任务链 11A→11C→11D/E/F→11H
- doc/plans/client-connect-config.example.json(新建):
  最小示例 config,字段与 deploy/ 模板对齐,可用 sing-box check -c 校验

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 01:43:17 +08:00
wangjia c92cd11cc5 feat: CI 流水线 — lint + 单测 + OpenAPI 校验 + 脱敏扫描 + 镜像构建 [tsk_P5b5nIrEsfrV]
新增 .gitea/workflows/ci.yml 五个 Job:
  1. lint        — shellcheck -S warning 扫描全部 deploy/ shell 脚本
  2. unit-test   — docker-compose config 语法校验 + nginx -t(桩证书)
  3. openapi-check — openapi-spec-validator 验证 design/server/openapi.yaml
  4. redline-scan  — ci/scan-redline.sh 扫描 UI 文案红线词(design/ jsx/dart/html)
  5. image-build   — docker build pangolin-edge:ci

附带:
  - ci/scan-redline.sh:脱敏扫描脚本,过滤注释行与外部渠道 handle
  - ci/nginx-test.sh:自签桩证书 + nginx -t,CI 免依赖真实 Let's Encrypt
  - design/server/openapi.yaml:依据 ARCHITECTURE.md §3 展开的 OAS 3.0 完整契约
  - dparts.jsx / parts.jsx:修复 killSwitchSub EN 文案「the VPN drops」红线词
    → 改为「connection drops」(行为描述,不提产品类别)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 01:19:28 +08:00
wangjia a642bf16a2 feat: 同步 design/ 设计系统(含 iPad tablet kit) + 架构任务拆分(todo/)
design/ 同步自最新设计导出,新增 ui_kits/tablet/ 平板分栏布局;todo/ 录入 18 个并行实施任务。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:57:57 +08:00