Files
卡若AI ba786b3700 feat: Persistent Chat v1.1 CO-Chat 整合上传 Gitea
同步 enhance/bridge/smoke/retire 模块、vendor 3.3.34、增强面板与 PRD 文档,
Hub 接入 hub-routes-prd,含安装/经验/模块说明与 co-integration 运维脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 17:42:16 +08:00

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 };