@lark-apaas/coding-template-nestjs-react-fullstack 0.1.40-alpha.20260916135942 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -46
- package/package.json +1 -1
- package/template/eslint.config.js +0 -2
- package/template/package-lock.json +37 -684
- package/template/package.json +5 -7
- package/template/scripts/build.sh +43 -81
- package/template/scripts/lint.js +18 -120
- package/template/tsconfig.node.json +1 -2
package/template/package.json
CHANGED
|
@@ -18,19 +18,17 @@
|
|
|
18
18
|
"build:server": "NODE_ENV=production nest build",
|
|
19
19
|
"build:client": "NODE_ENV=production vite build --config vite.config.ts",
|
|
20
20
|
"start": "NODE_ENV=production node main.js",
|
|
21
|
-
"eslint": "eslint . --quiet
|
|
21
|
+
"eslint": "eslint . --quiet",
|
|
22
22
|
"stylelint": "stylelint client/src/**/*.css --quiet",
|
|
23
|
-
"type:check": "
|
|
23
|
+
"type:check": "concurrently -n \"server,client\" -c \"blue,green\" \"npm run type:check:server\" \"npm run type:check:client\"",
|
|
24
24
|
"type:check:client": "tsc --noEmit --project tsconfig.app.json",
|
|
25
25
|
"type:check:server": "tsc --noEmit --project tsconfig.node.json",
|
|
26
26
|
"lint": "node ./scripts/lint.js",
|
|
27
27
|
"precommit": "node scripts/hooks/run-precommit.js",
|
|
28
|
-
"upgrade": "npx -y @lark-apaas/fullstack-cli sync --disable-gen-openapi"
|
|
29
|
-
"type:check:mcp-ui": "node ./scripts/lint.js --typecheck-mcp-ui",
|
|
30
|
-
"eslint:mcp-ui": "node ./scripts/lint.js --eslint-mcp-ui"
|
|
28
|
+
"upgrade": "npx -y @lark-apaas/fullstack-cli sync --disable-gen-openapi"
|
|
31
29
|
},
|
|
32
30
|
"dependencies": {
|
|
33
|
-
"@lark-apaas/fullstack-nestjs-core": "1.1.
|
|
31
|
+
"@lark-apaas/fullstack-nestjs-core": "^1.1.61",
|
|
34
32
|
"@nestjs/axios": "^4.0.1",
|
|
35
33
|
"@nestjs/cache-manager": "^3.1.3",
|
|
36
34
|
"@nestjs/common": "^10.4.20",
|
|
@@ -55,7 +53,7 @@
|
|
|
55
53
|
"devDependencies": {
|
|
56
54
|
"@hookform/resolvers": "^5.2.2",
|
|
57
55
|
"@lark-apaas/client-toolkit": "^1.2.70",
|
|
58
|
-
"@lark-apaas/coding-preset-vite-react": "1.0.23
|
|
56
|
+
"@lark-apaas/coding-preset-vite-react": "^1.0.23",
|
|
59
57
|
"@lark-apaas/fullstack-presets": "^1.1.0",
|
|
60
58
|
"@nestjs/cli": "^10.4.9",
|
|
61
59
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
@@ -43,43 +43,37 @@ echo ""
|
|
|
43
43
|
echo "🔨 [3/5] 并行构建 server 和 client"
|
|
44
44
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
45
45
|
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# 检查构建结果
|
|
68
|
-
if [ $SERVER_EXIT -ne 0 ]; then
|
|
69
|
-
echo " ❌ Server 构建失败"
|
|
70
|
-
cat /tmp/build-server.log
|
|
71
|
-
exit 1
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
75
|
-
echo " ❌ Client 构建失败"
|
|
76
|
-
cat /tmp/build-client.log
|
|
77
|
-
exit 1
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
echo " ✅ Server 构建完成"
|
|
81
|
-
echo " ✅ Client 构建完成"
|
|
46
|
+
# 并行构建
|
|
47
|
+
echo " ├─ 启动 server 构建..."
|
|
48
|
+
npm run build:server > /tmp/build-server.log 2>&1 &
|
|
49
|
+
SERVER_PID=$!
|
|
50
|
+
|
|
51
|
+
echo " ├─ 启动 client 构建..."
|
|
52
|
+
npm run build:client > /tmp/build-client.log 2>&1 &
|
|
53
|
+
CLIENT_PID=$!
|
|
54
|
+
|
|
55
|
+
# 等待两个构建完成
|
|
56
|
+
SERVER_EXIT=0
|
|
57
|
+
CLIENT_EXIT=0
|
|
58
|
+
|
|
59
|
+
wait $SERVER_PID || SERVER_EXIT=$?
|
|
60
|
+
wait $CLIENT_PID || CLIENT_EXIT=$?
|
|
61
|
+
|
|
62
|
+
# 检查构建结果
|
|
63
|
+
if [ $SERVER_EXIT -ne 0 ]; then
|
|
64
|
+
echo " ❌ Server 构建失败"
|
|
65
|
+
cat /tmp/build-server.log
|
|
66
|
+
exit 1
|
|
82
67
|
fi
|
|
68
|
+
|
|
69
|
+
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
70
|
+
echo " ❌ Client 构建失败"
|
|
71
|
+
cat /tmp/build-client.log
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo " ✅ Server 构建完成"
|
|
76
|
+
echo " ✅ Client 构建完成"
|
|
83
77
|
print_time $STEP_START
|
|
84
78
|
echo ""
|
|
85
79
|
|
|
@@ -87,21 +81,18 @@ echo ""
|
|
|
87
81
|
echo "📦 [4/5] 准备 server 依赖产物"
|
|
88
82
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
mkdir -p "$OUT_DIR/dist/client"
|
|
84
|
+
mkdir -p "$OUT_DIR/dist/client"
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# 构建产物 HTML 随后拷,覆盖 public 里的同名文件(保证入口页是构建版,不被 public 静默覆盖)
|
|
99
|
-
cp "$ROOT_DIR/dist/client/"*.html "$OUT_DIR/dist/client/" || true
|
|
86
|
+
# public 先进(server setBaseViewsDir + nestjs-core 中间件同源 serve)
|
|
87
|
+
if [ -d "$ROOT_DIR/client/public" ]; then
|
|
88
|
+
cp -R "$ROOT_DIR/client/public/." "$OUT_DIR/dist/client/"
|
|
89
|
+
fi
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
91
|
+
# 构建产物 HTML 随后拷,覆盖 public 里的同名文件(保证入口页是构建版,不被 public 静默覆盖)
|
|
92
|
+
cp "$ROOT_DIR/dist/client/"*.html "$OUT_DIR/dist/client/" || true
|
|
103
93
|
|
|
104
|
-
|
|
94
|
+
# 拷贝 run.sh 文件
|
|
95
|
+
cp "$ROOT_DIR/scripts/run.sh" "$OUT_DIR/"
|
|
105
96
|
|
|
106
97
|
# 清理无用文件
|
|
107
98
|
rm -rf "$ROOT_DIR/dist/scripts"
|
|
@@ -115,9 +106,7 @@ echo "✂️ [5/5] 智能依赖裁剪"
|
|
|
115
106
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
116
107
|
|
|
117
108
|
# 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
|
|
118
|
-
|
|
119
|
-
node "$ROOT_DIR/scripts/prune-smart.js"
|
|
120
|
-
fi
|
|
109
|
+
node "$ROOT_DIR/scripts/prune-smart.js"
|
|
121
110
|
|
|
122
111
|
print_time $STEP_START
|
|
123
112
|
echo ""
|
|
@@ -127,37 +116,10 @@ echo "构建完成"
|
|
|
127
116
|
print_time $TOTAL_START
|
|
128
117
|
|
|
129
118
|
# 输出产物信息
|
|
130
|
-
DIST_SIZE=$(du -sh "$
|
|
119
|
+
DIST_SIZE=$(du -sh "$OUT_DIR" | cut -f1)
|
|
120
|
+
NODE_MODULES_SIZE=$(du -sh "$OUT_DIR/node_modules" | cut -f1)
|
|
131
121
|
echo ""
|
|
132
122
|
echo "📊 构建产物统计:"
|
|
133
123
|
echo " 总大小: $DIST_SIZE"
|
|
134
|
-
|
|
135
|
-
NODE_MODULES_SIZE=$(du -sh "$OUT_DIR/node_modules" | cut -f1)
|
|
136
|
-
echo " node_modules: $NODE_MODULES_SIZE"
|
|
137
|
-
fi
|
|
124
|
+
echo " node_modules: $NODE_MODULES_SIZE"
|
|
138
125
|
echo ""
|
|
139
|
-
|
|
140
|
-
# 仅成功的全构建生成 backendBuildID;必须在构建、产物准备和依赖裁剪之后。
|
|
141
|
-
# UI/Skill 内容由 SDK 独立计入总 hash;纯前端发布不替换已部署的 backendBuildID。
|
|
142
|
-
if [[ "${only_frontend_change:-false}" != "true" ]]; then
|
|
143
|
-
node - "$ROOT_DIR/dist" <<'NODE'
|
|
144
|
-
const fs = require('node:fs');
|
|
145
|
-
const path = require('node:path');
|
|
146
|
-
const { randomUUID } = require('node:crypto');
|
|
147
|
-
const dist = process.argv[2];
|
|
148
|
-
// 防止 build:server 空跑成功、却没有可交付的服务端入口。
|
|
149
|
-
if (!fs.statSync(path.join(dist, 'server/main.js')).isFile()) {
|
|
150
|
-
throw new Error('Missing server build output: dist/server/main.js');
|
|
151
|
-
}
|
|
152
|
-
// runtime cwd 分别为工程根、dist/(或整包解压到 dist-server/)、旧版 dist/server/。
|
|
153
|
-
// 与 MCP UI/Skill 的交付布局一致:复制产物时保留同一个 UUID,不在启动时生成。
|
|
154
|
-
const files = [
|
|
155
|
-
path.join(dist, 'mcp-build-id'),
|
|
156
|
-
path.join(dist, 'dist/mcp-build-id'),
|
|
157
|
-
path.join(dist, 'server/dist/mcp-build-id'),
|
|
158
|
-
];
|
|
159
|
-
for (const file of files) fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
160
|
-
const buildID = randomUUID();
|
|
161
|
-
for (const file of files) fs.writeFileSync(file, buildID, 'utf8');
|
|
162
|
-
NODE
|
|
163
|
-
fi
|
package/template/scripts/lint.js
CHANGED
|
@@ -18,31 +18,19 @@ function runCommand(command, args) {
|
|
|
18
18
|
shell: false,
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
child.on('close', (code) => resolve(code
|
|
21
|
+
child.on('close', (code) => resolve(code || 0));
|
|
22
22
|
child.on('error', () => resolve(1));
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// 串行依次执行每个任务,全部跑完后再聚合退出码:
|
|
27
|
-
// 降低并发资源占用、让各任务输出按顺序清晰可读,同时保留“一次暴露所有 lint 问题”的行为。
|
|
28
|
-
async function runTasksSerially(taskSpecs) {
|
|
29
|
-
let exitCode = 0;
|
|
30
|
-
for (const [command, args] of taskSpecs) {
|
|
31
|
-
const code = await runCommand(command, args);
|
|
32
|
-
if (code !== 0) {
|
|
33
|
-
exitCode = 1;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return exitCode;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
26
|
function normalizeProjectFile(filePath) {
|
|
40
27
|
const absolutePath = path.isAbsolute(filePath)
|
|
41
28
|
? filePath
|
|
42
29
|
: path.resolve(cwd, filePath);
|
|
43
30
|
|
|
44
31
|
if (!fs.existsSync(absolutePath)) {
|
|
45
|
-
console.
|
|
32
|
+
console.warn(`[lint] Skip missing file: ${filePath}`);
|
|
33
|
+
return null;
|
|
46
34
|
}
|
|
47
35
|
|
|
48
36
|
const relativePath = path.relative(cwd, absolutePath);
|
|
@@ -106,92 +94,17 @@ function canRunStylelint() {
|
|
|
106
94
|
return STYLELINT_CONFIG_FILES.some(file => fs.existsSync(path.join(cwd, file)));
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
const UI_DIR = 'server/mcp/ui';
|
|
110
|
-
const UI_TYPECHECK = 'node ./scripts/lint.js --typecheck';
|
|
111
|
-
|
|
112
|
-
function isUiFile(file) {
|
|
113
|
-
return file.startsWith(`${UI_DIR}/`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function uiSourceFiles() {
|
|
117
|
-
const files = [];
|
|
118
|
-
function visit(relative) {
|
|
119
|
-
const absolute = path.join(cwd, relative);
|
|
120
|
-
if (!fs.existsSync(absolute)) return;
|
|
121
|
-
if (fs.lstatSync(absolute).isSymbolicLink()) {
|
|
122
|
-
throw new Error(`MCP UI 检查不支持符号链接: ${relative}`);
|
|
123
|
-
}
|
|
124
|
-
for (const entry of fs.readdirSync(absolute, { withFileTypes: true })) {
|
|
125
|
-
if (['node_modules', 'dist', '.git'].includes(entry.name)) continue;
|
|
126
|
-
const file = `${relative}/${entry.name}`;
|
|
127
|
-
if (entry.isSymbolicLink()) throw new Error(`MCP UI 检查不支持符号链接: ${file}`);
|
|
128
|
-
if (entry.isDirectory()) visit(file);
|
|
129
|
-
else if (isEslintTarget(file) && !/\.d\.(?:ts|mts|cts)$/.test(file)) files.push(file);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
visit(UI_DIR);
|
|
133
|
-
return files.sort();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function uiTasks({ types = true, eslint = true } = {}) {
|
|
137
|
-
const sources = uiSourceFiles();
|
|
138
|
-
if (!sources.length) return [];
|
|
139
|
-
const tasks = [];
|
|
140
|
-
if (types) {
|
|
141
|
-
const config = `${UI_DIR}/tsconfig.json`;
|
|
142
|
-
if (!fs.existsSync(path.join(cwd, config))) {
|
|
143
|
-
throw new Error(`MCP UI 缺少 ${config},请按 mcp-guide 补齐独立浏览器 TypeScript 配置。`);
|
|
144
|
-
}
|
|
145
|
-
const ts = require('typescript');
|
|
146
|
-
const parsed = ts.getParsedCommandLineOfConfigFile(path.join(cwd, config), {}, {
|
|
147
|
-
...ts.sys,
|
|
148
|
-
onUnRecoverableConfigFileDiagnostic: d => { throw new Error(ts.flattenDiagnosticMessageText(d.messageText, '\n')); },
|
|
149
|
-
});
|
|
150
|
-
if (!parsed || parsed.errors.length) throw new Error(`MCP UI TypeScript 配置无效: ${config}`);
|
|
151
|
-
const included = new Set(parsed.fileNames.map(file => path.resolve(file)));
|
|
152
|
-
const missing = sources.filter(file => !included.has(path.resolve(cwd, file)));
|
|
153
|
-
if (missing.length) throw new Error(`MCP UI TypeScript 配置未覆盖源码: ${missing.join(', ')};请检查 include/exclude,JS 源码需开启 allowJs。`);
|
|
154
|
-
tasks.push([getBinName('npx'), ['--no-install', 'tsc', '--noEmit', '-p', config]]);
|
|
155
|
-
}
|
|
156
|
-
if (eslint) {
|
|
157
|
-
const config = ['eslint.mcp-ui.config.js', 'eslint.mcp-ui.config.cjs', 'eslint.mcp-ui.config.mjs']
|
|
158
|
-
.find(file => fs.existsSync(path.join(cwd, file)));
|
|
159
|
-
if (!config) throw new Error('MCP UI 缺少独立 ESLint 配置,请按 mcp-guide 创建 eslint.mcp-ui.config.cjs。');
|
|
160
|
-
tasks.push([getBinName('npx'), ['--no-install', 'eslint', '--config', config, '--quiet', '--max-warnings', '0', ...sources]]);
|
|
161
|
-
}
|
|
162
|
-
return tasks;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function packageScripts() {
|
|
166
|
-
return JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8')).scripts || {};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function runTypeCheck() {
|
|
170
|
-
const scripts = packageScripts();
|
|
171
|
-
const tasks = ['type:check:server', 'type:check:client'].map(name => {
|
|
172
|
-
if (!scripts[name]) throw new Error(`缺少 scripts.${name},请保留应用原有类型检查命令。`);
|
|
173
|
-
return [getBinName('npm'), ['run', name]];
|
|
174
|
-
});
|
|
175
|
-
tasks.push(...uiTasks({ eslint: false }));
|
|
176
|
-
process.exit(await runTasksSerially(tasks));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
97
|
async function runDefaultLint() {
|
|
180
|
-
const
|
|
181
|
-
[getBinName('npm'), ['run', 'eslint']],
|
|
182
|
-
[getBinName('npm'), ['run', 'type:check']],
|
|
183
|
-
];
|
|
184
|
-
|
|
185
|
-
// Customized type:check remains untouched; ensure full lint still checks UI.
|
|
186
|
-
taskSpecs.push(...uiTasks({ types: packageScripts()['type:check'] !== UI_TYPECHECK }));
|
|
98
|
+
const commands = ['npm run eslint', 'npm run type:check'];
|
|
187
99
|
|
|
188
100
|
if (canRunStylelint()) {
|
|
189
|
-
|
|
101
|
+
commands.push('npm run stylelint');
|
|
190
102
|
} else {
|
|
191
103
|
console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
|
|
192
104
|
}
|
|
193
105
|
|
|
194
|
-
|
|
106
|
+
const code = await runCommand(getBinName('npx'), ['concurrently', ...commands]);
|
|
107
|
+
process.exit(code);
|
|
195
108
|
}
|
|
196
109
|
|
|
197
110
|
async function runSelectiveLint(inputFiles) {
|
|
@@ -204,20 +117,15 @@ async function runSelectiveLint(inputFiles) {
|
|
|
204
117
|
process.exit(0);
|
|
205
118
|
}
|
|
206
119
|
|
|
207
|
-
const eslintFiles = normalizedFiles.filter(
|
|
208
|
-
const stylelintFiles = normalizedFiles.filter(
|
|
120
|
+
const eslintFiles = normalizedFiles.filter(isEslintTarget);
|
|
121
|
+
const stylelintFiles = normalizedFiles.filter(isStylelintTarget);
|
|
209
122
|
const typeCheckFiles = normalizedFiles.filter(isTypeCheckTarget);
|
|
210
123
|
|
|
211
124
|
const clientTypeFiles = [];
|
|
212
125
|
const serverTypeFiles = [];
|
|
213
|
-
const rootConfigChanged = normalizedFiles.some(file => /^tsconfig(?:\.[^/]*)?\.json$/.test(file));
|
|
214
|
-
if (rootConfigChanged) { clientTypeFiles.push('config'); serverTypeFiles.push('config'); }
|
|
215
|
-
let checkUi = rootConfigChanged || normalizedFiles.some(file => isUiFile(file) || file.startsWith('shared/') || file.startsWith('eslint.mcp-ui.config.'));
|
|
216
126
|
|
|
217
127
|
for (const filePath of typeCheckFiles) {
|
|
218
|
-
if (
|
|
219
|
-
checkUi = true;
|
|
220
|
-
} else if (filePath.startsWith('client/')) {
|
|
128
|
+
if (filePath.startsWith('client/')) {
|
|
221
129
|
clientTypeFiles.push(filePath);
|
|
222
130
|
} else if (filePath.startsWith('server/')) {
|
|
223
131
|
serverTypeFiles.push(filePath);
|
|
@@ -227,46 +135,36 @@ async function runSelectiveLint(inputFiles) {
|
|
|
227
135
|
}
|
|
228
136
|
}
|
|
229
137
|
|
|
230
|
-
const
|
|
138
|
+
const tasks = [];
|
|
231
139
|
|
|
232
140
|
if (eslintFiles.length > 0) {
|
|
233
|
-
|
|
141
|
+
tasks.push(runCommand(getBinName('npx'), ['eslint', '--quiet', ...eslintFiles]));
|
|
234
142
|
}
|
|
235
143
|
|
|
236
144
|
if (stylelintFiles.length > 0 && !canRunStylelint()) {
|
|
237
145
|
console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
|
|
238
146
|
} else if (stylelintFiles.length > 0) {
|
|
239
|
-
|
|
147
|
+
tasks.push(runCommand(getBinName('npx'), ['stylelint', '--quiet', ...stylelintFiles]));
|
|
240
148
|
}
|
|
241
149
|
|
|
242
150
|
if (clientTypeFiles.length > 0) {
|
|
243
|
-
|
|
151
|
+
tasks.push(runCommand(getBinName('npm'), ['run', 'type:check:client']));
|
|
244
152
|
}
|
|
245
153
|
|
|
246
154
|
if (serverTypeFiles.length > 0) {
|
|
247
|
-
|
|
155
|
+
tasks.push(runCommand(getBinName('npm'), ['run', 'type:check:server']));
|
|
248
156
|
}
|
|
249
157
|
|
|
250
|
-
if (
|
|
251
|
-
|
|
252
|
-
if (taskSpecs.length === 0) {
|
|
158
|
+
if (tasks.length === 0) {
|
|
253
159
|
console.log('[lint] No supported files matched for lint');
|
|
254
160
|
process.exit(0);
|
|
255
161
|
}
|
|
256
162
|
|
|
257
|
-
|
|
163
|
+
const results = await Promise.all(tasks);
|
|
164
|
+
process.exit(results.some(code => code !== 0) ? 1 : 0);
|
|
258
165
|
}
|
|
259
166
|
|
|
260
167
|
async function main() {
|
|
261
|
-
const args = process.argv.slice(2);
|
|
262
|
-
const modes = ['--typecheck', '--typecheck-mcp-ui', '--eslint-mcp-ui'];
|
|
263
|
-
if (args.length && !(args[0] === '--files' && args.length > 1) && !(args.length === 1 && modes.includes(args[0]))) {
|
|
264
|
-
throw new Error('用法: lint.js [--files <paths...> | --typecheck | --typecheck-mcp-ui | --eslint-mcp-ui]');
|
|
265
|
-
}
|
|
266
|
-
if (args[0] === '--files' && args.slice(1).some(arg => arg.startsWith('--'))) throw new Error('--files 不可与其他检查模式混用');
|
|
267
|
-
if (args.includes('--typecheck')) return runTypeCheck();
|
|
268
|
-
if (args.includes('--typecheck-mcp-ui')) return process.exit(await runTasksSerially(uiTasks({ eslint: false })));
|
|
269
|
-
if (args.includes('--eslint-mcp-ui')) return process.exit(await runTasksSerially(uiTasks({ types: false })));
|
|
270
168
|
const files = parseFilesArg(process.argv.slice(2));
|
|
271
169
|
if (files === null) {
|
|
272
170
|
await runDefaultLint();
|
|
@@ -13,6 +13,5 @@
|
|
|
13
13
|
"excludeDirectories": ["node_modules/**"]
|
|
14
14
|
},
|
|
15
15
|
"include": ["server/**/*", "shared/**/*.ts"],
|
|
16
|
-
|
|
17
|
-
"exclude": ["server/mcp/ui", "node_modules", "dist", "client", "source_package", "**/*.spec.ts", "**/*.e2e-spec.ts"],
|
|
16
|
+
"exclude": ["node_modules", "dist", "client", "source_package", "**/*.spec.ts", "**/*.e2e-spec.ts"],
|
|
18
17
|
}
|