@aipanel/core 1.2.26 → 1.2.27

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.
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { exec } from "node:child_process";
3
+ import { execa } from "execa";
4
4
  import { createRequire } from "node:module";
5
5
  import { SEVERITY_ERROR, SEVERITY_WARN } from "../common/constants.mjs";
6
6
  import { createLogger } from "./node-logger.mjs";
@@ -189,41 +189,35 @@ function parseOxlintOutput(stdout, cwd) {
189
189
  async function runOxlintFiles(pattern, cwd, warnLimit) {
190
190
  const bin = resolveOxlintBin(cwd);
191
191
  if (!bin) return {};
192
- return new Promise((resolve) => {
193
- exec(
194
- // ESLint 默认行为对齐:忽略 node_modules(oxlint 默认不排除)
195
- `node "${bin}" --format=json --ignore-pattern node_modules "${pattern}"`,
196
- { cwd, timeout: 6e4, maxBuffer: 50 * 1024 * 1024 },
197
- (error, stdout, stderr) => {
198
- const killed = error?.killed;
199
- if (killed) {
200
- log.warn("oxlint timed out", { pattern });
201
- resolve({
202
- text: "[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A\u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u3002",
203
- diagnostics: [],
204
- engines: ["oxlint"]
205
- });
206
- return;
207
- }
208
- try {
209
- const messages = parseOxlintOutput(stdout, cwd);
210
- log.debug("oxlint lint", {
211
- pattern,
212
- messageCount: messages.length,
213
- stderr: stderr || void 0
214
- });
215
- resolve(formatLintMessages(messages, { label: "oxlint", source: "oxlint" }, warnLimit));
216
- } catch (e) {
217
- log.warn("oxlint failed", { pattern, error: e.message });
218
- resolve({
219
- text: `[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A${e.message}`,
220
- diagnostics: [],
221
- engines: ["oxlint"]
222
- });
223
- }
224
- }
225
- );
226
- });
192
+ const result = await execa(
193
+ "node",
194
+ [bin, "--format=json", "--ignore-pattern", "node_modules", pattern],
195
+ { cwd, timeout: 6e4, maxBuffer: 50 * 1024 * 1024, reject: false }
196
+ );
197
+ if (result.timedOut || result.isTerminated || result.isMaxBuffer) {
198
+ log.warn("oxlint timed out", { pattern });
199
+ return {
200
+ text: "[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A\u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u3002",
201
+ diagnostics: [],
202
+ engines: ["oxlint"]
203
+ };
204
+ }
205
+ try {
206
+ const messages = parseOxlintOutput(result.stdout, cwd);
207
+ log.debug("oxlint lint", {
208
+ pattern,
209
+ messageCount: messages.length,
210
+ stderr: result.stderr || void 0
211
+ });
212
+ return formatLintMessages(messages, { label: "oxlint", source: "oxlint" }, warnLimit);
213
+ } catch (e) {
214
+ log.warn("oxlint failed", { pattern, error: e.message });
215
+ return {
216
+ text: `[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A${e.message}`,
217
+ diagnostics: [],
218
+ engines: ["oxlint"]
219
+ };
220
+ }
227
221
  }
228
222
  let _vueTscBin;
229
223
  function resolveVueTscBin() {
@@ -364,45 +358,43 @@ async function runTypeCheck(filePath, cwd) {
364
358
  }
365
359
  const timeout = filePath ? 6e4 : 12e4;
366
360
  const maxBuffer = filePath ? 10 * 1024 * 1024 : 50 * 1024 * 1024;
367
- return new Promise((resolve) => {
368
- exec(
369
- `node "${engine.bin}" --build --noEmit --pretty false`,
370
- { cwd: projectDir, timeout, maxBuffer },
371
- (error, stdout, stderr) => {
372
- let rawOutput = stdout + stderr;
373
- const killed = error?.killed;
374
- const exitCode = typeof error?.code === "number" ? error.code : killed ? 1 : 0;
375
- if (killed && !rawOutput) {
376
- rawOutput = `${engine.source} \u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u6216\u4F18\u5316\u9879\u76EE\u914D\u7F6E\u3002`;
377
- }
378
- const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
379
- if (filePath) {
380
- const resolved = path.resolve(filePath);
381
- const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
382
- const lines = rawOutput.split("\n");
383
- const filtered = [];
384
- let keep = false;
385
- for (const line of lines) {
386
- const m = errorLinePat.exec(line);
387
- if (m) {
388
- keep = path.resolve(projectDir, m[1]) === resolved;
389
- } else if (!/^\s/.test(line)) {
390
- keep = false;
391
- }
392
- if (keep) filtered.push(line);
393
- }
394
- rawOutput = filtered.join("\n");
395
- }
396
- log.debug("type-check finished", {
397
- engine: engine.source,
398
- filePath: filePath || "(all)",
399
- exitCode,
400
- outputLength: rawOutput.length
401
- });
402
- resolve({ rawOutput, exitCode, diagnostics, source: engine.source });
361
+ const result = await execa("node", [engine.bin, "--build", "--noEmit", "--pretty", "false"], {
362
+ cwd: projectDir,
363
+ timeout,
364
+ maxBuffer,
365
+ reject: false
366
+ });
367
+ let rawOutput = result.stdout + result.stderr;
368
+ const killed = result.timedOut || result.isTerminated || result.isMaxBuffer;
369
+ const exitCode = typeof result.exitCode === "number" ? result.exitCode : killed ? 1 : 0;
370
+ if (killed && !rawOutput) {
371
+ rawOutput = `${engine.source} \u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u6216\u4F18\u5316\u9879\u76EE\u914D\u7F6E\u3002`;
372
+ }
373
+ const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
374
+ if (filePath) {
375
+ const resolved = path.resolve(filePath);
376
+ const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
377
+ const lines = rawOutput.split("\n");
378
+ const filtered = [];
379
+ let keep = false;
380
+ for (const line of lines) {
381
+ const m = errorLinePat.exec(line);
382
+ if (m) {
383
+ keep = path.resolve(projectDir, m[1]) === resolved;
384
+ } else if (!/^\s/.test(line)) {
385
+ keep = false;
403
386
  }
404
- );
387
+ if (keep) filtered.push(line);
388
+ }
389
+ rawOutput = filtered.join("\n");
390
+ }
391
+ log.debug("type-check finished", {
392
+ engine: engine.source,
393
+ filePath: filePath || "(all)",
394
+ exitCode,
395
+ outputLength: rawOutput.length
405
396
  });
397
+ return { rawOutput, exitCode, diagnostics, source: engine.source };
406
398
  }
407
399
  async function runAllChecks(pattern, cwd) {
408
400
  log.debug("runAllChecks", { pattern, cwd });
@@ -1,4 +1,5 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { execa } from "execa";
2
3
  import { createRequire } from "node:module";
3
4
  import fs from "node:fs";
4
5
  import http from "node:http";
@@ -124,40 +125,18 @@ function findGitRoot(startDir, maxDepth = 10) {
124
125
  }
125
126
  async function checkCliInstalled(bin) {
126
127
  const timer = new PerformanceTimer(`checkCliInstalled:${bin}`);
127
- return new Promise((resolve) => {
128
- const proc = spawn(bin, ["--version"], { stdio: "ignore", shell: true });
129
- proc.on("close", (code) => {
130
- const installed = code === 0;
131
- timer.end(installed ? `\u2713 ${bin} is installed` : `\u2716 ${bin} not found`);
132
- resolve(installed);
133
- });
134
- proc.on("error", (err) => {
135
- log.debug(`Failed to check ${bin} installation`, { error: err.message });
136
- timer.end("\u2716 Check failed");
137
- resolve(false);
138
- });
139
- });
128
+ const result = await execa(bin, ["--version"], { reject: false, stdio: "ignore" });
129
+ const installed = result.exitCode === 0;
130
+ if (!installed && result.exitCode === void 0) {
131
+ log.debug(`Failed to check ${bin} installation`, { error: result.message });
132
+ }
133
+ timer.end(installed ? `\u2713 ${bin} is installed` : `\u2716 ${bin} not found`);
134
+ return installed;
140
135
  }
141
- function getCliVersion(bin) {
142
- return new Promise((resolve) => {
143
- const proc = spawn(bin, ["--version"], { stdio: "pipe", shell: true });
144
- let stdout = "";
145
- let stderr = "";
146
- proc.stdout?.on("data", (data) => {
147
- stdout += data.toString();
148
- });
149
- proc.stderr?.on("data", (data) => {
150
- stderr += data.toString();
151
- });
152
- proc.on("close", (code) => {
153
- if (code !== 0) {
154
- resolve(null);
155
- return;
156
- }
157
- resolve(stdout.trim() || stderr.trim() || null);
158
- });
159
- proc.on("error", () => resolve(null));
160
- });
136
+ async function getCliVersion(bin) {
137
+ const result = await execa(bin, ["--version"], { reject: false });
138
+ if (result.exitCode !== 0) return null;
139
+ return result.stdout.trim() || result.stderr.trim() || null;
161
140
  }
162
141
  function killOrphanCliProcesses(bin, options) {
163
142
  const label = options.label ?? bin;
@@ -42,7 +42,7 @@ __export(diagnostics_exports, {
42
42
  module.exports = __toCommonJS(diagnostics_exports);
43
43
  var import_node_fs = __toESM(require("node:fs"));
44
44
  var import_node_path = __toESM(require("node:path"));
45
- var import_node_child_process = require("node:child_process");
45
+ var import_execa = require("execa");
46
46
  var import_node_module = require("node:module");
47
47
  var import_constants = require("../common/constants.cjs");
48
48
  var import_node_logger = require("./node-logger.cjs");
@@ -232,41 +232,35 @@ function parseOxlintOutput(stdout, cwd) {
232
232
  async function runOxlintFiles(pattern, cwd, warnLimit) {
233
233
  const bin = resolveOxlintBin(cwd);
234
234
  if (!bin) return {};
235
- return new Promise((resolve) => {
236
- (0, import_node_child_process.exec)(
237
- // ESLint 默认行为对齐:忽略 node_modules(oxlint 默认不排除)
238
- `node "${bin}" --format=json --ignore-pattern node_modules "${pattern}"`,
239
- { cwd, timeout: 6e4, maxBuffer: 50 * 1024 * 1024 },
240
- (error, stdout, stderr) => {
241
- const killed = error?.killed;
242
- if (killed) {
243
- log.warn("oxlint timed out", { pattern });
244
- resolve({
245
- text: "[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A\u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u3002",
246
- diagnostics: [],
247
- engines: ["oxlint"]
248
- });
249
- return;
250
- }
251
- try {
252
- const messages = parseOxlintOutput(stdout, cwd);
253
- log.debug("oxlint lint", {
254
- pattern,
255
- messageCount: messages.length,
256
- stderr: stderr || void 0
257
- });
258
- resolve(formatLintMessages(messages, { label: "oxlint", source: "oxlint" }, warnLimit));
259
- } catch (e) {
260
- log.warn("oxlint failed", { pattern, error: e.message });
261
- resolve({
262
- text: `[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A${e.message}`,
263
- diagnostics: [],
264
- engines: ["oxlint"]
265
- });
266
- }
267
- }
268
- );
269
- });
235
+ const result = await (0, import_execa.execa)(
236
+ "node",
237
+ [bin, "--format=json", "--ignore-pattern", "node_modules", pattern],
238
+ { cwd, timeout: 6e4, maxBuffer: 50 * 1024 * 1024, reject: false }
239
+ );
240
+ if (result.timedOut || result.isTerminated || result.isMaxBuffer) {
241
+ log.warn("oxlint timed out", { pattern });
242
+ return {
243
+ text: "[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A\u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u3002",
244
+ diagnostics: [],
245
+ engines: ["oxlint"]
246
+ };
247
+ }
248
+ try {
249
+ const messages = parseOxlintOutput(result.stdout, cwd);
250
+ log.debug("oxlint lint", {
251
+ pattern,
252
+ messageCount: messages.length,
253
+ stderr: result.stderr || void 0
254
+ });
255
+ return formatLintMessages(messages, { label: "oxlint", source: "oxlint" }, warnLimit);
256
+ } catch (e) {
257
+ log.warn("oxlint failed", { pattern, error: e.message });
258
+ return {
259
+ text: `[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A${e.message}`,
260
+ diagnostics: [],
261
+ engines: ["oxlint"]
262
+ };
263
+ }
270
264
  }
271
265
  let _vueTscBin;
272
266
  function resolveVueTscBin() {
@@ -407,45 +401,43 @@ async function runTypeCheck(filePath, cwd) {
407
401
  }
408
402
  const timeout = filePath ? 6e4 : 12e4;
409
403
  const maxBuffer = filePath ? 10 * 1024 * 1024 : 50 * 1024 * 1024;
410
- return new Promise((resolve) => {
411
- (0, import_node_child_process.exec)(
412
- `node "${engine.bin}" --build --noEmit --pretty false`,
413
- { cwd: projectDir, timeout, maxBuffer },
414
- (error, stdout, stderr) => {
415
- let rawOutput = stdout + stderr;
416
- const killed = error?.killed;
417
- const exitCode = typeof error?.code === "number" ? error.code : killed ? 1 : 0;
418
- if (killed && !rawOutput) {
419
- rawOutput = `${engine.source} \u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u6216\u4F18\u5316\u9879\u76EE\u914D\u7F6E\u3002`;
420
- }
421
- const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
422
- if (filePath) {
423
- const resolved = import_node_path.default.resolve(filePath);
424
- const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
425
- const lines = rawOutput.split("\n");
426
- const filtered = [];
427
- let keep = false;
428
- for (const line of lines) {
429
- const m = errorLinePat.exec(line);
430
- if (m) {
431
- keep = import_node_path.default.resolve(projectDir, m[1]) === resolved;
432
- } else if (!/^\s/.test(line)) {
433
- keep = false;
434
- }
435
- if (keep) filtered.push(line);
436
- }
437
- rawOutput = filtered.join("\n");
438
- }
439
- log.debug("type-check finished", {
440
- engine: engine.source,
441
- filePath: filePath || "(all)",
442
- exitCode,
443
- outputLength: rawOutput.length
444
- });
445
- resolve({ rawOutput, exitCode, diagnostics, source: engine.source });
404
+ const result = await (0, import_execa.execa)("node", [engine.bin, "--build", "--noEmit", "--pretty", "false"], {
405
+ cwd: projectDir,
406
+ timeout,
407
+ maxBuffer,
408
+ reject: false
409
+ });
410
+ let rawOutput = result.stdout + result.stderr;
411
+ const killed = result.timedOut || result.isTerminated || result.isMaxBuffer;
412
+ const exitCode = typeof result.exitCode === "number" ? result.exitCode : killed ? 1 : 0;
413
+ if (killed && !rawOutput) {
414
+ rawOutput = `${engine.source} \u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u6216\u4F18\u5316\u9879\u76EE\u914D\u7F6E\u3002`;
415
+ }
416
+ const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
417
+ if (filePath) {
418
+ const resolved = import_node_path.default.resolve(filePath);
419
+ const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
420
+ const lines = rawOutput.split("\n");
421
+ const filtered = [];
422
+ let keep = false;
423
+ for (const line of lines) {
424
+ const m = errorLinePat.exec(line);
425
+ if (m) {
426
+ keep = import_node_path.default.resolve(projectDir, m[1]) === resolved;
427
+ } else if (!/^\s/.test(line)) {
428
+ keep = false;
446
429
  }
447
- );
430
+ if (keep) filtered.push(line);
431
+ }
432
+ rawOutput = filtered.join("\n");
433
+ }
434
+ log.debug("type-check finished", {
435
+ engine: engine.source,
436
+ filePath: filePath || "(all)",
437
+ exitCode,
438
+ outputLength: rawOutput.length
448
439
  });
440
+ return { rawOutput, exitCode, diagnostics, source: engine.source };
449
441
  }
450
442
  async function runAllChecks(pattern, cwd) {
451
443
  log.debug("runAllChecks", { pattern, cwd });
@@ -40,6 +40,7 @@ __export(node_utils_exports, {
40
40
  });
41
41
  module.exports = __toCommonJS(node_utils_exports);
42
42
  var import_node_child_process = require("node:child_process");
43
+ var import_execa = require("execa");
43
44
  var import_node_module = require("node:module");
44
45
  var import_node_fs = __toESM(require("node:fs"));
45
46
  var import_node_http = __toESM(require("node:http"));
@@ -161,40 +162,18 @@ function findGitRoot(startDir, maxDepth = 10) {
161
162
  }
162
163
  async function checkCliInstalled(bin) {
163
164
  const timer = new import_node_logger.PerformanceTimer(`checkCliInstalled:${bin}`);
164
- return new Promise((resolve) => {
165
- const proc = (0, import_node_child_process.spawn)(bin, ["--version"], { stdio: "ignore", shell: true });
166
- proc.on("close", (code) => {
167
- const installed = code === 0;
168
- timer.end(installed ? `\u2713 ${bin} is installed` : `\u2716 ${bin} not found`);
169
- resolve(installed);
170
- });
171
- proc.on("error", (err) => {
172
- log.debug(`Failed to check ${bin} installation`, { error: err.message });
173
- timer.end("\u2716 Check failed");
174
- resolve(false);
175
- });
176
- });
165
+ const result = await (0, import_execa.execa)(bin, ["--version"], { reject: false, stdio: "ignore" });
166
+ const installed = result.exitCode === 0;
167
+ if (!installed && result.exitCode === void 0) {
168
+ log.debug(`Failed to check ${bin} installation`, { error: result.message });
169
+ }
170
+ timer.end(installed ? `\u2713 ${bin} is installed` : `\u2716 ${bin} not found`);
171
+ return installed;
177
172
  }
178
- function getCliVersion(bin) {
179
- return new Promise((resolve) => {
180
- const proc = (0, import_node_child_process.spawn)(bin, ["--version"], { stdio: "pipe", shell: true });
181
- let stdout = "";
182
- let stderr = "";
183
- proc.stdout?.on("data", (data) => {
184
- stdout += data.toString();
185
- });
186
- proc.stderr?.on("data", (data) => {
187
- stderr += data.toString();
188
- });
189
- proc.on("close", (code) => {
190
- if (code !== 0) {
191
- resolve(null);
192
- return;
193
- }
194
- resolve(stdout.trim() || stderr.trim() || null);
195
- });
196
- proc.on("error", () => resolve(null));
197
- });
173
+ async function getCliVersion(bin) {
174
+ const result = await (0, import_execa.execa)(bin, ["--version"], { reject: false });
175
+ if (result.exitCode !== 0) return null;
176
+ return result.stdout.trim() || result.stderr.trim() || null;
198
177
  }
199
178
  function killOrphanCliProcesses(bin, options) {
200
179
  const label = options.label ?? bin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipanel/core",
3
- "version": "1.2.26",
3
+ "version": "1.2.27",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "lib/index.cjs",
@@ -32,6 +32,7 @@
32
32
  "registry": "https://registry.npmjs.org/"
33
33
  },
34
34
  "dependencies": {
35
+ "execa": "^9.6.1",
35
36
  "vue-tsc": "^3.3.9"
36
37
  },
37
38
  "scripts": {