From efaceb7a970516f464fc174bfa682383c3130314 Mon Sep 17 00:00:00 2001 From: sunlei Date: Fri, 12 Jun 2026 13:21:39 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=9B=BA=E5=8C=96QQBot=E5=AE=A1?= =?UTF-8?q?=E6=9F=A5=E6=8A=A4=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/selfTest.ts | 17 ++++++++++++++++- src/tools/review.ts | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ed62e5..e7c1a7f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ - 生成验证进程清理计划:按项目路径和端口给出 PowerShell 检查命令,不直接杀进程。 - 清理历史产物:统一治理 `.kt-workspace` 下的测试/验证产物,按目录最近修改时间只保留最近 3 轮,模板目录永久保留;CLI 默认 dry-run,真实清理必须显式传 `--execute`。 - 检查 env 策略和变更风险:区分后端真实 env 与前端客户端 `.env*`,提醒锁文件、核心表格组件、部署链路和 Vue TSX 插槽写法等高风险改动。 -- 全局 CodeReview 只读扫描:汇总全部 KT 子仓库的 Git 状态、敏感文件跟踪、冲突标记、运行时调试输出、疑似凭据字面量、NapCat `latest` 镜像漂移风险、根目录生成产物、`TASKS.md` 最近记录字段结构和当前变更风险;默认只对变更文件做内容扫描,并放过短中文显示标签,避免历史误报污染上下文;任何文件改动后都要跑一遍。 +- 全局 CodeReview 只读扫描:汇总全部 KT 子仓库的 Git 状态、敏感文件跟踪、冲突标记、运行时调试输出、疑似凭据字面量、NapCat `latest` 镜像漂移风险、QQBot 重型服务单测导入风险、根目录生成产物、`TASKS.md` 最近记录字段结构和当前变更风险;默认只对变更文件做内容扫描,并放过短中文显示标签,避免历史误报污染上下文;任何文件改动后都要跑一遍。 - 生成或写入 `TASKS.md` 最近记录:默认 `dryRun=true`,确认后再落盘。 - 生成提交前检查清单:校验 KT commit message 约定。 @@ -106,7 +106,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login | 脚本 | 用途 | | --- | --- | | `pnpm run admin-login` | 使用可见 Edge 打开 Admin 登录页,填写账号密码,拖动滑块,保存登录态和截图。默认账号来自初始化数据 `admin/123456`,生产或个人账号用 `KT_ADMIN_USERNAME` / `KT_ADMIN_PASSWORD` 或 CLI 参数覆盖。 | -| `pnpm run global-review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅对变更文件做内容深扫,输出 JSON 复审报告,并校验 `TASKS.md` 最近记录只保留范围、关键词、验证字段;确认误报时优先升级 `src/tools/review.ts`,不要把误报沉积到上下文。 | +| `pnpm run global-review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅对变更文件做内容深扫,输出 JSON 复审报告,并校验 `TASKS.md` 最近记录只保留范围、关键词、验证字段、NapCat `latest` 漂移和 QQBot 重型服务单测导入风险;确认误报时优先升级 `src/tools/review.ts`,不要把误报沉积到上下文。 | | `pnpm run obsidian-context` | 输出 Obsidian 索引上下文;可传 `--module Admin`、`--query QQBot`、`--max-documents 10`。 | | `pnpm run obsidian-validate` | 校验 KT Obsidian vault 结构和链接;默认 warning 不让脚本失败,需要严格模式时传 `--fail-on-warnings`。 | | `pnpm run obsidian-sync` | 审计 Obsidian 工作流入口是否连通,并联动执行 validate。 | diff --git a/src/selfTest.ts b/src/selfTest.ts index 26449bb..1cd38b7 100644 --- a/src/selfTest.ts +++ b/src/selfTest.ts @@ -12,7 +12,7 @@ import { cleanupHistoryArtifacts, parseCliCleanupArgs } from './tools/cleanup.js import { buildWorkflowLoopAudit } from './tools/loop.js'; import { inspectProject } from './tools/inspect.js'; import { prepareTask, readWorkflowContext } from './tools/task.js'; -import { buildGlobalCodeReview, findNapcatImageGovernanceFindings, findTaskRecordGovernanceFindings, isBenignCredentialReviewValue } from './tools/review.js'; +import { buildGlobalCodeReview, findNapcatImageGovernanceFindings, findQqbotCommandServiceTestImportFindings, findTaskRecordGovernanceFindings, isBenignCredentialReviewValue } from './tools/review.js'; import { buildBusinessTestPlan } from './tools/testing.js'; import { buildVerificationPlan } from './tools/verification.js'; import { buildWorkstreamCloseout } from './tools/closeout.js'; @@ -50,6 +50,21 @@ export async function runSelfTest(): Promise { throw new Error('NapCat image governance self-check failed'); } + const qqbotCommandServiceImportFindings = findQqbotCommandServiceTestImportFindings( + ["import { QqbotCommandService } from '@/qqbot/command/qqbot-command.service';"], + { + file: 'test/qqbot/command/qqbot-command-cooldown.service.spec.ts', + project: 'Node/kt-template-online-api', + }, + ); + if ( + !qqbotCommandServiceImportFindings.some( + (item) => item.category === 'qqbot-command-service-heavy-test-import', + ) + ) { + throw new Error('QQBot command service test import governance self-check failed'); + } + const reviewCliParser = { dashedAll: parseGlobalReviewCliArgs(['node', 'server', '--global-review', '--content-scan-all']).contentScanMode, keyValueAll: parseGlobalReviewCliArgs(['node', 'server', '--global-review', '--contentScanMode=all']).contentScanMode, diff --git a/src/tools/review.ts b/src/tools/review.ts index 8eb7dcc..821633e 100644 --- a/src/tools/review.ts +++ b/src/tools/review.ts @@ -186,6 +186,39 @@ export function findNapcatImageGovernanceFindings( }); } +export function findQqbotCommandServiceTestImportFindings( + lines: string[], + context: { + file: string; + project: string; + }, +): ReviewFinding[] { + const normalized = context.file.replaceAll('\\', '/'); + if ( + context.project !== 'Node/kt-template-online-api' || + !normalized.startsWith('test/qqbot/') || + !normalized.endsWith('.ts') + ) { + return []; + } + + return lines.flatMap((line, index) => { + if (!/from\s+['"][^'"]*qqbot-command\.service['"]/.test(line)) return []; + + return [ + { + category: 'qqbot-command-service-heavy-test-import', + file: context.file, + line: index + 1, + level: 'P2' as const, + message: 'QQBot 测试直接导入 QqbotCommandService,容易拖入插件注册和 BangDream runtime 导致单测卡住。', + project: context.project, + suggestion: '把纯策略抽到轻量函数测试,或通过 Nest TestingModule 明确 mock 掉插件 registry/runtime 依赖。', + }, + ]; + }); +} + async function listGitTrackedFiles(projectPath: string): Promise { const tracked = await tryExecFile('git', ['ls-files'], projectPath); if (!tracked.ok) return []; @@ -363,6 +396,10 @@ function collectProjectContentFindings( file, project: project.relativePath, }), + ...findQqbotCommandServiceTestImportFindings(lines, { + file, + project: project.relativePath, + }), ); }