chore(client): add digital employee check

This commit is contained in:
baiyanyun
2026-06-08 10:36:19 +08:00
parent 700f6a40b8
commit 8dc9ce73b9
3 changed files with 113 additions and 0 deletions

View File

@@ -15,6 +15,7 @@
"build:renderer": "vite build",
"sync:sgrobot-digital": "node scripts/sync-sgrobot-digital.js",
"build:sgrobot-digital": "node scripts/build-sgrobot-digital.js",
"check:digital-employee": "node scripts/check-digital-employee.js",
"build": "dotenv -e .env.production -- cross-env NODE_ENV=production npm run build:main && npm run build:renderer",
"test": "vitest",
"test:run": "vitest run",

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env node
const fs = require("fs");
const os = require("os");
const path = require("path");
const { spawnSync } = require("child_process");
const packageRoot = path.resolve(__dirname, "..");
const requiredDigitalTables = [
"digital_plans",
"digital_tasks",
"digital_runs",
"digital_events",
"digital_artifacts",
"digital_approvals",
"digital_sync_outbox",
"digital_sync_attempts",
];
const testFiles = [
"src/main/services/digitalEmployee/stateService.test.ts",
"src/main/ipc/eventForwarders.test.ts",
"src/main/services/digitalEmployee/syncService.test.ts",
"src/main/services/digitalEmployee/skillCatalogService.test.ts",
"src/main/services/digitalEmployee/planTemplateService.test.ts",
];
function runStep(title, command, args, options = {}) {
console.log(`\n[DigitalEmployeeCheck] ${title}`);
const result = spawnSync(command, args, {
cwd: packageRoot,
stdio: "inherit",
shell: process.platform === "win32",
...options,
});
if (result.status !== 0) {
process.exitCode = result.status || 1;
throw new Error(`${title} failed`);
}
}
function checkSgrobotDigitalAssets() {
console.log("\n[DigitalEmployeeCheck] Verify embedded digital assets");
const indexPath = path.join(packageRoot, "public", "sgrobot-digital", "index.html");
const html = fs.readFileSync(indexPath, "utf8");
const assetRefs = [...html.matchAll(/(?:src|href)="\.\/(assets\/[^"]+)"/g)]
.map((match) => match[1]);
if (assetRefs.length === 0) {
throw new Error("No embedded digital assets referenced by index.html");
}
for (const assetRef of assetRefs) {
const assetPath = path.join(packageRoot, "public", "sgrobot-digital", assetRef);
if (!fs.existsSync(assetPath)) {
throw new Error(`Missing embedded digital asset: ${assetRef}`);
}
}
console.log(`[DigitalEmployeeCheck] ${assetRefs.length} asset references OK`);
}
function checkLocalDatabaseSchema() {
console.log("\n[DigitalEmployeeCheck] Verify local SQLite digital schema");
const dbPath = path.join(os.homedir(), ".qimingclaw", "qimingclaw.db");
if (!fs.existsSync(dbPath)) {
console.log(`[DigitalEmployeeCheck] Skip DB schema check; database not found: ${dbPath}`);
return;
}
const result = spawnSync("sqlite3", [dbPath, ".tables"], {
encoding: "utf8",
shell: process.platform === "win32",
});
if (result.error) {
console.log(`[DigitalEmployeeCheck] Skip DB schema check; sqlite3 unavailable: ${result.error.message}`);
return;
}
if (result.status !== 0) {
throw new Error(result.stderr || "sqlite3 .tables failed");
}
const tables = new Set(result.stdout.split(/\s+/).filter(Boolean));
const missing = requiredDigitalTables.filter((table) => !tables.has(table));
if (missing.length > 0) {
throw new Error(`Missing digital employee tables: ${missing.join(", ")}`);
}
console.log(`[DigitalEmployeeCheck] ${requiredDigitalTables.length} digital tables OK`);
}
function main() {
try {
runStep("Run digital employee unit tests", "npm", ["run", "test:run", "--", ...testFiles]);
runStep("Build Electron main process", "npm", ["run", "build:main:dev"]);
runStep("Build embedded digital employee", "npm", ["run", "build:sgrobot-digital"]);
checkSgrobotDigitalAssets();
checkLocalDatabaseSchema();
console.log("\n[DigitalEmployeeCheck] All checks passed");
} catch (error) {
console.error(`\n[DigitalEmployeeCheck] ${error instanceof Error ? error.message : String(error)}`);
process.exit(process.exitCode || 1);
}
}
main();

View File

@@ -1122,6 +1122,7 @@ User
- qimingclaw 内有数字员工前端源码目录。
- `public/sgrobot-digital` 可由脚本生成。
- `npm run check:digital-employee` 可重复验证数字员工关键单测、main build、embedded build、静态资源引用和本机 SQLite digital schema。
- 不启动 sgRobot 后端也能打开“概览”。
- “概览”直接显示数字员工页面。
- 不出现 sgRobot 配对页。
@@ -1129,6 +1130,15 @@ User
- sgRobot 仓库不参与 qimingclaw 提交。
- `npm run build:renderer` 通过。
### 本地验证入口
```bash
cd crates/agent-electron-client
npm run check:digital-employee
```
该命令不启动 sgRobot daemon。本机已有 `~/.qimingclaw/qimingclaw.db` 时会检查 `digital_*` 表;数据库尚未生成或 `sqlite3` 不可用时只跳过 schema 检查,代码回归仍继续执行。
## 最终验收标准
整个融合完成后,应满足: