Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cf29e2d
feat: 扩充生图风格库并补强提示词
damingishere-coder Aug 24, 2026
68b6ca6
docs: 添加项目全面工程体检报告
damingishere-coder Aug 24, 2026
5e1b8d6
fix: 收紧网络与文件路径安全边界
damingishere-coder Aug 24, 2026
714f2cf
docs: 记录 P0.2A 数据一致性取证
damingishere-coder Aug 24, 2026
df8966f
feat: 添加可回滚的离线数据迁移工具
damingishere-coder Aug 24, 2026
4039596
fix: 完成数据库关系约束正式切换
damingishere-coder Aug 24, 2026
05b1f64
fix: 修复 Codex 生图结果认领
damingishere-coder Aug 25, 2026
e15f8e5
fix: 隔离损坏状态并阻止重复执行
damingishere-coder Aug 25, 2026
58a332b
fix: 统一调度所有权和任务终态
damingishere-coder Aug 25, 2026
be24c22
fix: 让 Provider 配置默认失败关闭
damingishere-coder Aug 25, 2026
f88c4cc
feat: 默认自由生图并补全海报头尾
damingishere-coder Aug 25, 2026
26342bf
fix: 防止 AI 和邮件重复外部调用
damingishere-coder Aug 25, 2026
2453037
refactor: 冻结旧 V1 双轨写入
damingishere-coder Aug 25, 2026
b445bad
test: 补齐前端 E2E 和随机顺序验证
damingishere-coder Aug 25, 2026
62bd170
refactor: 拆分 V2 Pipeline 执行阶段
damingishere-coder Aug 25, 2026
20ceac2
refactor: 拆分 V2 API 与图片工作台
damingishere-coder Aug 25, 2026
f84cc0e
perf: 完善可观测性与运行效率
damingishere-coder Aug 25, 2026
1d27e43
feat: 固定群聊漫画提示词并支持并发生图
damingishere-coder Aug 25, 2026
a43d8fa
feat: 添加固定漫画分镜模板区块
damingishere-coder Aug 25, 2026
96e54bc
fix: 加固自动化恢复与发送验证
damingishere-coder Aug 26, 2026
7e3a511
feat: 完善状态闭环与风格动效
damingishere-coder Aug 26, 2026
7d8dad4
fix: 修复工作区导航和选题折叠显示
damingishere-coder Aug 26, 2026
f7f3918
fix: 修复日报 Prompt 生成故障
damingishere-coder Aug 27, 2026
8e7ac2d
docs: 添加无人值守稳定性审计
damingishere-coder Aug 27, 2026
dba95cb
fix: 提升无人值守运行可靠性
damingishere-coder Aug 27, 2026
5566cb8
feat: 建立可靠恢复闭环与每周洞察
damingishere-coder Aug 27, 2026
ac31db9
fix: 修复六群生图恢复阻塞
damingishere-coder Aug 27, 2026
00ec6f1
fix: 允许群报采用非固定尺寸图片
damingishere-coder Aug 28, 2026
eefe82a
fix: 修复群报生图失败恢复
damingishere-coder Aug 28, 2026
cd7cf90
fix: 修复 Eason 排行榜与图片事实校验
damingishere-coder Aug 28, 2026
37cfa43
feat: 统一六群排行榜与生图规则
damingishere-coder Aug 28, 2026
091dffb
fix: 稳定排行榜成员名称解析
damingishere-coder Aug 28, 2026
d22d674
feat: 添加总览实时任务节点和日志窗口
damingishere-coder Aug 28, 2026
f9f5bd6
fix: 恢复每日群报自动生成
damingishere-coder Aug 28, 2026
ab1e85d
fix: 稳定每日微信群报发送
damingishere-coder Aug 29, 2026
5a369d2
fix: 避免OCR跨行拼接数字单位
damingishere-coder Aug 29, 2026
b3becf6
fix: 固化说话人与消息快照绑定
damingishere-coder Aug 29, 2026
9a21e99
refactor: 改为每日定点生成和串行发送
damingishere-coder Aug 29, 2026
f4405cb
fix: 稳定微信群聊搜索校验
damingishere-coder Aug 30, 2026
26fae92
fix: 修复图片自动化降级
damingishere-coder Aug 31, 2026
3031d64
fix: 恢复失败终态的人工重试
damingishere-coder Aug 31, 2026
2005086
fix: 修复 Windows CI 状态写入竞态
damingishere-coder Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
634 changes: 634 additions & 0 deletions .codemap/codemap.html

Large diffs are not rendered by default.

225 changes: 225 additions & 0 deletions .codemap/codemap.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions .codemap/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"lang": "zh",
"project": "GroupBrief V1",
"subtitle": "本地微信群报生成与安全发送系统工程体检",
"outputDir": ".codemap",
"htmlFile": "codemap.html",
"mdFile": "codemap.md"
}
1,225 changes: 1,225 additions & 0 deletions .codemap/modules.json

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions .codemap/sonar-summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"server": "SonarQube Community Build 26.8.0.126808",
"projectKey": "groupbrief-v1-local-audit",
"analysisId": "1a07a159-5e1b-41b1-a74b-f68ee6dfe58a",
"ceTaskId": "02a52972-25c5-4dcc-8493-1bf7f0d9c2dd",
"status": "SUCCESS",
"warnings": 0,
"metrics": {
"ncloc": 23570,
"files": 120,
"bugs": 5,
"vulnerabilities": 12,
"securityHotspots": 0,
"codeSmells": 295,
"duplicatedBlocks": 5,
"duplicatedLines": 68,
"duplicatedLinesDensity": 0.2,
"coverage": 63.9,
"lineCoverage": 63.9,
"linesToCover": 10145,
"uncoveredLines": 3664,
"cognitiveComplexity": 3703,
"cyclomaticComplexity": 4368,
"maintainabilityRating": "A",
"reliabilityRating": "D",
"securityRating": "D",
"technicalDebtMinutes": 2141,
"technicalDebtRatioPercent": 0.3
},
"humanReview": {
"confirmedSonarBugs": 0,
"sonarBugCandidatesNeedingLowPriorityReview": 5,
"sonarVulnerabilitiesClassifiedLowValue": 12,
"reason": "Vulnerability findings are non-cryptographic random selection and deterministic fixture hashes; source review found more material authentication and path-boundary risks not detected by SonarQube."
},
"validation": {
"pythonTestsPassed": 413,
"pythonTestsFailed": 1,
"pythonWarnings": 1,
"pythonStatementCoveragePercent": 74.7,
"frontendAutomatedTests": 0,
"frontendBuild": "PASS",
"frontendMainJsBytes": 451300,
"frontendMainJsGzipBytes": 131500,
"npmAudit": {"moderate": 1, "high": 1, "critical": 0},
"pipAuditKnownVulnerabilities": 0
}
}
27 changes: 21 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
APP_HOST=127.0.0.1
APP_PORT=8766
APP_TIMEZONE=Asia/Shanghai
# 仅自动化测试或显式本地假数据演练可开启;真实运行必须保持 false。
ALLOW_TEST_PROVIDERS=false
# 旧 V1 数据库流水线默认只读;仅短期回滚/兼容窗口可临时改为 maintenance。
# 该开关不会从数据库或设置 UI 生效。
LEGACY_V1_WRITE_MODE=read_only

# --- 数据库 ---
DATABASE_URL=sqlite:///data/groupbrief.db

# --- 微信历史读取 Provider ---
# 主 Provider:wechat_data_analysis(WeChatDataAnalysis)
# 备用 Provider:wechat_cli(wechat-cli)
# --- V1 兼容历史读取 Provider(正式 V2 固定使用 WeChatDataAnalysis MCP/导出)---
# 不通过生产设置 UI 修改;V1 主/备仍保留一版兼容。
HISTORY_PROVIDER_PRIMARY=wechat_data_analysis
HISTORY_PROVIDER_FALLBACK=wechat_cli
HISTORY_PROVIDER_MOCK_ENABLED=true
# Mock 必须同时满足 ALLOW_TEST_PROVIDERS=true 才会注册。
HISTORY_PROVIDER_MOCK_ENABLED=false
# 微信数据目录(WeChatDataAnalysis 原始数据探测/状态提示使用,不用于群名解析)
WECHAT_DATA_DIR=
# 微信导出数据目录(WeChatDataAnalysis 结构化 JSON 导出根目录,群名解析与消息读取使用)。
Expand Down Expand Up @@ -52,8 +57,7 @@ CODEX_SUMMARY_TIMEOUT_SECONDS=240
CODEX_SUMMARY_MAX_RETRIES=2
CODEX_SUMMARY_REQUEST_CONCURRENCY=2

# DeepSeek 备用(只有 Codex 主调用失败时才使用)
AI_PROVIDER=deepseek
# DeepSeek 备用(只有 SUMMARY_PROVIDER_FALLBACK=deepseek 时才使用)
AI_BASE_URL=https://api.deepseek.com
AI_API_KEY=
AI_MODEL=deepseek-v4-flash
Expand Down Expand Up @@ -109,6 +113,17 @@ EMAIL_SEND_PARTIAL_REPORT=true

# --- 自动任务 ---
# 业务调度统一由后台 APScheduler 管理:每日 00:15 生成前一日群报,08:30 起按群发送。
# 正式环境只能有一个 owner。默认 fastapi;切为 external 前必须先停止内部 scheduler。
SCHEDULER_OWNER=fastapi
SCHEDULE_GENERATE_TIME=00:15
SCHEDULE_EMAIL_TIME=after_generate
SCHEDULE_STARTUP_CATCHUP_ENABLED=true
# 自动恢复仅扫描今天与前一天;代码还会把旧值强制收敛到 48 小时。
RELIABILITY_WATCHDOG_ENABLED=true
RELIABILITY_LOOKBACK_DAYS=2
RELIABILITY_WATCHDOG_INTERVAL_MINUTES=10
# 周报能力先部署后灰度。14 天验收完成前保持关闭;周报发送另有独立闸门。
WEEKLY_INSIGHTS_ENABLED=false
WEEKLY_SEND_ENABLED=false
WEEKLY_GENERATE_TIME=07:45
WEEKLY_SEND_TIME=08:30
19 changes: 19 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 5

- package-ecosystem: npm
directory: "/frontend"
schedule:
interval: weekly
open-pull-requests-limit: 5

- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 3
18 changes: 14 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ jobs:
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt
requirements.lock
- name: Install dependencies
run: python -m pip install -r requirements.txt -r requirements-dev.txt
- name: Run tests
run: python -m pytest tests -q
run: python -m pip install -r requirements.txt -r requirements-dev.txt -c requirements.lock
- name: Run tests and generate Sonar coverage
run: python -m pytest tests -q --cov=app --cov=scripts --cov-report=xml:coverage.xml
- name: Run tests in deterministic random order
run: python -m pytest tests -q --random-order-seed=20260825
- name: Compile Python sources
run: python -m compileall -q app scripts tests

Expand All @@ -36,10 +42,14 @@ jobs:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: "20"
node-version: "22.22.2"
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build frontend
run: npm run build
- name: Run frontend unit tests
run: npm test
- name: Run browser E2E with Fake API
run: npm run test:e2e
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
data/
output/
logs/
runtime/
*.db
*.sqlite
*.sqlite3
Expand All @@ -27,6 +28,11 @@ build/
node_modules/
frontend/dist/
frontend/.vite/
frontend/playwright-report/
frontend/test-results/
.coverage
coverage.xml
htmlcov/
*.tsbuildinfo

# --- 系统文件 ---
Expand Down
62 changes: 62 additions & 0 deletions GROUPBRIEF_DAILY_PREVIOUS_DAY_RECOVERY_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# GroupBrief 每日前一日规则修复与 2026-08-29 补跑任务

## 背景

2026-08-29 00:15 调度器已触发,但六个启用群均因 `weekday_default` 周末规则被过滤,
当天清单为空并以 `not_run` 结束。这与“每天生成前一天群报”的产品约定不一致。

## 目标

1. 将应用、新建群、空值回退和示例配置的默认统计规则统一为 `daily_previous_day`。
2. 保留 `weekday_default` 作为用户显式选择的兼容规则。
3. 在生产 SQLite 在线备份后,用单事务把群 23–28 切换为 `daily_previous_day`。
4. 通过带 `state_version` CAS 的恢复入口修复 2026-08-29 空清单并补跑六群生成。
5. 补跑不发送邮件、不手工调用微信发送;微信仍由既有 08:30 `send_due` 流程处理。

## 允许修改范围

- 群配置默认值、统计周期默认值、任务清单空值回退。
- Dashboard/群详情的默认规则展示和示例配置。
- 调度状态 CAS 更新与空清单显式恢复 API。
- 与上述行为直接相关的后端、前端测试。

## 禁止修改范围

- 不改变显式 `weekday_default` 的工作日语义。
- 不修改群名称、发送目标、发送时间、发送开关、Prompt、图片主题或排行榜规则。
- 不删除或覆盖历史 `run.json`、发送凭证、图片、Prompt 或聊天数据。
- 不手工提前发送、不重发历史内容、不访问或写入任何密钥。

## 已确定实现要求

- 默认值统一为 `daily_previous_day`;显式工作日规则仍可选。
- 空清单恢复只允许在旧状态为 `expected_groups=[]`、`generation_status=not_run`、
调用方提供的 `state_version` 匹配且当天不存在群级运行记录时执行。
- 恢复前按当前数据库重新计算预期群,并校验群 ID 集合完全匹配。
- 状态更新必须在生成锁与状态文件锁下原子完成,记录恢复审计字段。
- 生产数据库使用 SQLite online backup、`BEGIN IMMEDIATE`、完整性和外键检查。

## 验收标准

- 周六/周日默认规则也运行,且只覆盖前一自然日。
- 显式 `weekday_default` 周末仍跳过,周一仍覆盖周五至周日。
- 新建群、模型默认、旧库补列、空值回退与前端新建表单均为 `daily_previous_day`。
- 生产群 23–28 的规则均为 `daily_previous_day`,其他配置不变。
- 2026-08-29 清单包含且仅包含群 23–28,统计窗口为 2026-08-28 全天。
- 六群生成达到可信终态;未手工调用邮件或微信发送。
- 后端测试、前端测试、前端构建、Python 编译和 `git diff --check` 通过。

## 测试命令

- `.\.venv\Scripts\python.exe -m pytest tests -q`
- `npm test -- --run`
- `npm run build`
- `.\.venv\Scripts\python.exe -m compileall app scripts`
- `git diff --check`

## 返回格式

- 根因与修复范围。
- 生产备份路径、数据库更新前后值和完整性检查。
- 2026-08-29 六群生成及 08:30 待发送状态。
- 测试、提交哈希、分支和推送结果。
70 changes: 70 additions & 0 deletions GROUPBRIEF_DASHBOARD_RUNTIME_WINDOWS_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# GroupBrief 总览实时任务节点与日志窗口任务

## 背景

当前“运行总览”能展示每天各群的结果卡片,但 00:15 后台任务运行期间缺少实时阶段和日志视图。现有权威状态已经保存在 `output/.scheduler/<run_date>.json` 与各群 `run.json`,日志已经按固定分类写入 `logs/`。

## 目标

- 在总览统计卡片下方新增“任务节点”和“运行日志”两个只读窗口。
- 任务节点使用最新 scheduler/run 状态,展示全局阶段和每群当前阶段。
- 日志通过固定白名单、日期过滤、条数限制和脱敏后返回结构化数据。
- 今日运行中自动刷新,历史日期保持手动刷新。

## 允许修改范围

- `app/scheduler/runtime_status.py`
- `app/api/v2_ui_read.py`
- 新增只读日志解析服务及对应后端测试
- `frontend/src/api.ts`
- `frontend/src/pages/v2/Dashboard.tsx`
- Dashboard 相关样式、Vitest 与 Playwright 测试
- V2 路由契约测试
- 本任务文件

## 禁止修改范围

- 不修改 00:15/08:30 调度时间或 APScheduler 注册逻辑。
- 不修改取数、排行、Prompt、生图、发送算法及状态推进逻辑。
- 不修改数据库 Schema、生产数据、发送锁、未知结果保护或外部 Provider 配置。
- 不触发真实取数、AI 调用、图片生成、微信发送、服务重启或部署。
- 不读取或写入 `.env`、凭据、Cookie、浏览器数据。

## 已确定实现要求

1. 抽取每日状态的纯读取构建函数;Dashboard 直接基于最新 scheduler 和启用群 run 快照生成 `runtime`,现有状态文件写入合同保持兼容。
2. 节点固定为:调度启动、读取群消息、生成排行榜、摘要与提示词、生成图片、等待发送/发送完成。
3. 节点状态固定为:`pending`、`running`、`success`、`retry_pending`、`held`、`failed`。
4. 图片 `image_job.status=queued` 只能显示排队/等待,不得冒充正在生成。
5. 损坏状态 fail-closed 为需要关注,不写回、不猜测成功。
6. 新增 `GET /api/v2/runtime/logs`;`tail` 默认 100、范围 1..200;来源只允许 `scheduler/app/provider/ai`。
7. 日志记录包含时间、级别、来源、消息;按运行日期过滤,跨来源按时间排序,消息最长 500 字符并脱敏。
8. 桌面端任务节点/日志按约 60%/40% 并排,820px 以下上下排列。
9. 今日 `not_started` 每 30 秒刷新,`running/retry_pending` 每 3 秒刷新,终态停止;页面后台暂停,恢复可见立即刷新;历史日期仅手动刷新。
10. 日志支持来源/级别筛选、暂停/继续自动滚动和手动刷新。

## 验收标准

- Dashboard 响应新增 `runtime`,旧字段与原 URL 保持兼容。
- 六群可展开查看当前节点;空状态、运行中、重试、暂停、失败、完成均有准确文案。
- 日志接口拒绝非法来源/级别/日期/条数,不能读取任意路径,不能泄露敏感字段。
- 现有 Dashboard 生成、发送与人工核对操作仍只命中原接口。
- 窄屏无横向溢出;轮询会按状态和页面可见性启停。
- 所有定向后端测试、前端测试、构建和 Dashboard E2E 通过。

## 测试命令

```powershell
.\.venv\Scripts\python.exe -m pytest tests/test_runtime_status.py tests/test_runtime_logs.py tests/test_v2_ui_router_contract.py tests/test_p24_observability.py -q
npm --prefix frontend test -- --run src/api.test.ts src/pages/v2/dashboardRuntime.test.ts
npm --prefix frontend run build
npm --prefix frontend run test:e2e -- --grep Dashboard
git diff --check
```

## 返回格式

- 汇报后端状态/日志接口、前端两个窗口、自动刷新与安全边界。
- 提供测试命令和准确通过/失败数量。
- 汇报 Git 状态、提交哈希、分支、仓库地址与推送结果。
- 明确生产服务未重启,真实外部任务未触发。
67 changes: 67 additions & 0 deletions GROUPBRIEF_EASON_RANKING_IMAGE_FIX_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# GroupBrief Eason 排行榜与图片事实修复任务

## 背景

2026-08-28 的 `Eason张UED-4群🤘`(数据库 `group_id=28`)排行榜使用“所有非系统消息气泡”计数,群友期望改为文字主榜并单列互动数;展示名必须以 WeChatDataAnalysis 返回的 `senderDisplayName` 为准。当前再生图片还包含聊天证据中不存在的 BMI、体脂率和天气数字。

## 目标

1. 为单群提供可配置的排行榜计数与发言人名称策略。
2. 仅为 Eason 群启用“文字主榜+互动数”和 WeChatDataAnalysis 名称权威策略。
3. 扩展排行榜 JSON/文本并保持旧群、旧模板和下游读取兼容。
4. 为严格模式图片增加基于消息证据和 OCR 的事实校验,事实不明时失败并保持发送锁。
5. 重新读取 Eason 的 2026-08-28 数据、重建榜单和 Prompt、再生合格图片,绝不触发微信发送。

## 允许修改范围

- `app/db`、`app/api/groups.py`、排行榜与模板模块。
- WeChatDataAnalysis Provider/V2 数据源及消息快照兼容字段。
- 每日生成阶段、图片验证和图片再生流程。
- Eason 群配置页面、Dashboard 排行预览及相应类型。
- 与上述行为直接相关的测试、排行榜模板和本任务文件。
- 验证通过后更新本地 Eason 群配置与 2026-08-28 产物。

## 禁止修改范围

- 不改变其他五群的持久化策略或历史产物。
- 不修改 OpenAI/Codex 登录、认证或 Provider 配置。
- 不调用微信发送接口,不清除 `USER_REQUEST_NO_SEND_2026_08_28` 发送锁。
- 不提交 `.env`、日志、缓存、运行时数据库备份、生成图片或其他敏感/大型产物。
- 不 reset、stash、清理、强推或重写 Git 历史。

## 已确定实现要求

- 新增 `ranking_count_policy`,默认 `all_messages`;Eason 使用 `text_primary_with_interactions`。
- 新增 `sender_name_policy`,默认 `resolved`;Eason 使用 `wechat_data_analysis`。
- 文字主榜只按 `message_type=text` 排名,互动为其余可计数非系统类型;同文字数按规范化名称和身份键排序。
- `message_count` 保持所有可计数消息总数;新增文字数、互动数和文字发言人数。`TopSpeaker.count` 在文字主榜中等于文字数,并新增文字/互动/名称来源字段。
- WeChatDataAnalysis 原始展示名必须跨 MCP 与 JSON export 保存;Eason 不得被联系人备注覆盖。身份仍以 `sender_id` 聚合;空名匿名化;同名不同 ID 保持可区分。
- Eason Prompt 追加严格可见文案合同;图片事实校验使用同目录 `messages.json`、Prompt 与 OCR。无证据数字/长文本、OCR 不可用或识别失败不得晋级为可复核图片。
- 严格模式生图事实校验失败时最多生成两次;最终失败保持旧图和发送锁。
- 图片尺寸只校验可解码和正尺寸,不要求固定 1024×1536。

## 验收标准

- 当前 Eason 快照基准:383 条文字、226 条互动、609 条可计数消息、42 名活跃发言人;“深圳-UI-白白”为文字 55、互动 34。
- Eason 的名称来源标记为 `wechat_data_analysis`,不使用联系人备注覆盖。
- OCR/事实测试拒绝 `12%`、`90÷1.72²=30.4`、`120天`、`少油少盐`,允许消息证据中的 `78.8`、`61`、`66`。
- 其他群默认排行榜 JSON/文本和名称解析行为保持兼容。
- Eason 新产物完成后 `send_hold=true` 且 `send_hold_reason=USER_REQUEST_NO_SEND_2026_08_28`,没有新增发送证据。
- SQLite `integrity_check=ok`、外键检查无错误。

## 测试命令

```powershell
.\.venv\Scripts\python.exe -m pytest tests\test_v2_ranking.py tests\test_v2_ranking_template.py -q
.\.venv\Scripts\python.exe -m pytest tests\test_wechat_mcp.py tests\test_v2_data_source.py -q
.\.venv\Scripts\python.exe -m pytest tests\test_v2_image_task.py tests\test_v2_image_regeneration.py -q
.\.venv\Scripts\python.exe -m pytest tests -q
.\.venv\Scripts\python.exe -m compileall -q app tests
Set-Location frontend; npm test; npm run build
```

## 返回格式

- 精确命令、退出码、测试数量和失败证据。
- 修改文件范围、关键行为、Eason 实际产物统计与图片事实复核结果。
- 最终发送锁、Git 提交、分支、远端和推送结果。
Loading