同步 enhance/bridge/smoke/retire 模块、vendor 3.3.34、增强面板与 PRD 文档, Hub 接入 hub-routes-prd,含安装/经验/模块说明与 co-integration 运维脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
79 lines
2.6 KiB
JavaScript
79 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const http = require('http');
|
|
|
|
function httpCheck(url) {
|
|
return new Promise((resolve) => {
|
|
const req = http.get(url, (res) => {
|
|
res.resume();
|
|
resolve({ ok: res.statusCode >= 200 && res.statusCode < 400, status: res.statusCode });
|
|
});
|
|
req.on('error', (e) => resolve({ ok: false, error: String(e.message || e) }));
|
|
req.setTimeout(8000, () => { req.destroy(); resolve({ ok: false, error: 'timeout' }); });
|
|
});
|
|
}
|
|
|
|
function httpPost(url, body) {
|
|
return new Promise((resolve) => {
|
|
const data = JSON.stringify(body);
|
|
const u = new URL(url);
|
|
const req = http.request({
|
|
hostname: u.hostname,
|
|
port: u.port || 80,
|
|
path: u.pathname,
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
|
|
}, (res) => {
|
|
let raw = '';
|
|
res.on('data', (c) => { raw += c; });
|
|
res.on('end', () => {
|
|
try {
|
|
resolve({ ok: res.statusCode >= 200 && res.statusCode < 400, status: res.statusCode, json: JSON.parse(raw || '{}') });
|
|
} catch {
|
|
resolve({ ok: false, status: res.statusCode, json: {} });
|
|
}
|
|
});
|
|
});
|
|
req.on('error', (e) => resolve({ ok: false, error: String(e.message || e) }));
|
|
req.write(data);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
async function runSmoke(baseUrl) {
|
|
const base = baseUrl.replace(/\/$/, '');
|
|
const checks = [
|
|
{ name: 'panel', url: `${base}/` },
|
|
{ name: 'state', url: `${base}/api/state` },
|
|
{ name: 'prd', url: `${base}/api/prd/progress` },
|
|
{ name: 'enhance-status', url: `${base}/api/enhance/status` },
|
|
{ name: 'enhance-diagnose', url: `${base}/api/enhance/diagnose` },
|
|
{ name: 'mode-check', url: `${base}/api/mode/check` },
|
|
{ name: 'templates', url: `${base}/api/templates` },
|
|
{ name: 'retire-check', url: `${base}/api/retire/check` },
|
|
];
|
|
const results = [];
|
|
let fail = 0;
|
|
for (const c of checks) {
|
|
const r = await httpCheck(c.url);
|
|
results.push({ name: c.name, ok: r.ok, status: r.status, error: r.error });
|
|
if (!r.ok) fail += 1;
|
|
}
|
|
const created = await httpPost(`${base}/api/new`, { title: 'smoke-bridge' });
|
|
if (!created.ok || !created.json?.token) {
|
|
results.push({ name: 'new-session', ok: false });
|
|
fail += 1;
|
|
} else {
|
|
const bridged = await httpPost(`${base}/api/bridge/sync`, {
|
|
token: created.json.token,
|
|
content: 'smoke test conclusion',
|
|
});
|
|
const ok = !!(bridged.ok && bridged.json?.ok);
|
|
results.push({ name: 'bridge', ok });
|
|
if (!ok) fail += 1;
|
|
}
|
|
return { ok: fail === 0, fail, results, ranAt: new Date().toISOString() };
|
|
}
|
|
|
|
module.exports = { runSmoke };
|