feat(wechat): migrate schedule and sync handlers into wechat package
Extract schedule, greeting/status/connectivity replies, chat-general prompt, and display-name helpers from wechat-mp.mjs. Route sync intents via classifyWechatIntent and add channel isolation CI check. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const wechatRoot = path.join(root, 'wechat');
|
||||
const forbiddenWechatImports = [
|
||||
'mindspace-public-finish-sync.mjs',
|
||||
'chat-finish-sync.mjs',
|
||||
'useTKMindChat',
|
||||
'src/hooks/useTKMindChat',
|
||||
];
|
||||
const forbiddenH5ImportPatterns = [
|
||||
/from\s+['"][^'"]*\/wechat\//,
|
||||
/import\s*\(\s*['"][^'"]*\/wechat\//,
|
||||
/require\s*\(\s*['"][^'"]*\/wechat\//,
|
||||
];
|
||||
|
||||
function walk(dir, acc = []) {
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const full = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) walk(full, acc);
|
||||
else if (entry.name.endsWith('.mjs') || entry.name.endsWith('.ts') || entry.name.endsWith('.tsx')) acc.push(full);
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
function checkWechatImports() {
|
||||
const violations = [];
|
||||
for (const file of walk(wechatRoot)) {
|
||||
const text = fs.readFileSync(file, 'utf8');
|
||||
for (const token of forbiddenWechatImports) {
|
||||
if (text.includes(token)) violations.push({ file, token });
|
||||
}
|
||||
}
|
||||
return violations;
|
||||
}
|
||||
|
||||
function checkH5ImportsWechat() {
|
||||
const violations = [];
|
||||
const h5Paths = [
|
||||
path.join(root, 'src'),
|
||||
path.join(root, 'chat-finish-sync.mjs'),
|
||||
path.join(root, 'mindspace-public-finish-sync.mjs'),
|
||||
].filter((p) => fs.existsSync(p));
|
||||
|
||||
for (const base of h5Paths) {
|
||||
const files = fs.statSync(base).isDirectory() ? walk(base) : [base];
|
||||
for (const file of files) {
|
||||
const text = fs.readFileSync(file, 'utf8');
|
||||
for (const pattern of forbiddenH5ImportPatterns) {
|
||||
if (pattern.test(text)) violations.push({ file, token: pattern.source });
|
||||
}
|
||||
}
|
||||
}
|
||||
return violations;
|
||||
}
|
||||
|
||||
const wechatViolations = checkWechatImports();
|
||||
const h5Violations = checkH5ImportsWechat();
|
||||
|
||||
if (wechatViolations.length === 0 && h5Violations.length === 0) {
|
||||
console.log('wechat channel isolation check passed');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
for (const item of wechatViolations) {
|
||||
console.error(`wechat forbidden import: ${item.token} in ${path.relative(root, item.file)}`);
|
||||
}
|
||||
for (const item of h5Violations) {
|
||||
console.error(`h5 forbidden import: ${item.token} in ${path.relative(root, item.file)}`);
|
||||
}
|
||||
process.exit(1);
|
||||
Reference in New Issue
Block a user