Add MindSpace page live edit, chat skills, and H5 deploy tooling.
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>
This commit is contained in:
@@ -1,22 +1,54 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Map plaza.tkmind.cn -> 127.0.0.1 for local Plaza dev.
|
||||
* Requires sudo to edit /etc/hosts.
|
||||
* 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(
|
||||
@@ -24,35 +56,61 @@ const filtered = lines.filter(
|
||||
);
|
||||
|
||||
if (remove) {
|
||||
if (filtered.length === lines.length) {
|
||||
console.log(`hosts 中未找到 ${HOST},无需移除`);
|
||||
process.exit(0);
|
||||
}
|
||||
const next = filtered.join('\n').replace(/\n?$/, '\n');
|
||||
execSync(`tee ${hostsPath}`, { input: next, stdio: ['pipe', 'inherit', 'inherit'] });
|
||||
console.log(`已移除 ${HOST} 本地解析`);
|
||||
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);
|
||||
}
|
||||
|
||||
if (lines.some((line) => line.includes(MARKER) || new RegExp(`\\s${HOST.replace('.', '\\.')}(\\s|$)`).test(line))) {
|
||||
console.log(`${HOST} 已在 /etc/hosts 中指向本地`);
|
||||
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);
|
||||
}
|
||||
|
||||
const next = `${filtered.join('\n').replace(/\n?$/, '\n')}${LINE}\n`;
|
||||
if (process.getuid?.() !== 0) {
|
||||
console.log('需要 root 权限写入 /etc/hosts,请执行:');
|
||||
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 {
|
||||
execSync(`tee ${hostsPath}`, { input: next, stdio: ['pipe', 'inherit', 'inherit'] });
|
||||
console.log(`已添加:${LINE}`);
|
||||
console.log('下一步:');
|
||||
console.log(' sudo pnpm setup:plaza-local # hosts + TLS 证书');
|
||||
console.log(' sudo pnpm dev:plaza-proxy # HTTPS :443 代理');
|
||||
} catch {
|
||||
console.error('写入 /etc/hosts 失败,请手动执行:');
|
||||
console.error(` sudo sh -c 'echo "${LINE}" >> /etc/hosts'`);
|
||||
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 代理');
|
||||
|
||||
Reference in New Issue
Block a user