autotel-cli 0.18.5 → 0.18.6
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 +1 -1
- package/dist/index.js +149 -129
- package/package.json +13 -19
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -442,9 +442,10 @@ function sortImports(imports) {
|
|
|
442
442
|
const sideEffect = [];
|
|
443
443
|
const external = [];
|
|
444
444
|
const relative = [];
|
|
445
|
-
for (const imp of imports) if (imp.sideEffect)
|
|
446
|
-
|
|
447
|
-
|
|
445
|
+
for (const imp of imports) if (imp.sideEffect) {
|
|
446
|
+
if (imp.source === "autotel/register") sideEffect.unshift(imp);
|
|
447
|
+
else sideEffect.push(imp);
|
|
448
|
+
} else if (imp.source.startsWith(".") || imp.source.startsWith("/")) relative.push(imp);
|
|
448
449
|
else external.push(imp);
|
|
449
450
|
const sortBySource = (a, b) => a.source.localeCompare(b.source);
|
|
450
451
|
external.sort(sortBySource);
|
|
@@ -3024,32 +3025,34 @@ function applyPlan(args) {
|
|
|
3024
3025
|
}
|
|
3025
3026
|
const prod = plan.packagesToInstall.prod;
|
|
3026
3027
|
const dev = plan.packagesToInstall.dev;
|
|
3027
|
-
if (prod.length > 0 || dev.length > 0)
|
|
3028
|
-
if (
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3028
|
+
if (prod.length > 0 || dev.length > 0) {
|
|
3029
|
+
if (options.noInstall || options.printInstallCmd) {
|
|
3030
|
+
if (prod.length > 0) result.printedInstalls.push(getInstallCommand(project.packageManager, prod));
|
|
3031
|
+
if (dev.length > 0) result.printedInstalls.push(getInstallCommand(project.packageManager, dev, { dev: true }));
|
|
3032
|
+
} else {
|
|
3033
|
+
if (prod.length > 0) {
|
|
3034
|
+
const cmd = getInstallCommand(project.packageManager, prod);
|
|
3035
|
+
try {
|
|
3036
|
+
execSync(cmd, {
|
|
3037
|
+
cwd: project.packageRoot,
|
|
3038
|
+
stdio: "pipe"
|
|
3039
|
+
});
|
|
3040
|
+
result.ranInstalls.push(cmd);
|
|
3041
|
+
} catch {
|
|
3042
|
+
result.installErrors.push(cmd);
|
|
3043
|
+
}
|
|
3041
3044
|
}
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3045
|
+
if (dev.length > 0) {
|
|
3046
|
+
const cmd = getInstallCommand(project.packageManager, dev, { dev: true });
|
|
3047
|
+
try {
|
|
3048
|
+
execSync(cmd, {
|
|
3049
|
+
cwd: project.packageRoot,
|
|
3050
|
+
stdio: "pipe"
|
|
3051
|
+
});
|
|
3052
|
+
result.ranInstalls.push(cmd);
|
|
3053
|
+
} catch {
|
|
3054
|
+
result.installErrors.push(cmd);
|
|
3055
|
+
}
|
|
3053
3056
|
}
|
|
3054
3057
|
}
|
|
3055
3058
|
}
|
|
@@ -3471,29 +3474,30 @@ async function runChecks(options, projectRoot) {
|
|
|
3471
3474
|
}
|
|
3472
3475
|
});
|
|
3473
3476
|
const config = detectConfig(project.packageRoot);
|
|
3474
|
-
if (config.found)
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3477
|
+
if (config.found) {
|
|
3478
|
+
if (config.type === "cli-owned") checks.push({
|
|
3479
|
+
id: "config-found",
|
|
3480
|
+
title: "Configuration found",
|
|
3481
|
+
level: "info",
|
|
3482
|
+
status: "ok",
|
|
3483
|
+
message: `CLI-owned instrumentation at ${config.path}`
|
|
3484
|
+
});
|
|
3485
|
+
else if (config.type === "user-created") checks.push({
|
|
3486
|
+
id: "config-found",
|
|
3487
|
+
title: "Configuration found",
|
|
3488
|
+
level: "info",
|
|
3489
|
+
status: "ok",
|
|
3490
|
+
message: `User-created instrumentation at ${config.path}`,
|
|
3491
|
+
details: ["Add CLI header to enable auto-updates"]
|
|
3492
|
+
});
|
|
3493
|
+
else checks.push({
|
|
3494
|
+
id: "config-found",
|
|
3495
|
+
title: "Configuration found",
|
|
3496
|
+
level: "info",
|
|
3497
|
+
status: "ok",
|
|
3498
|
+
message: `Config found at ${config.path}`
|
|
3499
|
+
});
|
|
3500
|
+
} else checks.push({
|
|
3497
3501
|
id: "config-found",
|
|
3498
3502
|
title: "Configuration found",
|
|
3499
3503
|
level: "info",
|
|
@@ -3568,22 +3572,23 @@ async function runChecks(options, projectRoot) {
|
|
|
3568
3572
|
message: "No required environment variables for this backend"
|
|
3569
3573
|
});
|
|
3570
3574
|
const versionCheck = checkAutotelVersions(project.packageJson);
|
|
3571
|
-
if (versionCheck.packages.length > 1)
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3575
|
+
if (versionCheck.packages.length > 1) {
|
|
3576
|
+
if (versionCheck.compatible) checks.push({
|
|
3577
|
+
id: "version-compat",
|
|
3578
|
+
title: "Version compatibility",
|
|
3579
|
+
level: "warning",
|
|
3580
|
+
status: "ok",
|
|
3581
|
+
message: "All autotel packages are compatible"
|
|
3582
|
+
});
|
|
3583
|
+
else checks.push({
|
|
3584
|
+
id: "version-compat",
|
|
3585
|
+
title: "Version compatibility",
|
|
3586
|
+
level: "warning",
|
|
3587
|
+
status: "warn",
|
|
3588
|
+
message: "Autotel packages have mismatched major versions",
|
|
3589
|
+
details: versionCheck.packages.map((p) => `${p.name}@${p.version}`)
|
|
3590
|
+
});
|
|
3591
|
+
} else checks.push({
|
|
3587
3592
|
id: "version-compat",
|
|
3588
3593
|
title: "Version compatibility",
|
|
3589
3594
|
level: "warning",
|
|
@@ -3600,41 +3605,42 @@ async function runChecks(options, projectRoot) {
|
|
|
3600
3605
|
details: esmCheck.details
|
|
3601
3606
|
});
|
|
3602
3607
|
const loggerCheck = checkLoggerInstrumentation(project.packageRoot, deps);
|
|
3603
|
-
if (loggerCheck.hasLogger)
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3608
|
+
if (loggerCheck.hasLogger) {
|
|
3609
|
+
if (loggerCheck.configuredInCode && !loggerCheck.hasInstrumentation) checks.push({
|
|
3610
|
+
id: "logger-instrumentation",
|
|
3611
|
+
title: "Logger instrumentation",
|
|
3612
|
+
level: "warning",
|
|
3613
|
+
status: "warn",
|
|
3614
|
+
message: `${loggerCheck.logger} is configured but instrumentation package is missing`,
|
|
3615
|
+
details: [`${loggerCheck.logger} is used in autoInstrumentations but ${loggerCheck.instrumentationPackage} is not installed`, `Install it: ${getInstallCommand(project.packageManager, [loggerCheck.instrumentationPackage])}`],
|
|
3616
|
+
fix: {
|
|
3617
|
+
cmd: getInstallCommand(project.packageManager, [loggerCheck.instrumentationPackage]),
|
|
3618
|
+
description: `Install ${loggerCheck.instrumentationPackage}`
|
|
3619
|
+
}
|
|
3620
|
+
});
|
|
3621
|
+
else if (loggerCheck.hasInstrumentation && loggerCheck.configuredInCode) checks.push({
|
|
3622
|
+
id: "logger-instrumentation",
|
|
3623
|
+
title: "Logger instrumentation",
|
|
3624
|
+
level: "info",
|
|
3625
|
+
status: "ok",
|
|
3626
|
+
message: `${loggerCheck.logger} instrumentation is properly configured`
|
|
3627
|
+
});
|
|
3628
|
+
else if (loggerCheck.hasInstrumentation && !loggerCheck.configuredInCode) checks.push({
|
|
3629
|
+
id: "logger-instrumentation",
|
|
3630
|
+
title: "Logger instrumentation",
|
|
3631
|
+
level: "info",
|
|
3632
|
+
status: "ok",
|
|
3633
|
+
message: `${loggerCheck.logger} instrumentation package is installed`,
|
|
3634
|
+
details: [`Add '${loggerCheck.logger}' to autoInstrumentations in your init() call to enable trace context injection`]
|
|
3635
|
+
});
|
|
3636
|
+
else checks.push({
|
|
3637
|
+
id: "logger-instrumentation",
|
|
3638
|
+
title: "Logger instrumentation",
|
|
3639
|
+
level: "info",
|
|
3640
|
+
status: "skip",
|
|
3641
|
+
message: `${loggerCheck.logger} is installed but not configured in code`
|
|
3642
|
+
});
|
|
3643
|
+
} else checks.push({
|
|
3638
3644
|
id: "logger-instrumentation",
|
|
3639
3645
|
title: "Logger instrumentation",
|
|
3640
3646
|
level: "info",
|
|
@@ -5495,23 +5501,24 @@ function baselineError(source, reason) {
|
|
|
5495
5501
|
}
|
|
5496
5502
|
function readGitBaseline(cwd, ref) {
|
|
5497
5503
|
try {
|
|
5504
|
+
const prefix = execFileSync("git", [
|
|
5505
|
+
"-C",
|
|
5506
|
+
cwd,
|
|
5507
|
+
"rev-parse",
|
|
5508
|
+
"--show-prefix"
|
|
5509
|
+
], {
|
|
5510
|
+
encoding: "utf8",
|
|
5511
|
+
stdio: [
|
|
5512
|
+
"ignore",
|
|
5513
|
+
"pipe",
|
|
5514
|
+
"ignore"
|
|
5515
|
+
]
|
|
5516
|
+
}).trim();
|
|
5498
5517
|
return execFileSync("git", [
|
|
5499
5518
|
"-C",
|
|
5500
5519
|
cwd,
|
|
5501
5520
|
"show",
|
|
5502
|
-
`${ref}:${
|
|
5503
|
-
"-C",
|
|
5504
|
-
cwd,
|
|
5505
|
-
"rev-parse",
|
|
5506
|
-
"--show-prefix"
|
|
5507
|
-
], {
|
|
5508
|
-
encoding: "utf8",
|
|
5509
|
-
stdio: [
|
|
5510
|
-
"ignore",
|
|
5511
|
-
"pipe",
|
|
5512
|
-
"ignore"
|
|
5513
|
-
]
|
|
5514
|
-
}).trim()}${MAP_FILE_NAME}`
|
|
5521
|
+
`${ref}:${prefix}${MAP_FILE_NAME}`
|
|
5515
5522
|
], {
|
|
5516
5523
|
encoding: "utf8",
|
|
5517
5524
|
stdio: [
|
|
@@ -5519,7 +5526,7 @@ function readGitBaseline(cwd, ref) {
|
|
|
5519
5526
|
"pipe",
|
|
5520
5527
|
"ignore"
|
|
5521
5528
|
],
|
|
5522
|
-
maxBuffer:
|
|
5529
|
+
maxBuffer: 67108864
|
|
5523
5530
|
});
|
|
5524
5531
|
} catch {
|
|
5525
5532
|
return null;
|
|
@@ -6555,7 +6562,8 @@ async function resolveCodemodFiles(pathArg, cwd) {
|
|
|
6555
6562
|
return [];
|
|
6556
6563
|
}
|
|
6557
6564
|
}
|
|
6558
|
-
|
|
6565
|
+
const pattern = path$1.isAbsolute(pathArg) ? pathArg : path$1.join(cwd, pathArg);
|
|
6566
|
+
return (await glob(pattern, {
|
|
6559
6567
|
cwd,
|
|
6560
6568
|
absolute: true,
|
|
6561
6569
|
ignore: ["**/node_modules/**", "**/*.d.ts"]
|
|
@@ -8266,12 +8274,13 @@ async function runDiagnoseAnomalies(flags) {
|
|
|
8266
8274
|
await runInvestigate("diagnose anomalies", flags, async (backend) => {
|
|
8267
8275
|
const lookback = flags.lookbackMinutes ?? 60;
|
|
8268
8276
|
const nowMs = Date.now();
|
|
8269
|
-
|
|
8277
|
+
const result = await backend.searchTraces({
|
|
8270
8278
|
service: flags.service,
|
|
8271
8279
|
startTimeUnixMs: nowMs - lookback * 60 * 1e3,
|
|
8272
8280
|
endTimeUnixMs: nowMs,
|
|
8273
8281
|
limit: 100
|
|
8274
|
-
})
|
|
8282
|
+
});
|
|
8283
|
+
return detectAnomalies(result.items, {
|
|
8275
8284
|
service: flags.service,
|
|
8276
8285
|
operation: flags.operation
|
|
8277
8286
|
});
|
|
@@ -8414,12 +8423,13 @@ async function runExplainSlowdown(flags) {
|
|
|
8414
8423
|
await runInvestigate("correlate explain-slowdown", flags, async (backend) => {
|
|
8415
8424
|
const lookback = flags.lookbackMinutes ?? 60;
|
|
8416
8425
|
const nowMs = Date.now();
|
|
8417
|
-
const
|
|
8426
|
+
const result = await backend.searchTraces({
|
|
8418
8427
|
service: flags.service,
|
|
8419
8428
|
startTimeUnixMs: nowMs - lookback * 60 * 1e3,
|
|
8420
8429
|
endTimeUnixMs: nowMs,
|
|
8421
8430
|
limit: 100
|
|
8422
|
-
})
|
|
8431
|
+
});
|
|
8432
|
+
const anomalies = detectAnomalies(result.items, { service: flags.service });
|
|
8423
8433
|
const findings = await Promise.all(anomalies.map(async (anomaly) => {
|
|
8424
8434
|
const sampleTraceId = anomaly.affectedTraceIds[0];
|
|
8425
8435
|
if (!sampleTraceId) return {
|
|
@@ -8486,7 +8496,8 @@ async function collectTracesForAnalytics(backend, input) {
|
|
|
8486
8496
|
}
|
|
8487
8497
|
async function runLlmUsage(flags) {
|
|
8488
8498
|
await runInvestigate("llm usage", flags, async (backend) => {
|
|
8489
|
-
const
|
|
8499
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8500
|
+
const report = collectUsage(traces);
|
|
8490
8501
|
return {
|
|
8491
8502
|
period: {
|
|
8492
8503
|
startTime: flags.startTime ?? null,
|
|
@@ -8513,7 +8524,8 @@ async function runLlmUsage(flags) {
|
|
|
8513
8524
|
}
|
|
8514
8525
|
async function runLlmModels(flags) {
|
|
8515
8526
|
await runInvestigate("llm models", flags, async (backend) => {
|
|
8516
|
-
const
|
|
8527
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8528
|
+
const models = listModels(traces).slice(0, flags.limit ?? 1e3);
|
|
8517
8529
|
return {
|
|
8518
8530
|
count: models.length,
|
|
8519
8531
|
models
|
|
@@ -8522,14 +8534,16 @@ async function runLlmModels(flags) {
|
|
|
8522
8534
|
}
|
|
8523
8535
|
async function runLlmModelStats(flags) {
|
|
8524
8536
|
await runInvestigate("llm model-stats", flags, async (backend) => {
|
|
8525
|
-
const
|
|
8537
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8538
|
+
const stats = getModelStats(traces, flags.modelName);
|
|
8526
8539
|
if (!stats) return { error: `No traces found for model '${flags.modelName}' in the specified time range` };
|
|
8527
8540
|
return stats;
|
|
8528
8541
|
});
|
|
8529
8542
|
}
|
|
8530
8543
|
async function runLlmExpensive(flags) {
|
|
8531
8544
|
await runInvestigate("llm expensive", flags, async (backend) => {
|
|
8532
|
-
|
|
8545
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8546
|
+
let ranked = rankExpensiveTraces(traces);
|
|
8533
8547
|
if (flags.minTokens !== void 0) ranked = ranked.filter((t) => t.tokens.total >= flags.minTokens);
|
|
8534
8548
|
ranked = ranked.slice(0, flags.limit ?? 10);
|
|
8535
8549
|
return {
|
|
@@ -8540,7 +8554,8 @@ async function runLlmExpensive(flags) {
|
|
|
8540
8554
|
}
|
|
8541
8555
|
async function runLlmSlow(flags) {
|
|
8542
8556
|
await runInvestigate("llm slow", flags, async (backend) => {
|
|
8543
|
-
|
|
8557
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8558
|
+
let ranked = rankSlowTraces(traces);
|
|
8544
8559
|
if (flags.minDurationMs !== void 0) ranked = ranked.filter((t) => t.durationMs >= flags.minDurationMs);
|
|
8545
8560
|
ranked = ranked.slice(0, flags.limit ?? 10);
|
|
8546
8561
|
return {
|
|
@@ -8551,7 +8566,8 @@ async function runLlmSlow(flags) {
|
|
|
8551
8566
|
}
|
|
8552
8567
|
async function runLlmTools(flags) {
|
|
8553
8568
|
await runInvestigate("llm tools", flags, async (backend) => {
|
|
8554
|
-
const
|
|
8569
|
+
const traces = await collectTracesForAnalytics(backend, flags);
|
|
8570
|
+
const tools = listToolUsage(traces).slice(0, flags.limit ?? 1e3);
|
|
8555
8571
|
return {
|
|
8556
8572
|
count: tools.length,
|
|
8557
8573
|
totalCalls: tools.reduce((sum, t) => sum + t.usageCount, 0),
|
|
@@ -8741,7 +8757,8 @@ function assertVersion(version) {
|
|
|
8741
8757
|
}
|
|
8742
8758
|
async function runCollectorValidate(flags) {
|
|
8743
8759
|
await runStatic("collector validate", flags, async () => {
|
|
8744
|
-
|
|
8760
|
+
const config = readJsonFromStdinOrFile(flags.configFile);
|
|
8761
|
+
return validateOtlpReceiverConfig(config);
|
|
8745
8762
|
});
|
|
8746
8763
|
}
|
|
8747
8764
|
async function runCollectorSuggest(flags) {
|
|
@@ -9743,7 +9760,10 @@ async function run() {
|
|
|
9743
9760
|
const parseWithTelemetry = withCommanderTelemetry({
|
|
9744
9761
|
name: () => program.name(),
|
|
9745
9762
|
version: () => program.version() ?? "",
|
|
9746
|
-
parseAsync
|
|
9763
|
+
async parseAsync(argv) {
|
|
9764
|
+
await program.parseAsync(argv);
|
|
9765
|
+
return this;
|
|
9766
|
+
}
|
|
9747
9767
|
}, {
|
|
9748
9768
|
name: "autotel",
|
|
9749
9769
|
version: program.version()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-cli",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.6",
|
|
4
4
|
"description": "CLI for autotel - setup wizard, diagnostics, and incremental features",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,31 +18,25 @@
|
|
|
18
18
|
"NOTICE"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@inquirer/prompts": "^8.
|
|
21
|
+
"@inquirer/prompts": "^8.7.2",
|
|
22
22
|
"@opentelemetry/otlp-transformer": "^0.222.0",
|
|
23
|
-
"autotel-mcp": "0.
|
|
24
|
-
"chalk": "^
|
|
23
|
+
"autotel-mcp": "0.10.0",
|
|
24
|
+
"chalk": "^6.0.1",
|
|
25
25
|
"commander": "^15.0.0",
|
|
26
26
|
"glob": "^13.0.6",
|
|
27
27
|
"ora": "^9.4.1",
|
|
28
28
|
"semver": "^7.8.5",
|
|
29
29
|
"ts-morph": "^28.0.0",
|
|
30
|
-
"yaml": "^2.9.
|
|
30
|
+
"yaml": "^2.9.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@types/
|
|
35
|
-
"@types/node": "^26.1.2",
|
|
36
|
-
"@types/semver": "^7.7.1",
|
|
33
|
+
"@types/node": "^26.6.3",
|
|
34
|
+
"@types/semver": "^7.8.0",
|
|
37
35
|
"autotel-telemetry": "0.2.0",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"tsx": "^4.23.1",
|
|
43
|
-
"typescript": "^6.0.3",
|
|
44
|
-
"typescript-eslint": "^8.65.0",
|
|
45
|
-
"vitest": "^4.1.10"
|
|
36
|
+
"tsdown": "^0.23.0",
|
|
37
|
+
"tsx": "^4.23.15",
|
|
38
|
+
"typescript": "^7.0.2",
|
|
39
|
+
"vitest": "^5.0.2"
|
|
46
40
|
},
|
|
47
41
|
"engines": {
|
|
48
42
|
"node": ">=22.0.0"
|
|
@@ -69,7 +63,7 @@
|
|
|
69
63
|
"dev": "tsdown --watch",
|
|
70
64
|
"test": "vitest run --config vitest.unit.config.ts",
|
|
71
65
|
"test:watch": "vitest",
|
|
72
|
-
"lint": "
|
|
73
|
-
"
|
|
66
|
+
"lint": "oxlint -c oxlint.json --disable-nested-config src",
|
|
67
|
+
"type-check": "tsc --noEmit"
|
|
74
68
|
}
|
|
75
69
|
}
|