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>
117 lines
3.7 KiB
JavaScript
117 lines
3.7 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* Map plaza.tkmind.cn -> 127.0.0.1 for local Plaza dev.
|
||
* Requires sudo to edit /etc/hosts and /etc/resolver.
|
||
*
|
||
* macOS + Tailscale/Clash fake-ip: /etc/hosts alone is not enough — browsers may
|
||
* still resolve 198.18.x.x. Per-domain resolver forces local DNS server.
|
||
*
|
||
* Usage:
|
||
* node scripts/setup-plaza-local-dns.mjs
|
||
* node scripts/setup-plaza-local-dns.mjs --remove
|
||
*/
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { execSync } from 'node:child_process';
|
||
|
||
const HOST = process.env.PLAZA_LOCAL_HOST ?? 'plaza.tkmind.cn';
|
||
const IP = process.env.PLAZA_LOCAL_IP ?? '127.0.0.1';
|
||
const DNS_PORT = Number(process.env.PLAZA_LOCAL_DNS_PORT ?? 5533);
|
||
const MARKER = '# tkmind-plaza-local';
|
||
const RESOLVER_MARKER = '# tkmind-plaza-local';
|
||
const LINE = `${IP} ${HOST} ${MARKER}`;
|
||
const remove = process.argv.includes('--remove');
|
||
|
||
const hostsPath = '/etc/hosts';
|
||
const resolverDir = '/etc/resolver';
|
||
const resolverPath = path.join(resolverDir, HOST);
|
||
const resolverBody = `nameserver 127.0.0.1\nport ${DNS_PORT}\n${RESOLVER_MARKER}\n`;
|
||
|
||
function flushDnsCache() {
|
||
try {
|
||
execSync('dscacheutil -flushcache', { stdio: 'ignore' });
|
||
execSync('killall -HUP mDNSResponder', { stdio: 'ignore' });
|
||
} catch {
|
||
// best effort
|
||
}
|
||
}
|
||
|
||
function writeResolver() {
|
||
fs.mkdirSync(resolverDir, { recursive: true });
|
||
fs.writeFileSync(resolverPath, resolverBody, 'utf8');
|
||
}
|
||
|
||
function removeResolver() {
|
||
try {
|
||
if (fs.existsSync(resolverPath)) fs.unlinkSync(resolverPath);
|
||
} catch {
|
||
// ignore
|
||
}
|
||
}
|
||
|
||
const current = fs.readFileSync(hostsPath, 'utf8');
|
||
const lines = current.split('\n');
|
||
const filtered = lines.filter(
|
||
(line) => !line.includes(MARKER) && !line.match(new RegExp(`\\s${HOST.replace('.', '\\.')}(\\s|$)`)),
|
||
);
|
||
|
||
if (remove) {
|
||
const next = filtered.join('\n').replace(/\n?$/, '\n');
|
||
if (filtered.length !== lines.length) {
|
||
execSync(`tee ${hostsPath}`, { input: next, stdio: ['pipe', 'inherit', 'inherit'] });
|
||
console.log(`已移除 hosts 中的 ${HOST}`);
|
||
} else {
|
||
console.log(`hosts 中未找到 ${HOST},无需移除`);
|
||
}
|
||
removeResolver();
|
||
flushDnsCache();
|
||
console.log('已移除 per-domain resolver');
|
||
process.exit(0);
|
||
}
|
||
|
||
const hostsReady = lines.some(
|
||
(line) => line.includes(MARKER) || new RegExp(`\\s${HOST.replace('.', '\\.')}(\\s|$)`).test(line),
|
||
);
|
||
const resolverReady =
|
||
fs.existsSync(resolverPath) && fs.readFileSync(resolverPath, 'utf8').trim() === resolverBody.trim();
|
||
|
||
if (hostsReady && resolverReady) {
|
||
console.log(`${HOST} 本地解析已配置(hosts + resolver)`);
|
||
process.exit(0);
|
||
}
|
||
|
||
if (process.getuid?.() !== 0) {
|
||
console.log('需要 root 权限写入 /etc/hosts 和 /etc/resolver,请执行:');
|
||
console.log(` sudo node ${process.argv[1]}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
if (!hostsReady) {
|
||
const next = `${filtered.join('\n').replace(/\n?$/, '\n')}${LINE}\n`;
|
||
try {
|
||
execSync(`tee ${hostsPath}`, { input: next, stdio: ['pipe', 'inherit', 'inherit'] });
|
||
console.log(`已添加 hosts:${LINE}`);
|
||
} catch {
|
||
console.error('写入 /etc/hosts 失败,请手动执行:');
|
||
console.error(` sudo sh -c 'echo "${LINE}" >> /etc/hosts'`);
|
||
process.exit(1);
|
||
}
|
||
} else {
|
||
console.log(`${HOST} 已在 /etc/hosts 中指向本地`);
|
||
}
|
||
|
||
try {
|
||
writeResolver();
|
||
console.log(`已添加 resolver:${resolverPath} -> 127.0.0.1:${DNS_PORT}`);
|
||
} catch (err) {
|
||
console.error('写入 /etc/resolver 失败:', err instanceof Error ? err.message : err);
|
||
process.exit(1);
|
||
}
|
||
|
||
flushDnsCache();
|
||
console.log('已刷新 DNS 缓存');
|
||
console.log('');
|
||
console.log('下一步:');
|
||
console.log(' pnpm dev:plaza # 含本地 DNS + Plaza 服务');
|
||
console.log(' sudo pnpm dev:plaza-proxy # HTTPS :443 代理');
|