70 KiB
Nexus /app-v2 双后台实施说明(2026-07-07)
结论
已在 Nexus 源码快照中新增第二套后台 /app-v2,并保留旧后台 /app/ 不动。当前 /app-v2 已从纯静态 mock 版推进到“真实 API 优先 + 演示数据兜底”的首屏版本:
- 旧后台:/app/,继续承载完整生产功能。
- 新后台:/app-v2/,React + TypeScript + Vite + Tailwind + shadcn 风格组件。
- 服务器资产、宝塔状态、一键登录已接入现有后端 API。
- 一键登录仍走后端既有逻辑,因此会触发登录前宝塔 session TTL 兜底检测 / 修复。
- 非 401 API 异常会 fallback 到演示数据;401 或未登录会显示登录保护卡片。
当前代码位置
项目目录:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042
新后台源码目录:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\frontend-v2
构建输出目录:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\web\app-v2
预览截图:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\ui-mockups\nexus-app-v2-implemented-20260707.png
技术栈
| 模块 | 选择 |
|---|---|
| 前端框架 | React |
| 类型系统 | TypeScript strict |
| 构建工具 | Vite |
| 样式 | Tailwind CSS + shadcn 风格原子组件 |
| 请求缓存 | TanStack Query |
| 表格 | TanStack Table |
| 状态管理 | Zustand |
| 图标 | lucide-react |
| 命令面板 | cmdk |
后端静态挂载
文件:
server/main.py
已挂载:
WEB_APP_V2_DIR = ROOT_DIR / "web" / "app-v2"
if WEB_APP_V2_DIR.is_dir():
app.mount("/app-v2", StaticFiles(directory=str(WEB_APP_V2_DIR), html=True), name="static_app_v2")
Docker 构建
文件:
Dockerfile
Dockerfile.prod
处理方式:
- Dockerfile 增加 web/app-v2 静态目录复制。
- Dockerfile.prod 增加 frontend-v2 build stage,并把构建产物复制到镜像内 web/app-v2。
本轮新增 / 修改的关键文件
前端 V2:
frontend-v2/src/features/dashboard/api/dashboardApi.ts
frontend-v2/src/features/dashboard/hooks/useDashboardData.ts
frontend-v2/src/features/dashboard/DashboardPage.tsx
frontend-v2/src/features/dashboard/components/AppShell.tsx
frontend-v2/src/features/dashboard/components/CommandPalette.tsx
frontend-v2/src/features/dashboard/components/ServerTable.tsx
frontend-v2/src/features/dashboard/components/ServerDrawer.tsx
frontend-v2/src/features/dashboard/components/TtlMatrix.tsx
frontend-v2/src/features/dashboard/components/TaskCenter.tsx
frontend-v2/src/features/dashboard/components/TrendPanel.tsx
frontend-v2/src/features/dashboard/components/HealthScore.tsx
frontend-v2/src/features/dashboard/components/AuditTimeline.tsx
frontend-v2/src/features/dashboard/data/dashboardData.ts
核心工程:
frontend-v2/src/lib/api.ts
frontend-v2/src/stores/appStore.ts
server/main.py
Dockerfile
Dockerfile.prod
已接入的真实 API
1. 服务器列表
请求:
GET /api/servers/?page=1&per_page=100&sort_by=id&sort_order=desc
用途:
- 生成服务器资产表格。
- 生成服务器详情抽屉。
- 计算在线服务器、风险告警、心跳延迟等指标。
2. 宝塔状态列表
请求:
GET /api/btpanel/servers
用途:
- 合并宝塔 configured / verify_ssl / bootstrap_state。
- 合并 session_cleanup_ttl_ok。
- 合并 session_cleanup_ttl_patched。
- 合并 session_cleanup_ttl_checked_at 和 last_error。
- 驱动 TTL 健康矩阵、任务中心和详情诊断。
3. 宝塔一键登录
请求:
POST /api/btpanel/servers/{server_id}/login-url
前端行为:
- 表格操作列可触发。
- 详情抽屉快捷操作可触发。
- Ctrl/Cmd + K 命令面板可触发。
- 成功后使用新标签页打开返回的登录 URL。
- 页面提示“后端已执行 TTL 兜底检测”。
后端关键点:
- V2 没有绕过后端,也没有在前端生成宝塔 token。
- 仍调用既有 create_login_url 逻辑。
- 该后端逻辑会在一键登录前调用 session cleanup TTL 检测 / 修复。
- 因此新增宝塔也能在一键登录前走 hardcoded_3600 兜底检测 / 修复路径。
登录与安全策略
V2 当前策略:
- 不在前端展示全局 API Key。
- 不把 API Key、JWT、Cookie、宝塔 tmp_login token、私钥等敏感值写入页面展示。
- access token 只放内存。
- 页面启动时调用 /api/auth/refresh 通过 HttpOnly refresh cookie 恢复会话。
- 成功后再请求 /api/auth/me。
- 未登录或 401 时显示登录保护,不展示后台数据。
- 非 401 API 失败时 fallback 到演示数据,方便本地预览和灰度 UI 验证。
当前 V2 首屏能力
| 区块 | 状态 | 说明 |
|---|---|---|
| 左侧导航 | 已完成 | 未迁移功能先回跳 /app/ |
| 顶部搜索入口 | 已完成 | Ctrl/Cmd + K 命令面板 |
| 资产统计卡片 | 已接真实数据 | 在线服务器、宝塔修复、活跃任务、风险告警 |
| 健康评分 | 已接真实数据 | 根据在线率、TTL 修复率、风险数计算 |
| 资产健康趋势 | 已完成 | 轻量 SVG 趋势图 |
| 宝塔 TTL 健康矩阵 | 已接真实数据 | 根据 session_cleanup_ttl_ok / patched / online 着色 |
| 任务中心 | 已接真实数据 | TTL、SSL、Agent 进度按当前资产计算 |
| 服务器表格 | 已接真实数据 | TanStack Table,可选中服务器,可一键登录 |
| 服务器详情抽屉 | 已接真实数据 | CPU、内存、磁盘、心跳、TTL、SSL、错误信息 |
| 审计时间线 | 演示数据 | 后续可接审计日志 API |
| 迁移看板 | 已完成 | 明确双后台并行进度 |
构建验证
执行目录:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\frontend-v2
已执行并通过:
npm.cmd run build
构建输出包括:
web/app-v2/index.html
web/app-v2/assets/index-*.css
web/app-v2/assets/react-*.js
web/app-v2/assets/query-*.js
web/app-v2/assets/table-*.js
web/app-v2/assets/ui-*.js
web/app-v2/assets/DashboardPage-*.js
后端语法验证也已通过:
python -m py_compile server/main.py
发布状态
当前改动已在本地源码快照中完成并构建通过,但没有发布到线上域名,也没有部署到 https://api.synaglobal.vip。
如果要上线,需要单独执行发布步骤:
- 确认当前源码快照是要发布的版本。
- 构建 Docker 镜像或同步 web/app-v2 静态目录。
- 部署到目标 Nexus 后端。
- 访问 /app-v2/ 做登录、真实 API、宝塔一键登录抽检。
- 保留 /app/ 回退入口,确认旧后台不受影响。
下一步建议
- 在本地或测试机启动 Nexus 后端,访问 /app-v2/ 做真实登录态验证。
- 抽检 42.193.182.190、120.79.213.154、192.168.124.219 的一键登录链路。
- 对 /api/btpanel/servers 返回字段做一次真实数据快照校验,确认字段名与前端映射完全一致。
- 继续迁移宝塔面板页、服务器资产详情页、任务中心详情页。
- 给 /app-v2 增加专用 favicon、错误页、空状态和更丰富的 shadcn 风格交互组件。
2026-07-07 继续推进:服务器资产中心
本轮继续把 /app-v2 从“单页看板”推进为“可逐页替换的第二后台”:
已新增
- 新增 V2 页面:服务器资产中心。
- 侧栏支持 V2 内部模块切换:
- 总览 Dashboard:仍留在 /app-v2;
- 服务器资产:进入新资产中心;
- 宝塔面板、任务中心、终端/文件、安全巡检、审计日志、系统设置:暂时跳回 /app/,保证功能不减少。
- 资产中心新增:
- 名称 / IP / 区域 / TTL 搜索;
- 宝塔状态筛选;
- 风险等级筛选;
- 在线资产、TTL 兜底通过、已修复宝塔、需关注等指标卡;
- 一键登录仍调用后端 /api/btpanel/servers/{id}/login-url;
- 页面内明确提示:前端不生成宝塔 token,后端登录前继续执行 hardcoded_3600 TTL 兜底检测/修复。
变更文件
frontend-v2/src/stores/appStore.tsfrontend-v2/src/features/dashboard/components/AppShell.tsxfrontend-v2/src/features/dashboard/components/AssetInventoryPage.tsxfrontend-v2/src/features/dashboard/DashboardPage.tsx
验证
npm.cmd run build通过。python -m py_compile server/main.py通过。- 构建产物已更新到
web/app-v2/。
当前边界
- 仍未发布到线上
https://api.synaglobal.vip。 - 资产中心当前复用已有服务器/宝塔状态 API,批量编辑、凭据管理、深度审计等高风险功能仍回退旧后台,后续逐页迁移。
2026-07-07 继续推进:宝塔面板 V2
本轮继续迁移第三个 V2 页面:宝塔面板 / 登录稳定性中心。
已新增
- 新增 V2 页面:宝塔登录稳定性中心。
- 侧栏“宝塔面板”从旧后台回退改为 /app-v2 内部页面。
- 页面展示:
- 已配置宝塔数量;
- TTL 兜底通过数量;
- 待兜底修复数量;
- 面板 SSL 建议数量;
- 每台宝塔的面板地址、Session TTL、最近检测、Bootstrap 状态、最近错误。
- 页面内的一键登录仍复用现有后端接口:
POST /api/btpanel/servers/{id}/login-url
- V2 前端仍不保存、不显示:
- 宝塔密码;
- Cookie;
- tmp_login token;
- 全局 API Key。
- 宝塔配置编辑、批量导入、危险配置修改仍回旧后台,保证迁移期间功能不减少。
变更文件
frontend-v2/src/features/dashboard/components/BtPanelPage.tsxfrontend-v2/src/features/dashboard/components/AppShell.tsxfrontend-v2/src/features/dashboard/DashboardPage.tsxfrontend-v2/src/stores/appStore.tsfrontend-v2/src/features/dashboard/api/dashboardApi.tsfrontend-v2/src/features/dashboard/data/dashboardData.ts
验证
npm.cmd run build通过。python -m py_compile server/main.py通过。- 构建产物已更新到
web/app-v2/。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
仍回退旧后台的模块
- 任务中心深度详情;
- 终端 / 文件;
- 安全巡检详情;
- 审计日志完整查询;
- 系统设置;
- 宝塔凭据编辑和批量导入。
2026-07-07 继续推进:任务中心 V2
本轮继续迁移第四个 V2 页面:任务中心 / 自动化运行态。
已新增
- 新增 V2 页面:任务中心 / 自动化运行态。
- 侧栏“任务中心”从旧后台回退改为 /app-v2 内部页面。
- 页面展示以下任务态:
- BT TTL 自动巡检:展示 hardcoded_3600 兜底状态;
- 宝塔一键登录兜底队列:强调一键登录前仍由后端执行 TTL 检测/修复;
- 面板 SSL 建议扫描:识别公网宝塔 SSL 建议项;
- Agent 心跳同步:展示在线、CPU、内存、磁盘等资产同步基础;
- 服务器资产风险同步:汇总离线、TTL、SSL、宝塔配置风险;
- 脚本执行审计同步:仅展示入口和迁移状态。
- 新增任务筛选:全部任务、运行中、已完成、需要关注、排队中。
- 新增任务搜索:可按任务名、类型、状态、描述搜索。
安全边界
- V2 任务中心第一版只做只读运行态展示,不直接调用脚本执行 API。
- 脚本执行、停止、重试、危险写操作继续回旧后台 /app/。
- 前端仍不展示、不保存:密码、Cookie、Token、tmp_login token、全局 API Key、私钥等敏感信息。
- 宝塔一键登录没有迁移到任务页直接执行;仍在资产页/宝塔页复用后端 POST /api/btpanel/servers/{id}/login-url,保留后端 Redis lock、TTL 兜底检测/修复和审计链路。
变更文件
- frontend-v2/src/features/dashboard/components/TaskCenterPage.tsx
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
仍回退旧后台的模块
- 任务中心的脚本执行、停止、重试、执行详情深查;
- 终端 / 文件;
- 安全巡检详情;
- 审计日志完整查询;
- 系统设置;
- 宝塔凭据编辑和批量导入。
2026-07-07 继续推进:审计日志 V2
本轮继续迁移第五个 V2 页面:审计日志 / 告警时间线。
已新增
- 新增 V2 页面:审计日志 / 告警时间线。
- 侧栏“审计日志”从旧后台回退改为 /app-v2 内部页面。
- 页面读取现有后端接口:
- GET /api/audit/
- GET /api/alert-history/
- 页面将管理员审计记录和告警/恢复记录合并为只读时间线。
- 新增审计筛选:全部、管理员、服务器、宝塔、安全、告警。
- 新增搜索:可搜索动作、管理员、目标、IP、详情、时间。
- 新增指标卡:审计记录、告警记录、需关注、宝塔相关。
安全边界
- V2 审计日志只做只读查询,不新增删除、导出、批量清理等写操作。
- 页面会对疑似敏感字段做前端二次隐藏,包括 password、token、cookie、secret、api key、private key 等模式。
- 前端仍不展示、不保存:密码、Cookie、Token、tmp_login token、全局 API Key、私钥等敏感信息。
- 如果审计/告警 API 异常,页面只切换演示 fallback,不影响旧后台完整查询。
变更文件
- frontend-v2/src/features/dashboard/components/AuditLogPage.tsx
- frontend-v2/src/features/dashboard/api/dashboardApi.ts
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
仍回退旧后台的模块
- 任务中心的脚本执行、停止、重试、执行详情深查;
- 终端 / 文件;
- 安全巡检详情;
- 系统设置;
- 宝塔凭据编辑和批量导入。
2026-07-07 继续推进:安全巡检 V2
本轮继续迁移第六个 V2 页面:安全巡检 / 风险总览。
已新增
- 新增 V2 页面:安全巡检 / 风险总览。
- 侧栏“安全巡检”从旧后台回退改为 /app-v2 内部页面。
- 页面复用当前资产、宝塔状态、审计和告警信号,形成只读巡检项:
- 宝塔 Session TTL 兜底;
- 公网宝塔面板 SSL;
- Agent 在线与资产同步;
- 审计/告警异常事件;
- 管理员远程执行命令边界;
- 敏感信息前端可见性。
- 新增巡检筛选:全部、严重、关注、通过、宝塔、SSL、Agent、审计。
- 新增搜索:可按巡检项、证据、建议、分类和等级搜索。
- 新增指标卡:巡检得分、严重项、需关注、通过项。
安全边界
- V2 安全巡检当前只做只读风险总览,不触发修复、不修改服务器、不执行脚本。
- script_service 是管理员远程执行命令能力,允许 shell 属于预期设计;V2 只标注权限/审计边界,不把它作为漏洞处理。
- 修复 SSL、修改宝塔凭据、执行 shell、清理审计日志等写操作仍回旧后台 /app/。
- 前端仍不展示、不保存:密码、Cookie、Token、tmp_login token、全局 API Key、私钥等敏感信息。
- 宝塔一键登录仍在资产页/宝塔页复用后端接口,后端继续负责 TTL 兜底和审计链路。
变更文件
- frontend-v2/src/features/dashboard/components/SecurityInspectionPage.tsx
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
- 安全巡检 / 风险总览。
仍回退旧后台的模块
- 任务中心的脚本执行、停止、重试、执行详情深查;
- 终端 / 文件;
- 系统设置;
- 宝塔凭据编辑和批量导入;
- 会修改服务器状态的深度修复动作。
2026-07-07 继续推进:系统设置 V2
本轮继续迁移第七个 V2 页面:系统设置只读概览。
已新增
- 新增 V2 页面:系统设置 / 只读概览。
- 侧栏“系统设置”从旧后台回退改为 /app-v2 内部页面。
- 新增设置概览 API 聚合:
- GET /api/settings/:读取设置表,后端敏感值继续返回脱敏状态;
- GET /api/settings/ip-allowlist:读取登录白名单状态;
- 任一非认证错误会降级为安全演示数据,不影响旧后台。
- 页面展示管理员会话、TOTP 状态、全局 API Key 配置状态、登录白名单、宝塔 TTL 兜底、中心 API 地址、心跳阈值。
- 新增“可安全展示的设置”列表,只列出白名单内的非敏感设置键。
- 迁移看板更新:系统设置进入 V2 只读迁移阶段,终端 / 文件仍回旧后台。
安全边界
- V2 系统设置当前只做只读概览,不直接执行任何生产配置写入。
- 全局 API Key 只显示“已配置(隐藏)/未配置”,不显示真实值、不复制、不导出。
- 前端继续不展示、不保存:密码、Cookie、Token、tmp_login token、全局 API Key、私钥等敏感信息。
- 凭据编辑、API Key 修改、SSH 私钥、白名单增删、系统级配置写入仍回旧后台 /app/。
- 宝塔一键登录仍走后端 login-url 接口,登录前 TTL 兜底检测/修复链路未改变。
变更文件
- frontend-v2/src/features/dashboard/components/SettingsOverviewPage.tsx
- frontend-v2/src/features/dashboard/api/dashboardApi.ts
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
- 敏感关键词扫描仅命中说明性文案、脱敏逻辑和内存 access token 管理代码,未发现写死真实敏感值。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
- 安全巡检 / 风险总览。
- 系统设置 / 只读概览。
仍回退旧后台的模块
- 终端 / 文件;
- 任务中心的脚本执行、停止、重试、执行详情深查;
- 宝塔凭据编辑和批量导入;
- API Key 修改、SSH 私钥、白名单增删;
- 会修改服务器状态或系统配置的深度修复动作。
2026-07-07 继续推进:终端 / 文件 V2
本轮继续迁移第八个 V2 页面:终端 / 文件安全入口。
已新增
- 新增 V2 页面:终端 / 文件安全入口。
- 侧栏“终端 / 文件”从旧后台回退改为 /app-v2 内部页面。
- 页面按风险分层展示:
- WebSSH 终端;
- 远程文件浏览;
- 文件推送 / 上传;
- 脚本库 / 命令执行;
- 命令日志 / 执行记录;
- 宝塔联动保护。
- 页面接入 /api/audit/ 和 /api/alert-history/ 的现有数据聚合,筛选终端、文件、脚本相关审计摘要。
- 审计 detail 在前端二次脱敏后展示,避免把历史命令或文件操作中的密码、Token、Cookie、API Key、私钥片段直接显示出来。
- 新增能力搜索,可按终端、文件、脚本、审计、安全边界搜索。
- 保留旧后台入口:/app/terminal、/app/files、/app/push、/app/scripts、/app/commands。
安全边界
- V2 当前不创建 WebSSH 会话,不发送键盘输入。
- V2 当前不上传、不删除、不写文件、不 chmod、不压缩/解压远端文件。
- V2 当前不调用 /api/scripts/exec,不绕过后端危险命令检查。
- script_service 是管理员远程执行 shell 的预期功能,不作为漏洞处理;V2 只强调执行必须继续经过后端和审计链路。
- 高风险动作包括真实终端、文件写入、上传、删除、停止、重试、脚本执行详情深查,继续回旧后台 /app/。
- 宝塔一键登录和 TTL hardcoded_3600 兜底修复链路未改,仍在资产/宝塔页调用后端 login-url。
变更文件
- frontend-v2/src/features/dashboard/components/TerminalFilesPage.tsx
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
- 安全巡检 / 风险总览。
- 系统设置 / 只读概览。
- 终端 / 文件安全入口。
仍回退旧后台的模块
- 真实 WebSSH 交互终端;
- 文件上传、删除、写入、chmod、压缩/解压、跨服务器传输;
- 脚本执行、停止、重试、执行详情深查;
- 宝塔凭据编辑和批量导入;
- API Key 修改、SSH 私钥、白名单增删;
- 会修改服务器状态或系统配置的深度修复动作。
2026-07-07 继续推进:执行记录只读中心 V2
本轮继续迁移第九个 V2 页面:执行记录只读中心。
已新增
- 新增 V2 页面:执行记录只读中心。
- 侧栏新增“执行记录”,进入 /app-v2 内部页面,不影响旧后台 /app/。
- 新增执行记录 API 聚合:
- GET /api/execution-records?limit=80&offset=0;
- 读取失败但非 401 时,降级为只读演示数据;
- 401 继续交给登录态保护处理。
- 页面使用 TanStack Query 缓存执行记录,使用 TanStack Table 渲染列表。
- 支持按任务名、操作者、操作、ID 搜索。
- 支持按记录类型筛选:脚本执行、服务器批量任务。
- 支持按状态筛选:running、completed、failed、partial、cancelled 以及后端返回的其它状态。
- 指标卡展示执行记录总量、运行中数量、异常/部分完成数量、涉及服务器数量。
安全边界
- V2 当前只读,不调用 /api/scripts/exec。
- V2 当前不停止任务、不重试任务、不拉取完整日志、不展示完整命令详情。
- 列表中的 label、op、command 做前端二次脱敏,隐藏 password、token、cookie、secret、api key、private key、BT_PANEL、BT_KEY、Authorization、Bearer 等片段。
- 真实脚本执行、停止、重试、完整日志和深度详情继续跳回旧后台 /app/scripts。
- script_service 仍按用户确认作为“管理员远程执行 shell”的预期能力保留;V2 只控制早期迁移阶段不误触发写操作。
变更文件
- frontend-v2/src/features/dashboard/components/ExecutionRecordsPage.tsx
- frontend-v2/src/features/dashboard/api/dashboardApi.ts
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
- 敏感关键词扫描仅命中说明性文案、脱敏正则和内存 access token 管理代码;未发现写死真实敏感值。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
- 安全巡检 / 风险总览。
- 系统设置 / 只读概览。
- 终端 / 文件安全入口。
- 执行记录只读中心。
仍回退旧后台的模块
- 真实 WebSSH 交互终端。
- 文件上传、删除、写入、chmod、压缩/解压、跨服务器传输。
- 脚本执行、停止、重试、完整日志和执行详情深查。
- 宝塔凭据编辑和批量导入。
- API Key 修改、SSH 私钥、白名单增删。
- 会修改服务器状态或系统配置的深度修复动作。
2026-07-07 继续推进:脚本库只读浏览 V2
本轮继续迁移第十个 V2 页面:脚本库只读浏览。
已新增
- 新增后端只读摘要接口:GET /api/scripts/summaries。
- 该接口只返回脚本元数据,不返回 script.content,避免脚本正文进入 /app-v2 浏览器网络响应。
- 新增 V2 页面:脚本库只读浏览。
- 侧栏新增“脚本库”,进入 /app-v2 内部页面,不影响旧后台 /app/。
- 页面使用 TanStack Query 缓存脚本摘要,使用 TanStack Table 渲染列表。
- 支持按脚本名、分类、描述、创建者、ID 搜索。
- 支持按 category 分类筛选。
- 支持“只看有正文”筛选,但仅依据 has_content/content_size/line_count,不展示正文。
- 指标卡展示脚本数量、分类数、正文规模和只读安全边界。
后端接口返回字段
GET /api/scripts/summaries 每条记录仅返回:
- id
- name
- category
- description
- created_by
- created_at
- updated_at
- has_content
- content_size
- line_count
明确不返回:
- content
- 凭据
- 执行参数
- token/cookie/api key/private key 等敏感字段
安全边界
- V2 当前只读,不调用 /api/scripts/exec。
- V2 当前不创建脚本、不编辑脚本、不删除脚本、不复制脚本正文。
- V2 当前不返回 script.content,因此即使打开浏览器 DevTools 也不会从新接口看到脚本正文。
- name/description 仍做前端二次脱敏,隐藏 password、token、cookie、secret、api key、private key、BT_PANEL、BT_KEY、Authorization、Bearer 等片段。
- 编辑、复制正文、执行、删除、凭据选择继续跳回旧后台 /app/scripts。
- script_service 作为管理员远程执行 shell 的预期功能继续保留;V2 只避免早期迁移阶段误触发写操作或暴露正文。
变更文件
- server/api/scripts.py
- frontend-v2/src/features/dashboard/components/ScriptLibraryPage.tsx
- frontend-v2/src/features/dashboard/api/dashboardApi.ts
- frontend-v2/src/features/dashboard/components/AppShell.tsx
- frontend-v2/src/features/dashboard/DashboardPage.tsx
- frontend-v2/src/stores/appStore.ts
验证
- python -m py_compile server\api\scripts.py server\main.py 通过。
- npm.cmd run build 通过。
- 构建产物已更新到 web/app-v2/。
- 搜索 /scripts 调用确认 V2 只使用 /api/scripts/summaries,不调用会返回正文的 /api/scripts/。
- 敏感关键词扫描仅命中说明性文案、脱敏正则和内存 access token 管理代码;未发现写死真实敏感值。
当前 /app-v2 已迁移页面
- 总览 Dashboard。
- 服务器资产中心。
- 宝塔登录稳定性中心。
- 任务中心 / 自动化运行态。
- 审计日志 / 告警时间线。
- 安全巡检 / 风险总览。
- 系统设置 / 只读概览。
- 终端 / 文件安全入口。
- 执行记录只读中心。
- 脚本库只读浏览。
仍回退旧后台的模块
- 真实 WebSSH 交互终端。
- 文件上传、删除、写入、chmod、压缩/解压、跨服务器传输。
- 脚本创建、编辑、删除、复制正文、执行、停止、重试、完整日志和执行详情深查。
- 宝塔凭据编辑和批量导入。
- API Key 修改、SSH 私钥、白名单增删。
- 会修改服务器状态或系统配置的深度修复动作。
2026-07-07 继续推进:真实只读文件浏览 V2
本轮继续完善第二后台 /app-v2 的“终端 / 文件”能力,新增真实只读文件浏览第一步,目标是先把安全、低风险的目录浏览迁移到 V2,同时继续保留旧后台 /app/files 处理所有写操作和高风险操作。
已新增
- 新增 V2 组件:
frontend-v2/src/features/dashboard/components/ReadOnlyFileBrowser.tsx。 - 已接入到“终端 / 文件”页面:
frontend-v2/src/features/dashboard/components/TerminalFilesPage.tsx。 - 复用后端现有只读接口:
GET /api/files/browse?server_id=...&path=...。 - 新增前端 API 聚合类型与函数:
RemoteFileItemFileBrowseDatafetchFileBrowseData(serverId, path)
- 页面支持:
- 选择在线服务器;
- 输入远程绝对路径;
- 浏览目录;
- 点击目录进入下级;
- 返回上级目录;
- 刷新当前目录;
- 按名称、owner、group、权限过滤;
- 展示当前服务器、当前路径、目录/文件数量、文件体积合计。
安全边界
- V2 只调用
GET /api/files/browse列目录。 - V2 不读取文件正文。
- V2 不上传文件。
- V2 不删除文件。
- V2 不写入文件。
- V2 不 chmod/chown。
- V2 不执行压缩、解压、跨服务器推送等会改变远程状态的动作。
- 文件读取、上传、删除、chmod、压缩/解压、跨服务器推送仍跳回旧后台
/app/files。 - 后端路径校验、SSH 执行、审计日志仍由现有
server/api/files.py与files_browse_service.py负责。
本轮修复
- 修复
ReadOnlyFileBrowser.tsx中路径正则写坏导致的 TypeScript/JSX 构建错误。 - 清理未使用图标 import。
- 重新用 UTF-8 写入该组件,避免中文文案和 JSX 标签出现乱码/截断问题。
变更文件
frontend-v2/src/features/dashboard/components/ReadOnlyFileBrowser.tsxfrontend-v2/src/features/dashboard/components/TerminalFilesPage.tsxfrontend-v2/src/features/dashboard/api/dashboardApi.ts
验证
npm.cmd run build通过。- 构建产物已更新到
web/app-v2/。 python -m py_compile server\api\files.py server\api\scripts.py server\main.py通过。- 敏感关键词扫描仅命中说明性文案、脱敏正则和内存 access token 管理代码;未发现写死真实密码、Cookie、API Key、私钥、tmp_login token 等敏感值。
当前状态
- 本轮改动仍在本地快照中。
- 尚未发布到
https://api.synaglobal.vip。 - 旧后台
/app/不受影响。
2026-07-08 继续推进:实时监控只读中心 V2
本轮继续完善第二后台 /app-v2 的“实时监控”只读能力,把监控槽、最近会话、探针记录和实时指标聚合到一个低风险页面中。旧后台 /app/watch 继续保留完整写操作能力,V2 当前只做查看与过滤。
已新增 / 已接入
- 新增 V2 组件:
frontend-v2/src/features/dashboard/components/WatchMonitoringPage.tsx。 - 新增模块枚举:
monitoring。 DashboardPage.tsx已接入WatchMonitoringPage。- 前端 API 聚合新增:
WatchMetricPointWatchProcessSnapshotWatchSlotItemWatchSessionItemWatchProbeRecordItemWatchMonitoringDatafetchWatchMonitoringData(hours)
- 页面支持 6h / 24h / 72h 时间窗口切换、刷新、监控槽卡片、CPU/内存/磁盘均值、sparkline、最近会话、最近探针记录、服务器/状态/错误过滤。
调用接口
GET /api/watch/pins:读取监控槽。GET /api/watch/live?server_ids=...:读取槽位服务器实时指标。GET /api/watch/sessions?hours=168:读取最近监控会话。GET /api/watch/probe-records?hours=...&page=1&per_page=40:读取最近探针记录。
安全边界
- V2 只调用 watch 模块 GET 接口。
- V2 不创建监控槽。
- V2 不删除或替换监控槽。
- V2 不启停监控。
- V2 不调整 TTL。
- V2 不安装 psutil。
- V2 不触发 SSH 写操作。
- 监控槽编辑、安装依赖、启停监控、TTL 调整等写操作继续跳回旧后台
/app/watch。
变更文件
frontend-v2/src/features/dashboard/components/WatchMonitoringPage.tsxfrontend-v2/src/features/dashboard/api/dashboardApi.tsfrontend-v2/src/features/dashboard/components/AppShell.tsxfrontend-v2/src/features/dashboard/DashboardPage.tsxfrontend-v2/src/stores/appStore.ts
验证
npm.cmd run build通过。python -m py_compile server\api\watch.py server\main.py通过。- 敏感关键词扫描仅命中说明性文案、脱敏正则和内存 access token 管理代码;未发现写死真实敏感值。
当前状态
- 本地快照已更新。
- 构建产物已更新到
web/app-v2/。 - 尚未发布到
https://api.synaglobal.vip。 - 旧后台
/app/不受影响。
2026-07-08 继续推进:SSH 会话 / 命令日志只读中心 V2
本轮继续迁移低风险只读模块,新增“SSH 会话 / 命令日志只读中心”。该页面用于审计查看最近 SSH 会话和命令日志,仍不提供 WebSSH、命令执行、会话回放、日志导出等写操作或高风险操作。
已新增 / 已接入
- 新增 V2 组件:
frontend-v2/src/features/dashboard/components/OperationLogsPage.tsx。 - 新增模块枚举:
operations。 - 侧栏新增“命令日志”入口。
DashboardPage.tsx新增operations分发。- 同步补上上一轮遗漏的侧栏“实时监控”入口,确保
monitoring页面可以从侧栏进入。 - 前端 API 聚合新增:
OperationSshSessionItemOperationCommandLogItemOperationLogsDatafetchOperationLogsData(serverId?)
调用接口
GET /api/assets/ssh-sessions?page=1&per_page=40:读取 SSH 会话元数据。GET /api/assets/command-logs?page=1&per_page=120&redact=true:读取命令日志摘要。- 可选追加
server_id=...进行服务器筛选。
本轮后端安全增强
server/api/assets.py的GET /api/assets/command-logs新增redact: bool = Query(False)参数。- 当
redact=true时,后端在返回前对命令中的敏感片段做服务端脱敏,包括:- password / passwd / pwd
- token / cookie / secret
- api key / private key / access key
- BT_PANEL / BT_KEY / Authorization / Bearer
--password/--token/sshpass -p/-p...等常见命令参数。
- 前端
OperationLogsPage.tsx仍保留二次脱敏兜底,防止旧数据或异常格式直接展示。
安全边界
- V2 只调用 assets 模块 GET 接口。
- V2 不打开 WebSSH。
- V2 不执行命令。
- V2 不重放命令。
- V2 不复制未脱敏命令正文。
- V2 不导出日志。
- V2 不修改服务器状态、凭据、权限或审计配置。
- 真实 WebSSH、命令执行、会话回放、导出和权限变更继续跳回旧后台
/app/。
变更文件
server/api/assets.pyfrontend-v2/src/features/dashboard/components/OperationLogsPage.tsxfrontend-v2/src/features/dashboard/api/dashboardApi.tsfrontend-v2/src/features/dashboard/components/AppShell.tsxfrontend-v2/src/features/dashboard/DashboardPage.tsxfrontend-v2/src/stores/appStore.ts
验证
npm.cmd run build通过,构建产物已更新到web/app-v2/。python -m py_compile server\api\assets.py server\api\watch.py server\main.py通过。- 敏感关键词扫描仅命中脱敏规则、演示数据中的
Authorization: [已脱敏]、以及frontend-v2/src/lib/api.ts的内存 access token 管理;未发现真实敏感值。
当前状态
- 本轮改动仍在本地快照中。
- 尚未发布到
https://api.synaglobal.vip。 - 旧后台
/app/不受影响。
2026-07-08 继续推进:宝塔资源只读总览 V2
本轮继续迁移宝塔相关能力,新增“宝塔资源只读总览”。该页面用于集中查看单台宝塔服务器的站点、数据库、计划任务和系统资源快照。旧后台仍负责所有会改变远端状态的宝塔操作。
已新增 / 已接入
- 新增 V2 组件:
frontend-v2/src/features/dashboard/components/BtResourceOverviewPage.tsx。 - 新增模块枚举:
btresources。 - 侧栏新增“宝塔资源”入口。
DashboardPage.tsx新增btresources分发。- 前端 API 聚合新增:
BtResourceRecordBtResourceOverviewDatafetchBtResourceOverviewData(serverId?)
调用接口
V2 本轮只调用已有 GET 接口:
GET /api/btpanel/servers/{server_id}/system/totalGET /api/btpanel/servers/{server_id}/system/diskGET /api/btpanel/servers/{server_id}/system/networkGET /api/btpanel/servers/{server_id}/sitesGET /api/btpanel/servers/{server_id}/databasesGET /api/btpanel/servers/{server_id}/crontab
旧后台的服务管理页当前主要是 POST /api/btpanel/servers/{server_id}/services 启停/重启服务,没有对应只读 GET 状态接口;因此 V2 本轮不做服务启停状态控制,只提供旧后台跳转。
页面能力
- 选择已配置宝塔的服务器。
- 搜索站点 / 数据库 / 计划任务 / 备注。
- 查看系统、宝塔版本、运行时间、CPU、内存、网络、磁盘快照。
- 查看站点列表:名称、路径、启停状态、PHP、备注、创建时间。
- 查看数据库列表:库名、用户、类型、备份数量、备注、创建时间。
- 查看计划任务列表:任务名、类型、目标、启停状态、执行摘要、时间配置。
- 计划任务命令摘要会做前端脱敏与截断,不展示完整敏感正文。
安全边界
- V2 只调用宝塔 GET 接口。
- V2 不调用站点启停接口:
POST /sites/start、POST /sites/stop。 - V2 不创建站点:
POST /sites。 - V2 不新增/删除域名。
- V2 不设置或申请 SSL。
- V2 不创建数据库。
- V2 不修改数据库密码。
- V2 不触发数据库备份。
- V2 不编辑或新增计划任务。
- V2 不调用服务启停/重启接口:
POST /services。 - 所有会改变远端宝塔状态的操作继续回旧后台
/app/btpanel/*执行。
变更文件
frontend-v2/src/features/dashboard/components/BtResourceOverviewPage.tsxfrontend-v2/src/features/dashboard/api/dashboardApi.tsfrontend-v2/src/features/dashboard/components/AppShell.tsxfrontend-v2/src/features/dashboard/DashboardPage.tsxfrontend-v2/src/stores/appStore.ts
验证
npm.cmd run build通过,构建产物已更新到web/app-v2/。python -m py_compile server\api\btpanel.py server\api\assets.py server\main.py通过。- 敏感关键词扫描仅命中脱敏规则、演示脱敏文本、以及内存 access token 管理;未发现真实敏感值。
当前状态
- 本轮改动仍在本地快照中。
- 尚未发布到
https://api.synaglobal.vip。 - 旧后台
/app/不受影响。
2026-07-08 继续推进:全局搜索 V2 只读中心
本次新增
- 新增 /app-v2 模块:全局搜索。
- 侧栏新增入口:全局搜索。
- 命令面板 Ctrl/Cmd + K 新增快捷项:打开全局搜索。
- 新增页面文件:frontend-v2/src/features/dashboard/components/GlobalSearchPage.tsx
- 修改接入文件:frontend-v2/src/features/dashboard/api/dashboardApi.ts、frontend-v2/src/features/dashboard/components/AppShell.tsx、frontend-v2/src/features/dashboard/components/CommandPalette.tsx、frontend-v2/src/features/dashboard/DashboardPage.tsx、frontend-v2/src/stores/appStore.ts。
接口调用
- 只调用现有只读接口:GET /api/search/?q=...
- 后端 server/api/search.py 已做 LIKE 通配符 escape,避免搜索 % / _ 时扩大匹配范围。
- V2 前端额外做输入标准化、至少 2 个字符才请求、350ms 防抖、TanStack Query 30 秒缓存。
- 后端不可用时切换只读演示数据;如果后端未命中服务器但当前 Dashboard 资产缓存命中,则单独显示本地命中。
覆盖范围
- 服务器:名称、域名、分组、在线状态。
- 脚本库:脚本名称、分类。
- 凭据元数据:名称、数据库类型、主机。
- 计划任务:计划名称、Cron 表达式、启停状态。
安全边界
- V2 搜索页只读,不新增/修改/删除任何业务对象。
- 不展示真实密码、Cookie、Token、API Key、SSH 私钥、宝塔 tmp_login。
- 凭据搜索只显示元数据;凭据编辑、密码查看/修改、私钥相关操作继续回旧后台。
- 搜索结果点击目前跳回旧后台对应模块,避免 V2 早期误接高风险写操作。
验证结果
- 已通过前端构建:frontend-v2 下执行 npm.cmd run build。
- 构建产物已更新到 web/app-v2/。
- 已通过后端语法检查:python -m py_compile server/api/search.py server/main.py。
- 敏感关键词扫描:命中均为脱敏规则、脱敏示例、说明文案或内存 access token 管理逻辑;未发现写入真实敏感值。
2026-07-08 继续推进:一键登录并发边界、V2 脱敏、验证与 PowerShell 建议
本轮结论
- PowerShell 7+ 相比 Windows PowerShell 5.1 更适合作为 Nexus 本地开发 shell:默认 UTF-8 更稳定,跨平台命令行为更接近 Linux,
pwsh对中文输出/输入更友好。 - 但 PowerShell 7+ 不是“彻底根治中文污染”的唯一手段:凡是涉及把中文脚本通过管道、heredoc / here-string 写入文件,仍建议使用 Node.js / Python 的 UTF-8 文件 API,或者直接使用
cmd.exe/ Git Bash / WSL 执行构建测试。 - 当前本地快照未发布到正式域名
https://api.synaglobal.vip。上线仍需要单独部署。
PowerShell / Shell 使用建议
建议优先级:
-
文件写入 / 大段中文文档:优先 Node.js
fs.writeFileSync(..., 'utf8')或 PythonPath.write_text(..., encoding='utf-8')。 -
前端构建 / 后端编译 / ripgrep 扫描:优先
cmd.exe /c或 PowerShell 7pwsh -NoLogo -NoProfile -Command。 -
SSH / Docker / Linux 批处理:长期最好使用 WSL 或远端 Linux 主机执行,减少 Windows shell 差异。
-
避免 Windows PowerShell 5.1 管道写中文,尤其不要使用:
@' 中文 Python 脚本 '@ | python -这类写法历史上已出现过把中文写成
????的问题。 -
如果继续使用 Windows PowerShell 5.1,至少把执行链限制在“只读扫描/启动命令”,不要用它负责生成中文代码或中文文档。
宝塔一键登录并发修复复核
已确认本地快照中存在以下修复方向:
- 同一服务器一键登录增加 Redis fail-fast 锁,避免双击、网关重试、多 worker 并发时后生成的
tmp_token覆盖前一个 token。 - 成功签发登录 URL 后增加短冷却 lease,减少 10 秒级连续打开多个宝塔页面时互相打掉登录态的概率。
- 宝塔 bootstrap / TTL 修复增加 Redis 分布式锁,避免多进程同时改远端
task.py。 - 远端 bootstrap 脚本改为
mktemp + flock + os.replace(),降低并发写坏远端文件的风险。
API 相对 tmp_token 不依赖 SSH 的补丁
后端 server/application/services/btpanel_service.py 已补强:
- 当宝塔 API 已返回
/login?tmp_token=...或login_url时,优先使用已配置的BtPanelCredentials.base_url归一化 URL。 - 不再因为“API 已成功但缺 SSH 凭据”而阻断本可成功的一键登录。
- 这对只配置宝塔 API、没有 SSH 凭据的服务器更稳。
新增/保留的测试点:
tests/test_btpanel_login_url.py增加“API 返回相对 tmp_token 时不调用 SSH”的测试用例。
/app-v2 脱敏边界
本轮复核并保留以下策略:
- V2 前端不显示全局 API Key。
- V2 不展示宝塔密码、Cookie、tmp_login token、SSH 私钥、PEM 私钥、API Key 等敏感值。
- 全局搜索对疑似敏感 query 直接阻断,不请求后端,不把原始敏感 query 放入 React Query cache key。
- 文件浏览对敏感路径做脱敏/阻断,不把原始敏感路径放入 React Query cache key。
- 后端错误信息进入 UI 前做
safeWarningText()脱敏。 bt.base_url显示前做sanitizeBtBaseUrl(),避免把 URL 内用户名密码等信息带到页面。- credentials 搜索结果中的 host 做
sanitizeHostDisplay(),避免 DSN 形式user:pass@host泄漏。
本轮验证命令与结果
在本地快照目录执行:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042
验证结果:
-
关键旧调用扫描:
rg -n "resolve_temp_login_url" server\application\services\btpanel_service.py结果:无命中,说明
btpanel_service.py不再直接依赖旧的 SSH discovery 归一化函数。 -
乱码扫描:
rg -n "\\?{3,}|�" frontend-v2\src server tests结果:无命中。
-
全局 API Key 文案扫描:
rg -n "全局 API Key|Global API Key" frontend-v2\src web\app-v2结果:无命中。
-
api_key字段扫描:rg -n "api_key" frontend-v2\src web\app-v2结果:无命中。之前 fallback 演示设置里的空
api_key字段名已移除。 -
后端语法检查:
python -m py_compile server\application\services\btpanel_service.py server\infrastructure\btpanel\bootstrap_lock.py server\infrastructure\btpanel\ssh_bootstrap.py tests\test_btpanel_login_url.py tests\test_btpanel_get_config.py tests\test_btpanel_bootstrap_lock.py tests\test_btpanel_ssh_bootstrap.py结果:通过。
-
前端构建:
cd frontend-v2 npm.cmd run build结果:通过,构建产物已更新到
web/app-v2/。 -
pytest:
python -m pytest tests\test_btpanel_ssh_bootstrap.py tests\test_btpanel_bootstrap_lock.py tests\test_btpanel_login_url.py tests\test_btpanel_get_config.py -q结果:未执行成功,当前默认解释器为
C:\Python314\python.exe,缺少 pytest:C:\Python314\python.exe: No module named pytest这属于本地测试环境问题,不是当前代码语法错误。建议后续用 Python 3.12 venv 固定依赖后再跑完整测试。
当前发布状态
- 本轮代码仍在本地快照目录。
- 尚未确认已部署到
https://api.synaglobal.vip。 - 如果要让正式站点看到
/app-v2、宝塔一键登录并发锁、API 相对 tmp_token 修复,需要执行正式发布流程。
后续待办
- 建 Python 3.12 虚拟环境,安装
pytest/sqlalchemy等 dev 依赖,跑完宝塔相关测试集。 - 给
BootstrapRemoteError增加永久失败语义,避免ssh_no_credentials/ssh_sudo_required被错误当成可重试。 - 明确 Redis 锁异常策略:当前建议 Redis 对登录并发锁和 bootstrap 锁是 mandatory,Redis 不可用时宁可阻断,避免并发打坏 token 或远端文件。
- 给
/app-v2增加构建后敏感词扫描脚本,并纳入 CI。 - 发布前再次扫描
web/app-v2构建产物,确认无真实 token/key/私钥。 - 发布到正式环境后,在
https://api.synaglobal.vip/app-v2/实测登录、列表、宝塔一键登录和旧后台跳转。
2026-07-08 追加修复:BootstrapRemoteError 永久失败语义
处理原因
子审查发现:BootstrapRemoteError 之前只携带 code,classify_ssh_result() 虽然能判断 ssh_no_credentials / ssh_sudo_required / ssh_auth_failed 是否属于永久失败,但该布尔值没有传到 service 层,导致 service 层只能用 exc.code == "ssh_auth_failed" 粗略判断。
已修复
server/infrastructure/btpanel/ssh_bootstrap.py:BootstrapRemoteError新增permanent: bool = False属性。ssh_bootstrap_panel()在 SSH 执行失败时把classify_ssh_result()的permanent传入异常。- 修复了一处历史中文注释乱码。
server/application/services/btpanel_service.py:bootstrap_server()改为使用exc.permanent写入 bootstrap 状态。
tests/test_btpanel_ssh_bootstrap.py:- 增加
test_ssh_bootstrap_panel_preserves_permanent_error_flag,验证 sudo 需要密码会抛出permanent=True的BootstrapRemoteError。
- 增加
追加验证
python -m py_compile server\infrastructure\btpanel\ssh_bootstrap.py server\application\services\btpanel_service.py tests\test_btpanel_ssh_bootstrap.py:通过。- 针对刚改文件扫描常见中文乱码片段:无命中。
待办更新
前一节“后续待办”中的 BootstrapRemoteError 永久失败语义已完成;剩余待办仍包括 Python 3.12 测试环境、Redis 异常策略测试/文档、构建产物敏感词 CI 扫描、正式发布验证。
2026-07-08 追加:/app-v2 构建产物敏感信息扫描脚本
处理原因
/app-v2 现在已经进入可并行使用阶段,发布前需要一个可以重复执行的检查,避免真实 API Key、Bearer token、JWT、宝塔 tmp_login、URL 内嵌账号密码、PEM 私钥等高风险内容被打进静态产物。
已新增文件
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\frontend-v2\scripts\scan-app-v2-sensitive.mjs
已更新文件
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\frontend-v2\package.json
新增 npm scripts:
npm run scan:sensitive
npm run build:safe
其中:
scan:sensitive:扫描../web/app-v2构建产物。build:safe:先执行 TypeScript/Vite 构建,再执行敏感信息扫描。
当前扫描规则
扫描对象:
.html.js.css.json.txt.svg.map
高置信阻断项:
- “全局 API Key” / “Global API Key” 文案。
- PEM 私钥块。
- CSR/PEM 请求块。
- JWT-like token。
sk-...类型密钥。- GitHub token。
- AWS Access Key ID。
- Bearer token。
- 宝塔
tmp_login/tmp_token明文值。 - URL 内嵌用户名密码。
- 高置信
password/api_key/secret/private_key/bt_key明文赋值。
验证结果
已在 frontend-v2 目录执行:
npm.cmd run build:safe
结果:通过。
关键输出:
[app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found in ...\web\app-v2
当前限制
- 这是高置信扫描,不替代完整 SAST/DAST。
- 为避免误报,规则不会因为普通说明文字中出现 token/password 等词就失败。
- 发布前仍建议配合后端接口脱敏、浏览器实际页面检查、以及线上响应头/缓存策略检查。
2026-07-08 追加:本地 Python 测试环境尝试结果
当前本机 Python 状态
执行:
py -0p
结果只有:
-V:3.14 * C:\Python314\python.exe
执行:
python -m pip show pytest sqlalchemy
结果:当前全局 Python 没有 pytest/sqlalchemy。
已尝试的隔离安装
已在项目快照目录创建临时虚拟环境:
.venv-py314
第一次使用默认 PyPI 安装 requirements.txt + requirements-dev.txt 失败,原因是 PyPI SSL EOF。
随后切换清华 PyPI 镜像:
.venv-py314\Scripts\python.exe -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt -r requirements-dev.txt
下载依赖成功,但安装失败在 pydantic-core==2.27.1。根因:当前 Python 是 3.14,而该版本 pydantic-core 使用的 PyO3 最高支持到 Python 3.13。
又尝试设置:
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
继续安装,仍失败,后续错误来自 jiter/PyO3 与 Python 3.14 C API 不兼容。
结论
- 本地 Windows Python 3.14 不适合跑 Nexus 当前后端依赖。
- 这不是 Nexus 代码语法问题,而是解释器版本与 pinned 依赖不兼容。
- 后端单测需要 Python 3.12,或至少 Python 3.13;最推荐与生产 Docker 保持 Python 3.12。
uv 检查
本机存在:
C:\Users\uzuma\.local\bin\uv.exe
但 uv python list --only-installed 默认读取用户 uv cache / install 目录时报权限或路径问题。即使设置工作区 UV_CACHE_DIR 与 UV_PYTHON_INSTALL_DIR,仍会扫到不可访问的 C:\Users\uzuma\.local\bin\python3.14.exe。
下一步建议
- 在 Windows 安装 Python 3.12 后重新建
.venv-py312。 - 或直接用 Docker Python 3.12 镜像跑 pytest。
- 或在局域网 Linux 测试部署机上安装 Python 3.12/venv 后跑后端测试。
- 当前已能继续做
py_compile、前端构建、V2 敏感产物扫描;完整 pytest 暂时不能在本机 Python 3.14 上完成。
2026-07-08 追加:后端测试环境检查脚本
已新增文件
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\check_backend_test_env.py
用途
在新机器或本机执行 pytest 前,先检查当前 Python 是否适合跑 Nexus 后端测试。
检查项:
- Python 版本必须是 3.12 或 3.13。
- 明确阻止 Python 3.14,因为当前 pinned
pydantic-core/ PyO3 不兼容。 - 检查
pytest、sqlalchemy、pydantic、fastapi是否可 import。
当前验证
在本机执行:
python scripts\check_backend_test_env.py
结果:按预期失败并提示需要 Python 3.12/3.13。
关键输出:
Python executable: C:\Python314\python.exe
Python version: 3.14.4
ERROR: Nexus backend tests should be run with Python 3.12 or 3.13.
这个脚本后续可以放到本地测试说明或 CI 前置检查中,避免在不兼容解释器上浪费依赖安装时间。
2026-07-08 追加:本地发布前 Gate 与宝塔测试入口
已新增文件
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_local_release_gate.py
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_btpanel_tests.py
run_local_release_gate.py
用途:发布前在本地快照上跑一组稳定、可重复的检查。
默认执行:
python -m py_compile检查本轮关键后端、测试、发布脚本。frontend-v2下执行npm run build:safe。build:safe内部包含 TypeScript 检查、Vite 构建、web/app-v2高置信敏感信息扫描。- 默认跳过 pytest,因为当前本机 Python 3.14 不适合跑 pinned 后端依赖。
执行命令:
python scripts\run_local_release_gate.py
当前验证结果:通过。
关键输出:
[app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found
[release-gate] pytest skipped. Use --with-pytest under Python 3.12/3.13 to run BtPanel tests.
[release-gate] OK
如在 Python 3.12/3.13 的正确测试环境里,可以执行:
python scripts\run_local_release_gate.py --with-pytest
run_btpanel_tests.py
用途:集中运行宝塔相关后端测试,避免每次手工拼测试文件列表。
默认覆盖测试文件:
tests/test_btpanel_bootstrap_lock.pytests/test_btpanel_bootstrap_loop.pytests/test_btpanel_client.pytests/test_btpanel_file_urls.pytests/test_btpanel_get_config.pytests/test_btpanel_login_url.pytests/test_btpanel_login_url_route.pytests/test_btpanel_server_list.pytests/test_btpanel_ssh_bootstrap.pytests/test_btpanel_ssh_login.pytests/test_btpanel_temp_login_ttl.py
执行命令:
python scripts\run_btpanel_tests.py
当前本机验证:按预期被 scripts/check_backend_test_env.py 阻断,因为当前是 Python 3.14。
关键输出:
ERROR: Nexus backend tests should be run with Python 3.12 or 3.13.
Python executable: C:\Python314\python.exe
Python version: 3.14.4
当前发布建议
- 本地每次准备发布
/app-v2或宝塔登录相关改动前,先跑python scripts\run_local_release_gate.py。 - 在 Python 3.12/3.13、Docker、WSL 或局域网 Linux 测试机里,再跑
python scripts\run_local_release_gate.py --with-pytest。 - 正式部署到
https://api.synaglobal.vip后,还需要线上实际验证/app-v2/、宝塔一键登录、多个宝塔并发打开、2 小时后刷新保持登录、新增宝塔 hardcoded_3600 兜底修复。
2026-07-08 追加:本轮继续验证与 Docker 测试入口补强
本轮完成事项
- 已把宝塔一键登录 API 路由的并发锁超时测试加入发布前 Gate。
- 已检查新增 Docker 测试脚本、宝塔路由测试脚本、发布 Gate 脚本,没有发现中文乱码占位符。
- 已重新执行本地发布前 Gate,结果通过。
- 已为 Docker Python 3.12 宝塔测试入口加入镜像拉取代理环境变量兜底,默认使用用户指定的 socks5 代理:
socks5://127.0.0.1:10808。 - 已尝试执行 Docker Python 3.12 宝塔测试入口;当前 Windows 环境未安装或不可用
docker命令,因此 Docker pytest 未能在本机完成。
本轮修改文件
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_local_release_gate.py
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_btpanel_tests_docker.cmd
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_btpanel_tests_docker.sh
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\tests\test_btpanel_login_url_route.py
发布前 Gate 当前覆盖
scripts/run_local_release_gate.py 当前会编译检查以下关键文件:
server/application/services/btpanel_service.pyserver/infrastructure/btpanel/bootstrap_lock.pyserver/infrastructure/btpanel/login_url_lock.pyserver/infrastructure/btpanel/ssh_bootstrap.pytests/test_btpanel_bootstrap_lock.pytests/test_btpanel_get_config.pytests/test_btpanel_login_url.pytests/test_btpanel_login_url_route.pytests/test_btpanel_ssh_bootstrap.pyscripts/check_backend_test_env.pyscripts/run_btpanel_tests.pyscripts/run_local_release_gate.py
其中 tests/test_btpanel_login_url_route.py 覆盖:同一宝塔一键登录 URL 正在签发时,LoginUrlLockTimeout 应映射为 HTTP 409,而不是返回 500 或误判成功。
本轮实际验证结果
执行:
python -m py_compile tests\test_btpanel_login_url_route.py scripts\run_btpanel_tests.py scripts\run_local_release_gate.py scripts\check_backend_test_env.py
结果:通过。
执行乱码扫描:
tests/test_btpanel_login_url_route.py
scripts/run_btpanel_tests_docker.cmd
scripts/run_btpanel_tests_docker.sh
scripts/run_btpanel_tests.py
scripts/run_local_release_gate.py
结果:
NO_BAD_TEXT
执行本地发布前 Gate:
python scripts\run_local_release_gate.py
结果:通过。关键输出:
tests/test_btpanel_login_url_route.py 已包含在 py_compile 目标内
[app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found
[release-gate] pytest skipped. Use --with-pytest under Python 3.12/3.13 to run BtPanel tests.
[release-gate] OK
执行 Docker Python 3.12 宝塔测试入口:
scripts\run_btpanel_tests_docker.cmd
当前结果:
ERROR: docker is not available
结论:Docker 测试入口脚本本身已就绪,但当前 Windows 环境没有可调用的 Docker CLI;这属于本机环境缺口,不是 Nexus 代码测试失败。
Docker 测试入口的代理行为
新增环境变量:
NEXUS_DOCKER_PULL_PROXY
默认值:
socks5://127.0.0.1:10808
如果不想走代理,可以执行前设置:
Windows CMD:
set NEXUS_DOCKER_PULL_PROXY=off
scripts\run_btpanel_tests_docker.cmd
Linux / WSL:
NEXUS_DOCKER_PULL_PROXY=off bash scripts/run_btpanel_tests_docker.sh
如果当前 Docker Desktop / Docker daemon 不读取 CLI 环境变量,则还需要在 Docker daemon 或 Docker Desktop 的代理设置里配置同一个 socks5 代理。
PowerShell 7+ 建议
PowerShell 7+ 对 UTF-8、Node、Python、Docker、SSH 更友好,建议安装并作为 Windows 本地默认 shell 使用。但 Nexus 的构建、pytest、Docker、批量 SSH 更推荐放到 WSL 或局域网 Linux 测试部署机执行。
稳定策略:
- Windows 本地用 PowerShell 7+ / CMD 执行轻量命令。
- 写中文 Markdown、批量改代码优先用 Node/Python UTF-8 API,不用 PowerShell 5.1 管道写文件。
- 后端 pytest 使用 Python 3.12/3.13、Docker Python 3.12、WSL 或局域网 Linux 测试机,不使用本机 Python 3.14。
下一步
-
在 Docker 可用的环境里执行:
scripts\run_btpanel_tests_docker.cmd或:
bash scripts/run_btpanel_tests_docker.sh -
如果仍在 Windows 本机执行,需要先安装 Docker Desktop 或改用 WSL/Linux 测试部署机。
-
Docker pytest 通过后,再发布到正式环境
https://api.synaglobal.vip。 -
发布后线上验证:
/app-v2/、宝塔一键登录、并发打开同一宝塔返回 409 兜底、多个宝塔 2 小时后刷新不掉线、新增宝塔自动检测/修复 hardcoded_3600。
2026-07-08 追加:Python 3.12 完整发布前 Gate 已跑通
本轮结论
已不再依赖本机 Python 3.14,也不再被本机 Docker 不可用卡住。使用 Codex bundled Python 3.12.13 创建了独立虚拟环境,并成功跑完整发布前 Gate:
py_compile + /app-v2 build:safe + 宝塔相关 pytest
最终结果:
[release-gate] OK
60 passed in 6.73s
新增 / 修改点
1. Python 3.12 测试虚拟环境
位置:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\.venv-py312-codex
Python 版本:
Python 3.12.13
依赖已安装:
requirements.txt
requirements-dev.txt
2. Windows 测试环境补充 tzdata
文件:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\requirements-dev.txt
新增:
tzdata>=2025.2
原因:
Windows Python 环境没有系统 IANA 时区库,ZoneInfo("Asia/Shanghai") 会报错。Nexus 测试导入 server.utils.display_time 时需要这个时区数据。
3. server/main.py 支持 Windows host-side 测试
文件:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\server\main.py
变更:
- Linux / 生产环境继续使用
fcntl.flock。 - Windows 测试环境没有
fcntl,增加 host-side fallback,避免导入server.main时直接失败。 - 该 fallback 只用于 Windows 本地测试兼容;生产 Linux 仍走原来的非阻塞 flock。
4. 宝塔测试入口参数转发修复
文件:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_btpanel_tests.py
修复:
-
支持向 pytest 透传参数。
-
示例:
python scripts\run_btpanel_tests.py -- -q
5. SSH bootstrap 测试导入修复
文件:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\tests\test_btpanel_ssh_bootstrap.py
修复:
- 新增
ssh_bootstrap_module导入,保证monkeypatch.setattr(...)能正确 patchexec_ssh_command。 - 新增
ssh_bootstrap_panel导入,覆盖BootstrapRemoteError.permanent透传测试。
6. release gate 覆盖增强
文件:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042\scripts\run_local_release_gate.py
新增 py_compile 覆盖:
server/main.py
这样 Windows fcntl fallback 和静态挂载入口也进入发布前语法检查。
实际执行命令
创建 Python 3.12 venv:
C:\Users\uzuma\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe -m venv .venv-py312-codex
安装依赖:
.venv-py312-codex\Scripts\python.exe -m pip install -r requirements.txt -r requirements-dev.txt
单独跑宝塔测试:
.venv-py312-codex\Scripts\python.exe scripts\run_btpanel_tests.py -- -q
结果:
60 passed in 1.70s
完整发布前 Gate:
.venv-py312-codex\Scripts\python.exe scripts\run_local_release_gate.py --with-pytest
关键输出:
[app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found
collected 60 items
60 passed in 6.73s
[release-gate] OK
已覆盖的宝塔测试文件
tests/test_btpanel_bootstrap_lock.pytests/test_btpanel_bootstrap_loop.pytests/test_btpanel_client.pytests/test_btpanel_file_urls.pytests/test_btpanel_get_config.pytests/test_btpanel_login_url.pytests/test_btpanel_login_url_route.pytests/test_btpanel_server_list.pytests/test_btpanel_ssh_bootstrap.pytests/test_btpanel_ssh_login.pytests/test_btpanel_temp_login_ttl.py
本轮额外安全检查
已检查本轮改动文件:
server/main.py
requirements-dev.txt
scripts/run_local_release_gate.py
scripts/run_btpanel_tests.py
tests/test_btpanel_ssh_bootstrap.py
检查结果:
NO_BAD_TEXT_OR_SECRET
也确认之前因 Windows CMD > 语义误生成的临时文件已删除:
redirect_file_exists False
当前发布判断
本地快照层面,宝塔一键登录相关代码已经具备更强发布前证据:
- Python 3.12 环境检查通过。
- 宝塔 60 个 pytest 全部通过。
/app-v2构建通过。/app-v2构建产物敏感信息扫描通过。- release gate 已包含 pytest,最终
[release-gate] OK。
下一步可以进入发布环节,但发布到 https://api.synaglobal.vip 后仍需要线上实际验证:
/app-v2/是否可访问。- 宝塔一键登录是否成功。
- 同一台宝塔短时间重复点击是否返回 409 兜底。
- 同时打开多个宝塔后,2 小时刷新是否不再陆续掉线。
- 新增宝塔是否自动检测并修复 hardcoded_3600。
2026-07-08 追加:发布差异清单与发布前清单
新增文档
差异清单:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-diff-manifest-20260708.md
发布前清单:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-ready-checklist-20260708.md
当前差异统计
已排除 .venv-*、node_modules、.pytest_cache、__pycache__、*.bak-、2025.2、=2025.2、tmp/nexus-frontend.tar.gz 等不应发布内容后:
added=381
modified=26
deleted=347
发布候选安全扫描
执行:
.venv-py312-codex\Scripts\python.exe scripts\scan_release_manifest.py --root C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 --manifest C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-diff-manifest-20260708.md
结果:
OK: no known environment leak markers found in release manifest entries
最新完整 Gate
执行:
.venv-py312-codex\Scripts\python.exe scripts\run_local_release_gate.py --with-pytest
结果:
[app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found
60 passed in 1.79s
[release-gate] OK
干净发布包
已生成并扫描:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz
扫描结果:
size_mb=27.02
entries=2409
OK: release bundle looks clean
本轮还修复了 .dockerignore 与 deploy/rsync-local-to-server.sh,避免发布时同步 frontend-v2/node_modules、.venv-*、.pytest_cache、2025.2、*.bak- 等脏文件。
2026-07-08 追加:部署脚本和发布后验证补强
新增:
scripts/check_deploy_excludes.py
scripts/verify_online_release.py
发布前 Gate 已加入:
bash -n deploy/deploy-production.sh
bash -n deploy/rsync-local-to-server.sh
python scripts/check_deploy_excludes.py
deploy/deploy-production.sh 发布后健康检查已增加 /app-v2/,不再只检查旧 /app/。
发布后可执行:
.venv-py312-codex\Scripts\python.exe scripts\verify_online_release.py --base-url https://api.synaglobal.vip
本轮尝试线上 SSH 只读探测时,Codex 审批系统返回 404 并拒绝执行;因此尚未实际发布线上。
2026-07-08 追加:/app-v2 发布同步路径补强
已补强:
deploy/deploy-production.sh
deploy/sync_webapp_to_container.sh
scripts/run_local_release_gate.py
变化:
deploy/deploy-production.sh现在会显式执行frontend-v2的npm run build:safe。- 发布脚本会把
web/app-v2/index.html与web/app-v2/assets/打包上传到宿主机。 - Docker 运行时的
sync_webapp_to_container.sh会同步web/app-v2到容器/app/web/app-v2。 - 容器同步脚本会校验
/app-v2/主 bundle 是否 HTTP 200。 - release gate 已加入
bash -n deploy/sync_webapp_to_container.sh。
最新验证:
60 passed in 1.70s
[release-gate] OK
发布包重新生成并扫描:
files=2409
entries=2409
OK: release bundle looks clean
2026-07-08 追加:发布包 SHA256 与手动部署命令
发布包:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz
SHA256:
46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
元数据:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.metadata.json
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-artifact-metadata-20260708.md
手动部署命令:
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-manual-deploy-commands-20260708.md
最新 Gate:
60 passed in 1.70s
[release-gate] OK
2026-07-08 追加:服务器侧发布包应用脚本
新增:
deploy/apply-release-bundle.sh
用途:
- 在线上服务器校验发布包 SHA256。
- 校验发布包必需路径和禁止路径。
- 自动备份当前部署目录。
- rsync 覆盖代码但保留
.env、docker/.env.prod、web/data。 - Docker 模式下执行
nexus-1panel.sh upgrade --skip-git。 - 同步
/app/与/app-v2/到容器。 - 验证本机
/health、/app/、/app-v2/。
最新发布包:
entries=2409
SHA256=46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
2026-07-08 validate-only verification
The server-side release applier now supports validate-only mode.
Command verified locally with Git Bash:
bash deploy/apply-release-bundle.sh --validate-only --tarball /c/Users/uzuma/Documents/Codex/2026-07-06/yuu/outputs/nexus-release-20260708.tar.gz --sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
`
Result:
` ext
SHA256 OK: 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
Extracted release tree validation OK
Validate-only mode: tarball checksum and content validation passed
`
Network/SSH production execution is still not performed because Codex approval auto-review returned HTTP 404 for read-only checks.
## 2026-07-08 one-command local artifact preparation
A single local command now prepares and verifies the release artifact end-to-end:
`cmd
.venv-py312-codex\Scripts\python.exe scripts\prepare_release_artifact.py --old-snapshot C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-070236 --output-dir C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs --name nexus-release-20260708
`
Verified result:
` ext
[prepare-release-artifact] OK
added=381 modified=26 deleted=347
files=2409
entries=2409
size_mb=27.02
sha256=46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
60 passed in 1.70s
`