Skip to content

Commit 351ccc4

Browse files
committed
feat: merge dev with window-recognition optimization (14 commits)
2 parents ca886a1 + 515b8ec commit 351ccc4

531 files changed

Lines changed: 34973 additions & 9246 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.env.example‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ SUPABASE_JWT_SECRET=
4747
# Supabase 项目 URL(用于后端验证 JWT issuer)
4848
SUPABASE_URL=https://your-project-id.supabase.co
4949

50+
# Supabase 服务端密钥(Service Role Key,仅供服务端调用,禁止暴露给前端)
51+
SUPABASE_SERVICE_KEY=your-service-role-key
52+
53+
# Supabase JWT 签名算法(HS256/RS256/ES256)
54+
# SUPABASE_JWT_ALGORITHM=RS256
55+
5056
# 开发者白名单(AI 网关):逗号分隔的 Supabase user_id 或邮箱,
5157
# 命中的账号完全豁免平台配额(不限流/不限费用)并赋予 lifetime 最高身份,
5258
# 仅供开发者自测,切勿在生产环境加入普通用户。
@@ -56,6 +62,25 @@ SUPABASE_URL=https://your-project-id.supabase.co
5662
SYNC_SERVICE_PORT=8080
5763
AI_GATEWAY_PORT=8000
5864

65+
# AI 网关预算控制(每日 token/费用上限,0=不限制)
66+
# BUDGET_DAILY_TOKEN_LIMIT=100000
67+
# BUDGET_DAILY_COST_LIMIT=10
68+
69+
# AI 网关开发降级模式(生产环境缺密钥时拒绝启动;仅开发环境可显式开启)
70+
# GATEWAY_ALLOW_DEV_AUTH=false
71+
72+
# OpenTelemetry 导出端点(可选,配置后网关上报 trace 到 OTLP Collector)
73+
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
74+
75+
# 付费系统(面包多,可选——未配置时付费功能禁用)
76+
# PAYMENT_PROVIDER=mianbaoduo
77+
# PAYMENT_API_KEY=your-mianbaoduo-api-key
78+
# PAYMENT_API_SECRET=your-mianbaoduo-api-secret
79+
# PAYMENT_WEBHOOK_SECRET=your-webhook-secret
80+
# PAYMENT_API_BASE_URL=https://api.mianbaoduo.com
81+
# PAYMENT_TIMEOUT_MS=5000
82+
# PAYMENT_RETRY_COUNT=3
83+
5984
# --- 生产部署配置 ---
6085

6186
# CORS 允许的前端域名(多个用逗号分隔)

‎.gitattributes‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
*.png filter=lfs diff=lfs merge=lfs -text
1+
*.png filter=lfs diff=lfs merge=lfs -text

‎.github/workflows/deploy-server.yml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,32 @@ on:
1010
jobs:
1111
deploy:
1212
runs-on: ubuntu-latest
13+
timeout-minutes: 30
1314
steps:
1415
- uses: actions/checkout@v4
1516

17+
# 部署前门禁(2026-08 审计 #11):server 变更直接部署前先跑完整测试,
18+
# 防止未验证代码上线(pr-check 只在 PR 流程生效,main 直推会绕过)
19+
- name: Gate - AI Gateway tests
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: '3.12'
23+
- name: Run AI Gateway tests
24+
run: |
25+
cd server/ai-gateway
26+
pip install -r requirements.txt
27+
pip install ruff pytest pytest-asyncio httpx
28+
ruff check .
29+
pytest tests/ -q
30+
- name: Gate - Sync service tests
31+
uses: actions/setup-go@v5
32+
with:
33+
go-version: '1.25'
34+
- name: Run Sync service tests
35+
run: |
36+
cd server/sync-service
37+
go build ./... && go vet ./... && go test ./... -count=1
38+
1639
# 上传 server/ 源码到服务器(服务器非 git 仓库,代码由 CI 同步)
1740
# 注意:rm 必须为 false —— 服务器上的 .env.production 为真实生产密钥,
1841
# 不在仓库内(被 gitignore),删除目标目录会导致密钥永久丢失。

‎.github/workflows/deploy-website.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
jobs:
1111
deploy:
1212
runs-on: ubuntu-latest
13+
timeout-minutes: 30
1314
steps:
1415
# lfs: true 必需:beian.png / sponsor-qr.png 等由 Git LFS 托管(.gitattributes:
1516
# *.png filter=lfs),不拉取则为 131 字节指针文件,线上为坏图
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: Release PWA (Mobile)
2+
3+
# 由 semantic-release 创建的 v* tag 触发:构建 PWA 移动端产物并部署到
4+
# ECS 服务器(https://entropydecrease.com/pwa/)。与 release.yml(Electron
5+
# 桌面端)共用同一 v* tag——双端同版本发布、互不干扰;PR 质量验证复用
6+
# pr-check.yml(client job 已含 vite build 产出 PWA)。
7+
on:
8+
push:
9+
tags: ['v*']
10+
# 兜底触发:semantic-release 以内置 GITHUB_TOKEN 推 tag 时 GitHub 防递归
11+
# 机制不派发 push 事件(同 release.yml 注释),Release 发布事件补跑
12+
release:
13+
types: [published]
14+
# 手动兜底:在 UI 选择对应 tag 运行,用于补发历史版本
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
19+
20+
# 同一 tag 的多个触发源串行执行,避免重复部署竞争
21+
concurrency:
22+
group: release-pwa-${{ github.ref_name }}
23+
cancel-in-progress: false
24+
25+
jobs:
26+
build:
27+
runs-on: ubuntu-latest
28+
timeout-minutes: 30
29+
steps:
30+
# lfs: true 必需:pwa-192x192.png 等由 Git LFS 托管,不拉取则为指针文件
31+
- uses: actions/checkout@v4
32+
with:
33+
lfs: true
34+
- uses: actions/setup-node@v4
35+
with:
36+
node-version: 20
37+
cache: 'npm'
38+
cache-dependency-path: client/package-lock.json
39+
- run: cd client && npm ci
40+
- run: cd client && npm run lint
41+
- run: cd client && npm run test -- --run
42+
# PWA 构建(子路径 /pwa/ 部署):.env.production 已入库(git 跟踪),
43+
# 生产环境变量自动注入;VITE_PWA_BASE 控制构建 base 与 manifest
44+
# start_url/scope(vite.config.ts),保证子路径安装入口正确
45+
- name: Build PWA (base=/pwa/)
46+
env:
47+
VITE_PWA_BASE: /pwa
48+
run: cd client && npx vite build
49+
- name: Verify PWA artifacts
50+
run: |
51+
cd client
52+
test -f dist/index.html && echo "index.html OK"
53+
test -f dist/manifest.webmanifest && echo "manifest.webmanifest OK"
54+
test -f dist/sw.js && echo "sw.js OK"
55+
- uses: actions/upload-artifact@v4
56+
with:
57+
name: pwa-dist
58+
path: client/dist/
59+
retention-days: 14
60+
61+
deploy:
62+
needs: build
63+
runs-on: ubuntu-latest
64+
timeout-minutes: 15
65+
steps:
66+
- uses: actions/download-artifact@v4
67+
with:
68+
name: pwa-dist
69+
path: pwa-dist
70+
- name: Ensure PWA directory on server
71+
uses: appleboy/ssh-action@v1
72+
with:
73+
host: ${{ secrets.SERVER_HOST }}
74+
username: ${{ secrets.SERVER_USER }}
75+
key: ${{ secrets.SSH_PRIVATE_KEY }}
76+
script: mkdir -p /opt/Entropydecrease/pwa
77+
- name: Upload PWA to server (clean replace)
78+
uses: appleboy/scp-action@v0.1.7
79+
with:
80+
host: ${{ secrets.SERVER_HOST }}
81+
username: ${{ secrets.SERVER_USER }}
82+
key: ${{ secrets.SSH_PRIVATE_KEY }}
83+
source: pwa-dist/*
84+
target: /opt/Entropydecrease/pwa
85+
strip_components: 1
86+
rm: true
87+
# scp rm:true 重建目录导致 bind mount 失效,须重启 nginx 容器恢复
88+
# (同 deploy-website.yml 模式);顺带写入版本标记 + 验证部署
89+
- name: Restart Nginx, write version and verify
90+
uses: appleboy/ssh-action@v1
91+
with:
92+
host: ${{ secrets.SERVER_HOST }}
93+
username: ${{ secrets.SERVER_USER }}
94+
key: ${{ secrets.SSH_PRIVATE_KEY }}
95+
script: |
96+
echo "${{ github.ref_name }}" > /opt/Entropydecrease/pwa/version.txt
97+
docker restart entropy-decrease-nginx
98+
sleep 5
99+
curl -sf https://entropydecrease.com/pwa/ | grep -q "熵减" || exit 1
100+
echo "PWA deployed: ${{ github.ref_name }}"

‎.github/workflows/pr-check.yml‎

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ jobs:
1010
# ===========================================================================
1111
changes:
1212
runs-on: ubuntu-latest
13+
timeout-minutes: 10
1314
# dorny/paths-filter 需要读取 PR 变更文件列表;Dependabot PR 的只读 token
1415
# 默认不含该权限,显式声明后 Dependabot PR 的路径检测才能正常工作
1516
permissions:
@@ -20,6 +21,7 @@ jobs:
2021
sync-service: ${{ steps.filter.outputs.sync-service }}
2122
ai-gateway: ${{ steps.filter.outputs.ai-gateway }}
2223
website: ${{ steps.filter.outputs.website }}
24+
docs: ${{ steps.filter.outputs.docs }}
2325
steps:
2426
- uses: actions/checkout@v4
2527
- uses: dorny/paths-filter@v3
@@ -36,6 +38,10 @@ jobs:
3638
- 'server/shared/**'
3739
website:
3840
- 'website/**'
41+
docs:
42+
- 'docs/**'
43+
- 'scripts/docs-check.mjs'
44+
- '.docscheckignore'
3945
4046
# ===========================================================================
4147
# Client —— React + Vite + Electron 前端
@@ -44,6 +50,7 @@ jobs:
4450
needs: changes
4551
if: needs.changes.outputs.client == 'true'
4652
runs-on: ubuntu-latest
53+
timeout-minutes: 30
4754
steps:
4855
- uses: actions/checkout@v4
4956
- uses: actions/setup-node@v4
@@ -53,20 +60,26 @@ jobs:
5360
cache-dependency-path: client/package-lock.json
5461
- run: cd client && npm ci
5562
- name: Lint
56-
run: cd client && npm run lint
63+
# --deny-warnings:2026-08 已清零全部 warning,此后新 warning 视为失败,
64+
# 防止 lint 债务回潮(审计 #4)
65+
run: cd client && npx oxlint --deny-warnings
5766
- name: Typecheck (renderer)
5867
# 渲染进程(React + Vite)的 TypeScript 编译检查
59-
run: cd client && npx tsc --noEmit
68+
run: cd client && npm run typecheck
6069
# Electron 主进程使用独立的 tsconfig(CommonJS / Node 目标),
6170
# 与渲染进程的 Vite+DOM 配置不同,需单独检查以捕获主进程类型错误
6271
- name: Typecheck (Electron main process)
63-
run: cd client && npx tsc -p electron/tsconfig.json --noEmit
72+
run: cd client && npm run typecheck:electron
6473
- name: Test (with coverage)
6574
# 启用覆盖率收集,与 vitest.config.ts 中配置的阈值配合,
6675
# 确保新增代码的测试覆盖不低于设定门槛
6776
run: cd client && npm run test -- --run --coverage
6877
- name: Build
6978
run: cd client && npm run build
79+
- name: Audit (client)
80+
# 供应链漏洞扫描:默认 registry 为 npmmirror 不支持 advisories API,
81+
# 显式指定官方 registry(见 migration-spec §15.5)
82+
run: cd client && npm audit --registry=https://registry.npmjs.org --audit-level=high
7083

7184
# ===========================================================================
7285
# Server / sync-service —— Go + Gin 同步服务
@@ -75,15 +88,16 @@ jobs:
7588
needs: changes
7689
if: needs.changes.outputs.sync-service == 'true'
7790
runs-on: ubuntu-latest
91+
timeout-minutes: 20
7892
defaults:
7993
run:
8094
working-directory: server/sync-service
8195
steps:
8296
- uses: actions/checkout@v4
8397
- uses: actions/setup-go@v5
8498
with:
85-
# Go 1.25 尚未发布,使用当前最新稳定版 1.24(截至 2026 年 8 月)
86-
go-version: '1.24'
99+
# 与 go.mod 的 go 1.25 指令一致(此前注释"1.25 尚未发布"已过时)
100+
go-version: '1.25'
87101
cache-dependency-path: server/sync-service/go.sum
88102
- name: Lint (go vet)
89103
run: go vet ./...
@@ -99,6 +113,7 @@ jobs:
99113
needs: changes
100114
if: needs.changes.outputs.ai-gateway == 'true'
101115
runs-on: ubuntu-latest
116+
timeout-minutes: 20
102117
defaults:
103118
run:
104119
working-directory: server/ai-gateway
@@ -125,6 +140,7 @@ jobs:
125140
needs: changes
126141
if: needs.changes.outputs.website == 'true'
127142
runs-on: ubuntu-latest
143+
timeout-minutes: 20
128144
defaults:
129145
run:
130146
working-directory: website
@@ -142,3 +158,20 @@ jobs:
142158
run: npx tsc --noEmit
143159
- name: Build
144160
run: npm run build
161+
162+
# ===========================================================================
163+
# Docs —— 文档体系一致性检查(链接/索引/命名)
164+
# ===========================================================================
165+
docs:
166+
needs: changes
167+
if: needs.changes.outputs.docs == 'true'
168+
runs-on: ubuntu-latest
169+
timeout-minutes: 10
170+
steps:
171+
- uses: actions/checkout@v4
172+
- uses: actions/setup-node@v4
173+
with:
174+
node-version: 20
175+
- name: Docs check
176+
# 相对链接完整性 + 索引覆盖 + 命名规范(历史快照豁免见 docs/.docscheckignore)
177+
run: node scripts/docs-check.mjs

‎.github/workflows/release.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ concurrency:
2424
jobs:
2525
lint-test:
2626
runs-on: ubuntu-latest
27+
timeout-minutes: 30
2728
steps:
2829
- uses: actions/checkout@v4
2930
- uses: actions/setup-node@v4
@@ -45,6 +46,8 @@ jobs:
4546
matrix:
4647
os: [windows-latest]
4748
runs-on: ${{ matrix.os }}
49+
# Electron 打包 + 上传 + CDN 同步:上限 90 分钟
50+
timeout-minutes: 90
4851
steps:
4952
# lfs: true 必需:app-icon.png 等 PNG 由 Git LFS 托管(.gitattributes:
5053
# *.png filter=lfs),不拉取则仅为 131 字节指针文件,
@@ -101,6 +104,7 @@ jobs:
101104
release:
102105
needs: build
103106
runs-on: ubuntu-latest
107+
timeout-minutes: 30
104108
# secrets 上下文**不可用于 if 条件**(仅限 env/with/run),否则整个
105109
# workflow 文件解析失败、所有触发立即 0 秒报错。
106110
# 故先将条件所需值注入 job 级 env,再在 step 的 if 中用 env.* 引用。

‎.github/workflows/version-release.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
release:
2424
name: Semantic Release
2525
runs-on: ubuntu-latest
26+
timeout-minutes: 20
2627
# 发布提交自身携带 [skip ci] 已可被 GitHub 拦截,此处再加一层双保险,防止回环触发
2728
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
2829
steps:
@@ -42,7 +43,8 @@ jobs:
4243
node-version: 20
4344

4445
- name: Install release tooling
45-
run: npm install --no-audit --no-fund
46+
# npm ci:基于 lockfile 可复现安装(2026-08 审计 #12)
47+
run: npm ci --no-audit --no-fund
4648

4749
- name: Semantic Release
4850
env:

‎.gitignore‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ node_modules/
33
vendor/
44
__pycache__/
55
*.pyc
6+
.pytest_cache/
7+
.ruff_cache/
68

79
# Build
810
dist/
@@ -47,8 +49,9 @@ Thumbs.db
4749
!client/.env.production
4850

4951
# Brainstorm scratch (personal notes)
50-
brainstorm*.md
51-
ui_brainstorm.md
52+
# 注意:锚定根目录(/brainstorm*.md),避免误吞 docs/templates/brainstorm-template.md
53+
/brainstorm*.md
54+
/ui_brainstorm.md
5255

5356
# Logs
5457
*.log
@@ -61,3 +64,12 @@ coverage/
6164
# Scripts temp
6265
scripts/.mp3tmp/
6366
scripts/sounds_backup_original/
67+
# 软著源码文档生成输出(generate_source_code_doc.ps1)
68+
docs/softcopy-materials/
69+
70+
# 临时截图/审计 scratch(勿提交)
71+
tmp-*.png
72+
missing_ai_context.txt
73+
74+
# 音效源文件备份(42 个 wav,零代码引用,勿再提交)
75+
client/public/sounds/_backup_original/

0 commit comments

Comments
 (0)