| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- 'use strict';
- const assert = require('assert/strict');
- const fs = require('fs');
- const os = require('os');
- const path = require('path');
- const { spawnSync } = require('child_process');
- const { resolveWorkspaceRoot, workspaceIdentity } = require('../mcp/src/core/runtime-context');
- const { buildStartupSummary, startupAssistantMessage } = require('../mcp/src/core/startup-summary');
- const ROOT = path.resolve(__dirname, '..');
- function testRuntimeContext(tempRoot) {
- const installedPackage = path.join(tempRoot, '.claude', 'plugins', 'qiwei-assistant');
- fs.mkdirSync(installedPackage, { recursive: true });
- assert.equal(resolveWorkspaceRoot({ packageRoot: installedPackage, cwd: installedPackage }), tempRoot);
- assert.equal(resolveWorkspaceRoot({ packageRoot: ROOT, workspaceRoot: tempRoot }), tempRoot);
- assert.match(workspaceIdentity(tempRoot), /^[0-9a-f]{12}$/);
- }
- function testStartupSummary() {
- const offline = buildStartupSummary(
- { summary: { authConfigured: true, subscribed: true } },
- { data: { account: { configured: true, online: false }, listener: { running: false }, config: { allowedSenderCount: 1 } } },
- );
- assert.equal(offline.ready, false);
- assert.equal(offline.nextAction, '在工作台点击“恢复登录”');
- assert.match(startupAssistantMessage(offline), /企微账号待处理/);
- const ready = buildStartupSummary(
- { summary: { authConfigured: true, subscribed: true } },
- { data: { account: { configured: true, online: true }, listener: { running: true }, config: { allowedSenderCount: 1 } } },
- );
- assert.equal(ready.ready, true);
- assert.match(ready.nextAction, /可以进入智能会话/);
- }
- function testWorkspaceInstall(tempRoot) {
- const target = path.join(tempRoot, 'customer-project');
- fs.mkdirSync(target, { recursive: true });
- fs.writeFileSync(path.join(target, '.gitignore'), '# Customer rules\ncustomer-cache/\n', 'utf8');
- const result = spawnSync(process.execPath, [path.join(ROOT, 'install.js'), 'workspace', target, '--skip-install'], {
- cwd: ROOT,
- encoding: 'utf8',
- windowsHide: true,
- });
- assert.equal(result.status, 0, result.stderr || result.stdout);
- const mcp = JSON.parse(fs.readFileSync(path.join(target, '.mcp.json'), 'utf8'));
- const config = mcp.mcpServers?.['qiwei-assistant'];
- assert.equal(config.cwd, target);
- assert.equal(config.env?.QIWEI_WORKSPACE_ROOT, target);
- assert.equal(config.env?.QIWEI_OUTPUTS_DIR, path.join(target, 'outputs'));
- assert.equal(config.env?.CLAUDE_CODE_WORKDIR, target);
- assert(fs.existsSync(path.join(target, '.claude', 'plugins', 'qiwei-assistant', 'scripts', 'preview-dashboard.js')));
- assert(!fs.existsSync(path.join(target, '.claude', 'plugins', 'qiwei-assistant', '.env.local')));
- const gitignorePath = path.join(target, '.gitignore');
- const firstGitignore = fs.readFileSync(gitignorePath, 'utf8');
- assert.match(firstGitignore, /# Customer rules\ncustomer-cache\//);
- assert.match(firstGitignore, /# >>> qiwei-assistant managed ignores >>>/);
- assert.match(firstGitignore, /\*\*\/\.env\.local/);
- assert.match(firstGitignore, /outputs\/messages\/\*\.db/);
- const repeated = spawnSync(process.execPath, [path.join(ROOT, 'install.js'), 'workspace', target, '--skip-install'], {
- cwd: ROOT,
- encoding: 'utf8',
- windowsHide: true,
- });
- assert.equal(repeated.status, 0, repeated.stderr || repeated.stdout);
- const secondGitignore = fs.readFileSync(gitignorePath, 'utf8');
- assert.equal((secondGitignore.match(/# >>> qiwei-assistant managed ignores >>>/g) || []).length, 1);
- assert.match(secondGitignore, /# Customer rules\ncustomer-cache\//);
- }
- function testRuntimeProcessSeparation() {
- const previewSource = fs.readFileSync(path.join(ROOT, 'scripts', 'preview-dashboard.js'), 'utf8');
- const dashboardSource = fs.readFileSync(path.join(ROOT, 'scripts', 'start-dashboard.js'), 'utf8');
- const serverSource = fs.readFileSync(path.join(ROOT, 'mcp', 'src', 'server.js'), 'utf8');
- assert.doesNotMatch(previewSource, /\.startRuntime\s*\(/);
- assert.match(previewSource, /ensureRelayDaemon\s*\(/);
- assert.match(dashboardSource, /ensureRelayDaemon\s*\(/);
- assert.match(serverSource, /ensureRelayDaemon\s*\(/);
- }
- function testAgentWorkbenchOfflineStartup() {
- const appSource = fs.readFileSync(path.join(ROOT, 'mcp', 'src', 'dashboard', 'app.js'), 'utf8');
- const renderAgentSource = appSource.slice(
- appSource.indexOf('function renderAgentPage()'),
- appSource.indexOf('// ==================== Login ===================='),
- );
- assert.match(renderAgentSource, /if \(!state\.bootstrapping\)\s+startAgentPageRuntime\(page\)/);
- assert.match(appSource, /state\.page === 'agent'[\s\S]*startAgentPageRuntime\(els\.content\.querySelector\('\.agent-page'\)\)/);
- assert.match(appSource, /api\('GET', '\/api\/status'\)/);
- assert.match(appSource, /api\('GET', '\/api\/agent\/status', undefined, 4000\)/);
- }
- function main() {
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-preview-smoke-'));
- try {
- testRuntimeContext(tempRoot);
- testStartupSummary();
- testWorkspaceInstall(tempRoot);
- testRuntimeProcessSeparation();
- testAgentWorkbenchOfflineStartup();
- } finally {
- fs.rmSync(tempRoot, { recursive: true, force: true });
- }
- process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 5 }, null, 2)}\n`);
- }
- try { main(); }
- catch (error) {
- process.stderr.write(`${error.message}\n`);
- process.exit(1);
- }
|