Commit Graph

526 Commits

Author SHA1 Message Date
wangjia c723bdd53e feat(client/update): 启动自动检查 + App 内下载安装(不走浏览器)
Deploy Client / build-windows (push) Successful in 2m2s
Deploy Client / build-android (push) Successful in 2m13s
Deploy Client / build-macos (push) Successful in 3m45s
Deploy Client / build-ios (push) Successful in 3m58s
Deploy Client / release-deploy (push) Successful in 2m1s
参照 jiu 补齐,但比 jiu 多做了 Android 原生安装(jiu 的 App 内下载仅 Win/mac):
- 启动自动检查:update_provider 改 AsyncNotifier,build() 延迟 3s 首查 + 每小时
  轮询;home_shell watch 拉起、listen 弹更新框;_dismissed 防反复弹(轮询重置);
  强制更新走不可关闭弹窗。设置页「检查更新」改 forceCheck()。
- App 内下载(core/update/app_updater.dart,http 流式带进度框,不再 launchUrl):
  · Android:下 APK → open_filex 拉起系统安装器(+ REQUEST_INSTALL_PACKAGES)
  · Windows:下 exe → Process.start(detached) → exit(0) 覆盖安装
  · macOS :下 zip → open 解压 + 访达显示,提示手动拖入(带系统扩展不自动 swap)
  · iOS   :降级外链(TestFlight/App Store)
  失败降级浏览器下载。新增 6 语更新进度/失败/提示文案。
- 依赖 open_filex;flutter analyze 仅 2 个既有 withOpacity info。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.61
2026-07-07 17:09:29 +08:00
wangjia 617b43083d feat(client/i18n): B1 硬编码文案 6 语化 + B2 语言持久化
B2 持久化:localeProvider 由 StateProvider 改 StateNotifier(LocaleNotifier),
默认英文,选择存 shared_preferences(key pg_lang),重启保留;新增 appTextFor(lang)
helper 供非 Consumer 场景复用。两处切换 .state= 改 .set()。

B1 硬编码 UI 文案 6 语化(AppLangMisc 扩展,exhaustive switch 不会漏):
- 不可用 / 流媒体优化 / 节点未就绪 / 连接失败 / 加载失败 / 暂无设备 / 改邮箱
- 相对时间(刚刚/X分钟前/…)relativeTime(Duration)
- 修 auth_screen 错误消息 bug:原 _errorZh 永远显示中文(连英文用户都中招)→
  按当前语言取 messageZh/En(非中文显英文)

仍回退英文(服务端数据,需服务端多语字段):节点/套餐名(nameZh/nameEn)、
API 错误消息(messageZh/En)。flutter analyze 仅 2 个既有 withOpacity info。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 14:32:13 +08:00
wangjia f9a87a9993 ci(site): deploy-site 增补用户中心构建+部署(补 CI 缺口)
Deploy Site / deploy-site (push) Successful in 3m42s
用户中心此前无 CI 部署(手动 wrangler),漂移风险。现纳入 site-v* 发版:
- scripts/ci/compile-usercenter.sh:next build → out/,⚠️内置 NEXT_PUBLIC_API_MODE=http
  + NEXT_PUBLIC_API_DOMAINS=https://api.yanmeiai.com(不设默认 mock=假数据,是个坑)
- scripts/ci/deploy-usercenter.sh:wrangler pages deploy → pangolin-usercenter
  (app.yanmeiai.com)
- deploy-site.yml 追加两步,官网+用户中心同一 tag 发,CF token/account 走全局 secret

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
site-v0.0.6
2026-07-07 13:37:31 +08:00
wangjia 8c14913275 feat(usercenter/i18n): 6 语(加 日/韩/俄/西)+ 默认英文
Deploy Site / deploy-site (push) Successful in 1m45s
Deploy Client / build-windows (push) Successful in 1m58s
Deploy Client / build-android (push) Successful in 2m10s
Deploy Client / build-macos (push) Successful in 4m2s
Deploy Client / build-ios (push) Successful in 3m40s
Deploy Client / release-deploy (push) Successful in 2m2s
- lib/i18n.ts: Lang/Entry 扩 6 语;STRINGS 130 条补 ja/ko/ru/es;makeT 回退英文
- lib/api/errors.ts: ERROR_TEXT 14 条补 4 语;bilingual 改为 code 本地字典优先
  → 英文字典 → 后端 message → 通用兜底
- lib/theme.tsx: 默认语种 zh→en;localStorage 白名单扩 6 语;setAttribute('lang') 直用 lang
- components/shared.tsx: LangSeg 段控 → 原生 select 6 语下拉
- app/layout.tsx: 默认壳 html lang zh→en;title/desc 改英文
- next build 通过(5 页静态);tsc 干净;无红线词

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.60 site-v0.0.5
2026-07-07 13:31:38 +08:00
wangjia f0d574bc44 feat(website/i18n): 6 语(加 日/韩/俄/西)+ 默认英文
- strings.ts: [zh,en] 二元组 → Record<Lang,string> 六语对象(157 条,ja/ko/ru/es
  据英文翻译,无红线词,scan-redline 过);createT 回退英文;PRICES 补 4 语(复用
  USD 价)
- 路由:默认英文移到 /(原 zh);中文挪 /zh/;新增 /ja//ko//ru//es/;删冗余 /en/
- Site.astro:html lang / canonical / hreflang(6+x-default)/ og:locale 全部改
  为按语言查表(HTML_LANG/OG_LOCALE/langPath)
- Header.jsx:langseg 2 项 → 原生 select 6 语下拉(横排会挤);+ .langsel 样式
- astro build 通过,6 页生成;/ 英文、/zh/ 中文、/ja/ 日语标题均已本地化

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 13:29:35 +08:00
wangjia 3aeb2a8680 feat(client/i18n): 新增 日/韩/俄/西 4 语,默认语种改英文
- AppLang enum 扩为 zh/en/ja/ko/ru/es;新增 strings_{ja,ko,ru,es}.dart
  (各 161 条,照 strings_en.dart 结构逐条翻译,无红线词,scan-redline 过)
- app_providers: localeProvider 默认 AppLang.en(国际化默认);appTextProvider
  三元改 switch 全覆盖 6 语
- AppLang.nativeLabel 扩展(各语言本地名);settings/account 两处 _LangSwitch
  段控改下拉(6 语横排会挤)
- flutter analyze lib 仅剩 2 个既有 withOpacity deprecation info

注:节点/套餐名、错误消息等 ~11 处数据驱动的 zh/en 三元暂回退 en(非崩溃,
后续可扩多语字段)。localeProvider 暂无持久化(沿用原设计,后续可加)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 13:20:16 +08:00
wangjia c3b64e8d0f feat(website): 下载页接入 macOS(.zip)按钮
Deploy Site / deploy-site (push) Successful in 1m22s
macOS 自 client-v1.0.59 起由 CI 产出 pangolin-macos-x64.zip 并部署到
/downloads,官网下载页 macOS 卡片从禁用占位改为真实下载直链;iOS 走
TestFlight 无直链、Linux 未接入,保持禁用。astro build 通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
site-v0.0.4
2026-07-07 11:56:21 +08:00
wangjia 7794c73a51 chore(manifest): version.yaml 补 macOS 下载直链(macOS 已随 1.0.59 产出)
build-macos 自 client-v1.0.59 起产出 pangolin-macos-x64.zip 并部署到
pangolin1:/downloads,故 download_urls.macos 填稳定直链,自动更新/下载页可
引导 macOS 用户;ios 走 TestFlight 无直链保持留空。下次 client-v* 发版时
release-client.sh 会把此 manifest 推到线上生效。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 11:42:14 +08:00
wangjia 6ce67176da fix(ci/macos): 构建后从 WORK 目录 embed 描述文件(xcodebuild 会清 PROF_DIR)
Deploy Client / build-android (push) Successful in 1m39s
Deploy Client / build-windows (push) Successful in 1m53s
Deploy Client / build-macos (push) Successful in 3m43s
Deploy Client / build-ios (push) Successful in 3m5s
Deploy Client / release-deploy (push) Successful in 2m7s
build-macos 失败:flutter build macos 期间 xcodebuild 修剪
~/Library/Developer/Xcode/UserData/Provisioning Profiles,把构建前装进去的
Developer ID 描述文件删掉,构建后 inside-out 重签时从该目录 cp 扑空
(cp: <uuid>.provisionprofile: No such file → exit 1)。改为从 mktemp 的 WORK
目录复制原始 .provisionprofile(xcodebuild 不碰),幂等可靠。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.59
2026-07-07 11:27:50 +08:00
wangjia 48e7efe92a ci(client): mac/iOS 证书 env 映射到全局通用短名密钥
Deploy Client / build-android (push) Successful in 1m52s
Deploy Client / build-windows (push) Successful in 1m57s
Deploy Client / build-macos (push) Failing after 1m53s
Deploy Client / build-ios (push) Successful in 6m3s
Deploy Client / release-deploy (push) Successful in 1m23s
Apple 证书/公证密钥是账号级、跨项目唯一 → 放全局(用户级)密钥用通用短名
(DEVELOPER_ID_P12/P12_PASSWORD/IOS_DIST_P12/IOS_DIST_PASSWORD/APPSTORE_*),
workflow env 里把脚本期望的长名映射过去,脚本不动。描述文件(与 bundle id 绑定)
仍走项目级。修此前 build-macos/ios 因密钥名对不上取不到证书。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.58
2026-07-07 08:14:10 +08:00
wangjia 6756cea413 ci: deploy-client concurrency cancel-in-progress true(新版取消僵尸旧 run)
Deploy Client / build-android (push) Successful in 1m37s
Deploy Client / build-macos (push) Failing after 3s
Deploy Client / build-ios (push) Successful in 3s
Deploy Client / release-deploy (push) Successful in 1m1s
Deploy Client / build-windows (push) Successful in 1m57s
client-v1.0.57
2026-07-07 01:07:00 +08:00
wangjia d4c9bb7d18 fix(ci): release-deploy 只 needs build-android(windows/macos/ios best-effort)
windows 机离线时 build-windows 无限排队会拖挂整条发版。改 release-deploy 只依赖
build-android(平台 floor),其余平台就绪则并入,不就绪不阻塞——对应平台下载保留上一版。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 01:06:05 +08:00
wangjia b072cf448d fix(client/android): 强制 androidx.core/browser 兼容 AGP 8.6(url_launcher 拉入 1.17/1.9 要 AGP 8.9.1)
Deploy Client / build-android (push) Successful in 1m38s
Deploy Client / build-macos (push) Failing after 2s
Deploy Client / build-ios (push) Successful in 3s
Deploy Client / build-windows (push) Has been cancelled
Deploy Client / release-deploy (push) Has been cancelled
client-v1.0.55 build-android 挂在 checkReleaseAarMetadata:url_launcher_android 拉入的
androidx.core:1.17 / androidx.browser:1.9 要求 AGP 8.9.1+,本项目 AGP 8.6。force 到
1.13.1/1.8.0(打开 URL 用不到新 API)。本地 apk 构建已验证通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.56
2026-07-07 00:25:04 +08:00
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
client-v1.0.55
2026-07-07 00:20:00 +08:00
wangjia 6277e86d0f feat(client): SSO 用户中心按钮 + 自动更新检查(镜像 jiu)
Deploy Server / deploy-server (push) Successful in 2m56s
SSO: web_launch.openWebUserCenter → POST /v1/auth/web-ticket → 打开 app.yanmeiai.com/sso?t=…;
设置页加「用户中心(网页)」入口。自动更新: update_provider 查 /version 语义比对 + update_dialog
「发现新版本」;设置页「检查更新」由空 onTap 接上。加 url_launcher(原缺)。flutter analyze 通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
server-v1.0.4
2026-07-07 00:13:50 +08:00
wangjia 4baf24f6f8 feat(server): 自动更新 /version 清单端点(镜像 jiu)
GET /version(公开)读 /etc/pangolin/version.yaml(每请求重载,免重启);缺省回退。
download_urls 接 /downloads。deploy.sh 装清单(存在则不覆盖, 保住线上 bump)。含 4 测试。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-07 00:12:46 +08:00
wangjia ec0942e1e7 feat(usercenter): SSO /sso 落地页(拿票兑会话→自动登录)
Deploy Server / deploy-server (push) Successful in 2m47s
App 打开 app.yanmeiai.com/sso?t=<ticket>&redirect=<路径>;本页 exchangeWebTicket→setSession
(与正常登录同路径)→跳白名单相对路径。镜像 jiu sso.njk。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
server-v1.0.3
2026-07-07 00:02:48 +08:00
wangjia 1e13f35219 feat(server): SSO 换票端点(App→Web 免登握手)
/v1/auth/web-ticket(需登录):签发一次性票据(crypto/rand 32B, Redis GETDEL 单用, 60s)。
/v1/auth/web-ticket/exchange(公开):票换与 /auth/login 同款 token pair。镜像 jiu。含 6 测试。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 23:54:15 +08:00
wangjia e4de308ba4 fix(usercenter): 首屏直接渲染登录页(修"空白")+ html suppressHydrationWarning
静态导出下 !ready 原来渲染空白背景 div,慢网络首屏看着是空的。改为 !ready||!authed
一律渲染 Login(静态无会话默认态),SSG 首屏即登录表单。html 加 suppressHydrationWarning
消除主题 data-theme 的 hydration 警告(#418)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 23:40:24 +08:00
wangjia 97caae95b8 feat(web): 官网 Windows 下载按钮上线(client CI 已产出 exe)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 23:12:57 +08:00
wangjia 4561ee4cc3 fix(ci): fetch-desktop-bin curl 加固(windows 外网 GFW 抖动)
Deploy Client / build-android (push) Successful in 1m58s
Deploy Client / build-windows (push) Successful in 6m51s
Deploy Client / release-deploy (push) Successful in 1m13s
wintun.net / github 下载偶发超时(curl 28)。retry 3→8、加 --retry-all-errors
+ --retry-connrefused + --connect-timeout 20,拉长重试窗口以命中可达时刻。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.53 client-v1.0.54
2026-07-06 22:56:20 +08:00
wangjia a53bbe743e fix(ci): release-deploy 合并为单次 download-artifact + flatten
Deploy Client / build-android (push) Successful in 1m33s
Deploy Client / build-windows (push) Failing after 8m7s
Deploy Client / release-deploy (push) Has been skipped
首次 windows release-deploy 失败:两次 download-artifact 复用致 act 对只读缓存
action(pack idx 444)EACCES。改一次性下全部 artifact(dist-raw/)再 flatten 到 dist/。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.52
2026-07-06 22:44:17 +08:00
wangjia 7b1f49c182 fix(ci): compile-windows 传 ISCC 用 Windows 路径(cygpath)
Deploy Client / build-android (push) Successful in 1m38s
Deploy Client / build-windows (push) Successful in 8m29s
Deploy Client / release-deploy (push) Failing after 6s
首个 Windows CI 失败:ISCC 'Unknown option: /c/pangolin-build/.../pangolin.iss'——
ISCC 是原生 Windows 程序,MSYS /c/... 路径被当成选项。用 cygpath 转 C:\... 再传。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.51
2026-07-06 22:31:40 +08:00
wangjia 8c8486f9af fix(ci): deploy-client 用 env 传 REF_NAME(防 Actions 注入)+ job.status 同法
Deploy Client / build-android (push) Successful in 1m38s
Deploy Client / build-windows (push) Failing after 6m27s
Deploy Client / release-deploy (push) Has been skipped
安全审查:run: 里内联 ${{ gitea.ref_name }} 有注入风险(恶意 tag 名);改经 env REF_NAME
+ 引用 "$REF_NAME"(同 deploy-server.yml 的 TAG 做法)。notify 的 job.status 同法。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.50
2026-07-06 22:22:00 +08:00
wangjia 7d0f4c8065 ci: 恢复 build-windows job(windows-runner 已提级 user 级)
Deploy Client / build-windows (push) Failing after 20s
Deploy Client / build-android (push) Successful in 1m40s
Deploy Client / release-deploy (push) Has been skipped
runs-on: windows;release-deploy needs [build-android, build-windows] + 下载 windows artifact。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.49
2026-07-06 22:15:06 +08:00
wangjia 3d521973ab feat(server): CORS 中间件(Web 用户中心跨域调 /v1/*)
Deploy Server / deploy-server (push) Successful in 2m56s
usercenter(app.yanmeiai.com,浏览器)跨域调控制面 API 会被浏览器拦(无 CORS 头)。
加白名单 CORS 中间件(CORS_ORIGINS,缺省 app.yanmeiai.com + pages.dev),应答 OPTIONS
预检。原生端非浏览器不受影响。Bearer 认证故不需 Allow-Credentials。含 3 项测试。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
server-v1.0.2
2026-07-06 21:52:33 +08:00
wangjia cb8e4bddd8 feat(web): 官网恢复登录入口 → usercenter(app.yanmeiai.com)
usercenter(web/usercenter, Next 静态导出)已部署到 CF Pages(pangolin-usercenter,
自定义域 app.yanmeiai.com)。site.ts 加 usercenter 字段;Header 恢复 .linklogin(t.login)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 21:48:59 +08:00
wangjia 4cfe4d0ccb chore(ci): deploy-client 本轮 Android-only(暂无 windows runner, 移除 build-windows)
Deploy Client / build-android (push) Successful in 2m9s
Deploy Client / release-deploy (push) Successful in 51s
release-deploy needs 改 [build-android];windows job/下载步骤 git 历史 2698116 可恢复。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
client-v1.0.48
2026-07-06 20:51:18 +08:00
wangjia 366695ffd6 chore(web): Windows 下载按钮暂改「即将推出」(其 CI 未产出 exe;本轮仅 Android 真下载)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 19:58:18 +08:00
wangjia 2e631ed3b5 feat(server+web): 客户端下载闭环——pangolin-server /downloads + 官网下载链接
Deploy Server / deploy-server (push) Successful in 2m59s
- server: /downloads/* 公开静态服务(NewDownloadsHandler,DOWNLOADS_DIR 默认
  /var/lib/pangolin/downloads),防目录穿越/不列目录/缺目录不崩,Cache-Control:
  no-cache 保证 CI 覆盖后永远最新。挂在 /healthz 同级(免鉴权)。含 4 项测试。
- deploy.sh: install -d 下载目录 + server.env 注入 DOWNLOADS_DIR。
- web: site.ts 增 downloads.{android,windows}(→ https://api.yanmeiai.com/downloads/*);
  Download.astro 接上 Android/Windows 按钮,iOS/macOS/Linux 改「即将推出」禁用态。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
server-v1.0.1
2026-07-06 19:48:57 +08:00
wangjia 2698116696 feat(ci): 客户端 CI 脚手架(Android+Windows, 照 jiu)——起草+Android 本地验证
- compile-android.sh: 建 libbox.aar + split-per-abi 取 arm64-v8a(~82MB, 避 232MB
  universal) + release 签名(RELEASE_KEYSTORE/KEY_PASSWORD)。本地已验证构建通过、
  libbox.so 打进 APK。
- compile-windows.sh: 复用 client/windows/installer/pangolin.iss(Inno Setup),不签名。
- release-client.sh / deploy-client.sh: 复用 pangolin lib-forgejo/lib-ssh,传 Gitea
  release + 部署最新到 pangolin1:/var/lib/pangolin/downloads(仅留最新)。
- deploy-client.yml: client-v* tag → build-android(mac)+build-windows(windows) → release-deploy(mac)。
- build.gradle: 补 release 签名 config(读 key.properties, 缺则回退 debug)。
- 待确认: keystore alias/密码(见脚本 TODO);runner 需提到 user 级;服务器 /downloads + 官网链接下一步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 19:40:34 +08:00
wangjia 973c2c021b fix(ci): 网络操作加超时(runner 长任务 ~14min 无日志崩溃 → 快失败可诊断)
Deploy Server / deploy-server (push) Successful in 3m24s
Setup Go 下载 + Forgejo GET/create/upload 的 curl 原本无 --max-time,网络停顿即
无限挂起(疑似 runner 长任务崩溃且不留日志的根因)。加 --max-time(+GET/下载 retry),
让停顿在超时内快失败并留下日志,而非静默 14 分钟后崩。POST 不 retry(避免重复建/传)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
server-v1.0.0
2026-07-06 18:43:59 +08:00
wangjia f1950ffb6f fix(ci): release-server 首次实跑修复 + go 工具链 sha256 pin
Deploy Server / deploy-server (push) Failing after 13m45s
- lib-forgejo/release-server: 5 处 read -r X < file 在 set -e 下遇无结尾换行的
  EOF 会返回 1 静默中止(ver_from_tag printf 无换行、curl -w http_code 无换行);
  逐处加 || true 容错(值已赋)。
- lib-forgejo: 空数组 ${FORGEJO_CURL_TLS[@]} 在 set -u 下老 bash 报 unbound;
  改 empty-safe 展开(可移植 + 本地可测)。
- deploy-server.yml: Setup Go 加 sha256 校验(供应链完整性, 防镜像篡改注入工具链)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 18:04:51 +08:00
wangjia 8850c94e96 fix(ci): deploy-server 先装 go(runner 无 go → compile exit 127)
Deploy Server / deploy-server (push) Failing after 2m16s
catthehacker ubuntu:act-latest 自带 node 不带 go;直接 go build 报 command not found。
加 Setup Go 步骤从 golang.google.cn(CN 镜像, 避开墙内不稳的 go.dev)装 1.25.10。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 17:55:33 +08:00
wangjia 4d67a90659 fix(ci): deploy-server 隧道 healthcheck 改非致命(本地 healthz 才是权威闸)
Deploy Server / deploy-server (push) Failing after 22s
隧道 /healthz 依赖 cloudflared/CF 边缘,与本次二进制是否健康是两回事;
CF 边缘抖动或隧道尚未 provision 不应判整次部署失败。改为失败仅告警。
(最终 whole-branch review 的 Minor A 决议)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:59:52 +08:00
wangjia cccbb7b56b docs: 控制面 CF Tunnel/端口布局说明 + 方案 HTML 登记 index
CLAUDE.md 补充控制面经 Cloudflare Tunnel 对外的端口/URL 布局说明;生成
docs/control-plane-tls-tunnel.html 阅读版并登记 docs/index.html「实现计划」;
顺带修正 deploy/single-node/deploy.sh 摘要 echo 里残留的旧明文口描述(Task 4/5
落地后措辞漂移,实际已是 CF Tunnel + loopback)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:53:36 +08:00
wangjia 06ba76e22b feat(deploy): 8080 收 loopback + 关 8080 防火墙 + 健康检查改本地/隧道(退役明文控制口)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:47:32 +08:00
wangjia e2ffce90d3 feat(deploy): PANGOLIN_PUBLIC_URL 改 https://api.yanmeiai.com(客户端规则集走隧道)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:45:00 +08:00
wangjia 1b091f3be0 ci: 守护 Android manifest 禁全局明文(#25 控制面已 https)
新增 ci/scan-cleartext.sh 扫描 client/android AndroidManifest.xml,
防止将来把 usesCleartextTraffic="true" 重新加回(退回明文态)。
CI 新增 cleartext-scan job,并把该脚本纳入 lint job 的 shellcheck 覆盖
(单独挂载 ci/ 目录,不动 scripts/ci 既有挂载)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:41:59 +08:00
wangjia a5aea9438a feat(client): 控制面基址默认 https://api.yanmeiai.com + 移除 Android 明文开关
TDD: 先加守护测试(断言 kApiBaseUrl 走 https 且不含硬编码 IP),确认失败后
再改 api_config.dart 默认值 + 去掉 AndroidManifest 的 usesCleartextTraffic。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:37:42 +08:00
wangjia 9b56e2667b feat(deploy): cloudflared 出站隧道前置控制面 API(api.yanmeiai.com→127.0.0.1:8080)
deploy.sh 在 systemd 安装段新增 cloudflared 二进制(apt 源)+ unit 安装;
enable-on-boot 用 /etc/pangolin/cloudflared.env(TUNNEL_TOKEN)存在与否作
门槛,避免全新单机部署在 token 未落地前因 cloudflared 起不来而失败。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:32:32 +08:00
wangjia bac79017ae docs(plan): #25 控制面 CF Tunnel 实现方案
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:30:11 +08:00
wangjia 5c647235aa chore(todo): #25 方案 propose/approve + #32 fallback 登记
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-06 16:28:45 +08:00
wangjia f8e870fd6a fix(ci): backup 大小 sanity 阈值 50k→1k(小库压缩后 <50k 被误删)
远端 .backup 出的库 gzip 后可能 <50KB,原 >50k 检查把有效备份当'异常小'删了。
空 gzip 仅 ~20 字节,>1k 足以区分空/断流与有效备份。
2026-07-06 15:34:18 +08:00
wangjia 84b042394d ci(backup): 备份步骤输出 tee 到 NAS _last-run.log(便于排障) 2026-07-06 15:32:10 +08:00
wangjia e557a94ed0 fix(ci): lib-ssh 加 IdentitiesOnly+BatchMode(修 Too many auth failures)
CI ssh 到 pangolin1 报 Too many authentication failures + 回落密码提示:ssh 把
容器默认/agent key 也一并递上,撞 MaxAuthTries。加 IdentitiesOnly=yes 只用 -i key,
BatchMode=yes 纯非交互。影响 deploy-server / backup 等所有走 lib-ssh 的部署。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 15:05:44 +08:00
wangjia e1a17acbe4 feat(ci): SQLite 每日备份到 NAS(异地容灾,#26/F2)
backup-db.sh:ssh pangolin1 → sqlite3 online .backup 取 WAL 一致快照 + 远端
integrity_check → gzip 流回 → 存 NAS /volume1/docker/backups/pangolin,保留 30 天。
backup.yml:每日 02:00(北京)cron + 手动,ubuntu-latest,复用 DEPLOY_SSH_KEY,
Telegram 通知。异地=家里 NAS≠VPS 机房。不在 pangolin1 装/常驻任何东西。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 14:55:11 +08:00
wangjia 3efd67297e ci(server): 编译/测试直接在 runner 跑,去嵌套 docker(修 DinD;go 工具链自动下载)
compile-backend/test.sh 原在 golang:1.25 容器里跑,job 容器内 $PWD 在宿主不存在
→ DinD 挂载失败。改直接跑;go.mod 要求 1.25.10,靠 Go 工具链经 goproxy.cn 自动拉取。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 14:40:09 +08:00
wangjia f6e565ffdc ci(site): 官网构建/部署直接在 runner 跑,去掉嵌套 docker(修 DinD 挂载)
Deploy Site / deploy-site (push) Successful in 1m23s
job 容器内 $PWD(/workspace/...)在宿主不存在,docker run -v $PWD 挂载失败。
runner 镜像 catthehacker/ubuntu:act-latest 自带 node/npx,直接 bash 跑即可。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
site-v0.0.3
2026-07-06 14:34:12 +08:00
wangjia ba5f71b716 ci: runs-on nas → ubuntu-latest(匹配 nas runner 实际 label)
Deploy Site / deploy-site (push) Failing after 1m36s
nas 上的 forgejo-act-runner 注册 label 是 ubuntu-latest(非 nas),导致所有
runs-on: nas 的工作流无匹配 runner。改为 ubuntu-latest 对齐 runner 现状。
(备选:给 runner 加 nas 标签保约定,未采用。)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
site-v0.0.2
2026-07-06 13:33:27 +08:00