6ee6fd64dd
Introduce page edit sessions with draft preview and patch API, chat skill picker, user memory profile, h5ApiBase resolution, voice WAV transport, and scripts for 105/g2 deployment and Plaza local dev. Co-authored-by: Cursor <cursoragent@cursor.com>
124 lines
4.0 KiB
JavaScript
124 lines
4.0 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* Diagnose local Plaza setup and print fix hints.
|
||
*/
|
||
import fs from 'node:fs';
|
||
import net from 'node:net';
|
||
import dns from 'node:dns';
|
||
import { promisify } from 'node:util';
|
||
import https from 'node:https';
|
||
|
||
const host = process.env.PLAZA_LOCAL_HOST ?? 'plaza.tkmind.cn';
|
||
const dnsPort = Number(process.env.PLAZA_LOCAL_DNS_PORT ?? 5533);
|
||
const plazaPort = Number(process.env.PLAZA_PORT ?? 3001);
|
||
const portalPort = Number(process.env.H5_PORT ?? 8081);
|
||
|
||
const lookup = promisify(dns.lookup);
|
||
const resolve4 = promisify(dns.resolve4);
|
||
|
||
function tcpOpen(port, bind = '127.0.0.1') {
|
||
return new Promise((resolve) => {
|
||
const s = net.connect(port, bind, () => {
|
||
s.end();
|
||
resolve(true);
|
||
});
|
||
s.on('error', () => resolve(false));
|
||
s.setTimeout(2000, () => {
|
||
s.destroy();
|
||
resolve(false);
|
||
});
|
||
});
|
||
}
|
||
|
||
function httpsPlaza() {
|
||
return new Promise((resolve) => {
|
||
const req = https.request(
|
||
{
|
||
hostname: host,
|
||
port: 443,
|
||
path: '/plaza',
|
||
rejectUnauthorized: false,
|
||
timeout: 3000,
|
||
},
|
||
(res) => resolve({ ok: res.statusCode === 200, code: res.statusCode }),
|
||
);
|
||
req.on('error', (err) => resolve({ ok: false, error: err.message }));
|
||
req.on('timeout', () => {
|
||
req.destroy();
|
||
resolve({ ok: false, error: 'timeout' });
|
||
});
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
const issues = [];
|
||
const ok = [];
|
||
|
||
// hosts
|
||
try {
|
||
const hosts = fs.readFileSync('/etc/hosts', 'utf8');
|
||
if (new RegExp(`127\\.0\\.0\\.1\\s+${host.replace('.', '\\.')}`).test(hosts)) ok.push('hosts 已指向 127.0.0.1');
|
||
else issues.push(`执行:sudo pnpm setup:plaza-dns`);
|
||
} catch {
|
||
issues.push('无法读取 /etc/hosts');
|
||
}
|
||
|
||
// resolver
|
||
try {
|
||
const body = fs.readFileSync(`/etc/resolver/${host}`, 'utf8');
|
||
if (body.includes(`port ${dnsPort}`)) ok.push(`resolver -> 127.0.0.1:${dnsPort}`);
|
||
else issues.push(`resolver 端口不对,执行:sudo pnpm setup:plaza-dns`);
|
||
} catch {
|
||
issues.push(`缺少 /etc/resolver/${host},执行:sudo pnpm setup:plaza-dns`);
|
||
}
|
||
|
||
// services
|
||
if (await tcpOpen(dnsPort)) ok.push(`本地 DNS :${dnsPort} 运行中`);
|
||
else issues.push(`本地 DNS 未运行,执行:pnpm dev:plaza-dns(或 pnpm dev:plaza)`);
|
||
|
||
if (await tcpOpen(plazaPort)) ok.push(`Plaza Next.js :${plazaPort} 运行中`);
|
||
else issues.push(`Plaza 未运行,执行:pnpm dev:plaza`);
|
||
|
||
if (await tcpOpen(portalPort)) ok.push(`Portal :${portalPort} 运行中`);
|
||
else issues.push(`Portal 未运行(dev:plaza 会自动启动)`);
|
||
|
||
if (await tcpOpen(443)) ok.push('HTTPS 代理 :443 运行中');
|
||
else issues.push('HTTPS 代理未运行,执行:sudo pnpm dev:plaza-proxy');
|
||
|
||
// DNS resolution
|
||
const looked = await lookup(host, { all: true });
|
||
const addrs = looked.map((x) => x.address);
|
||
if (addrs.every((a) => a === '127.0.0.1' || a.startsWith('::ffff:127.'))) {
|
||
ok.push(`系统 DNS lookup -> ${addrs.join(', ')}`);
|
||
} else {
|
||
issues.push(`系统 DNS 仍含非本地地址:${addrs.join(', ')}(Tailscale fake-ip)`);
|
||
}
|
||
|
||
try {
|
||
const r4 = await resolve4(host);
|
||
if (r4.some((a) => a !== '127.0.0.1')) {
|
||
issues.push(`resolve4 -> ${r4.join(', ')}(浏览器 Secure DNS 可能走线上 Cloudflare)`);
|
||
}
|
||
} catch {
|
||
// ignore
|
||
}
|
||
|
||
const httpsResult = await httpsPlaza();
|
||
if (httpsResult.ok) ok.push(`终端 HTTPS ${host}/plaza -> ${httpsResult.code}`);
|
||
else issues.push(`终端 HTTPS 失败:${httpsResult.error ?? httpsResult.code}`);
|
||
|
||
console.log('\n=== Plaza 本地诊断 ===\n');
|
||
for (const line of ok) console.log(`✓ ${line}`);
|
||
for (const line of issues) console.log(`✗ ${line}`);
|
||
|
||
console.log('\n--- 浏览器仍失败?---');
|
||
console.log('Chrome/Cursor 内置浏览器默认走「安全 DNS」,会绕过 /etc/hosts 连到线上 Cloudflare。');
|
||
console.log('');
|
||
console.log('解决:');
|
||
console.log(' 1. pnpm open:plaza # 用 Chrome 强制解析到本机');
|
||
console.log(' 2. 或关闭浏览器「安全 DNS / Secure DNS」后刷新');
|
||
console.log(' 3. 或临时访问 http://127.0.0.1:3001/plaza');
|
||
console.log('');
|
||
|
||
process.exit(issues.length ? 1 : 0);
|