@alint-js/cli 0.0.22 → 0.0.24
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 +2 -6
- package/dist/bin/index.mjs +1 -1
- package/dist/{cli-CmLooFry.mjs → cli-BsgD2UWS.mjs} +65 -33
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -421,11 +421,7 @@ import { defineRule } from '@alint-js/core'
|
|
|
421
421
|
|
|
422
422
|
export const checkFunctionRule = defineRule({
|
|
423
423
|
create: ctx => ({
|
|
424
|
-
async
|
|
425
|
-
if (target.kind !== 'function') {
|
|
426
|
-
return
|
|
427
|
-
}
|
|
428
|
-
|
|
424
|
+
async onTargetFunction(target) {
|
|
429
425
|
const model = await ctx.model({ capabilities: ['tool-call'], size: 'small' })
|
|
430
426
|
|
|
431
427
|
ctx.report({
|
|
@@ -467,7 +463,7 @@ Rule authors can opt out of caching when a rule depends on external state:
|
|
|
467
463
|
defineRule({
|
|
468
464
|
cache: false,
|
|
469
465
|
create: ctx => ({
|
|
470
|
-
|
|
466
|
+
onTargetFile(target) {
|
|
471
467
|
// Always reruns.
|
|
472
468
|
},
|
|
473
469
|
}),
|
package/dist/bin/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import process from "node:process";
|
|
2
2
|
import { inspect } from "node:util";
|
|
3
3
|
import { cac } from "cac";
|
|
4
|
+
import { appendFile, mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
4
5
|
import { getGlobalSetupConfigPath, getProjectSetupConfigPath, getStatsDir, installStaticPlugins, loadAlintConfig, loadSetupConfig, mergeSetupConfigs, writeSetupConfig } from "@alint-js/config";
|
|
5
|
-
import { AlintRunError, hasDiscoveryFilePatterns, matchesDiscoveryFile, normalizeConfig, resolveConfigForFile, runAlint } from "@alint-js/core";
|
|
6
|
+
import { AlintRunError, hasDiscoveryFilePatterns, matchesDiscoveryFile, normalizeConfig, resolveConfigForDirectory, resolveConfigForFile, runAlint } from "@alint-js/core";
|
|
6
7
|
import { isAbsolute, join, relative, resolve } from "pathe";
|
|
7
8
|
import { getBorderCharacters, table } from "table";
|
|
8
9
|
import { errorMessageFrom } from "@moeru/std/error";
|
|
9
|
-
import { appendFile, mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
10
10
|
import c, { createColors } from "tinyrainbow";
|
|
11
11
|
import cliSpinners from "cli-spinners";
|
|
12
12
|
import { relative as relative$1 } from "node:path";
|
|
@@ -14,7 +14,7 @@ import Gitignore from "gitignore-fs";
|
|
|
14
14
|
import { Minimatch, minimatch } from "minimatch";
|
|
15
15
|
import { errorMessageFrom as errorMessageFrom$1 } from "@moeru/std";
|
|
16
16
|
//#region package.json
|
|
17
|
-
var version = "0.0.
|
|
17
|
+
var version = "0.0.24";
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/cli/commands/command.ts
|
|
20
20
|
function defineCommand(node) {
|
|
@@ -208,15 +208,17 @@ function shouldSkipOptionValue(arg) {
|
|
|
208
208
|
//#endregion
|
|
209
209
|
//#region src/cli/commands/config/inspect.ts
|
|
210
210
|
const inspect$2 = defineCommand({
|
|
211
|
-
action: (context,
|
|
212
|
-
arguments: "<
|
|
213
|
-
description: "Inspect resolved config for a file",
|
|
211
|
+
action: (context, path, options) => runConfigInspectCommand(path, options.config, context.io),
|
|
212
|
+
arguments: "<path>",
|
|
213
|
+
description: "Inspect resolved config for a file or directory",
|
|
214
214
|
name: "inspect"
|
|
215
215
|
});
|
|
216
|
-
async function runConfigInspectCommand(
|
|
216
|
+
async function runConfigInspectCommand(path, configPath, io) {
|
|
217
217
|
const config = await loadAlintConfig(io.cwd, configPath);
|
|
218
|
-
const
|
|
219
|
-
|
|
218
|
+
const targetPath = resolve(io.cwd, path);
|
|
219
|
+
const isDirectory = await stat(targetPath).then((stats) => stats.isDirectory()).catch(() => false);
|
|
220
|
+
const result = isDirectory ? resolveConfigForDirectory(targetPath, config, { cwd: io.cwd }) : resolveConfigForFile(targetPath, config, { cwd: io.cwd });
|
|
221
|
+
io.stdout.write(`${isDirectory ? "directory" : "file"}: ${path}\n`);
|
|
220
222
|
io.stdout.write(`ignored: ${result.ignored ? "yes" : "no"}\n`);
|
|
221
223
|
io.stdout.write("matched:\n");
|
|
222
224
|
for (const item of result.matched) io.stdout.write(` - ${item.name ?? "<anonymous>"}\n`);
|
|
@@ -546,8 +548,9 @@ function formatJson(result) {
|
|
|
546
548
|
const colors$2 = createColors({ force: true });
|
|
547
549
|
function formatStylish(input, options = {}) {
|
|
548
550
|
const diagnostics = Array.isArray(input) ? input : input.diagnostics;
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
+
const result = Array.isArray(input) ? void 0 : input;
|
|
552
|
+
const style = createStyle(options.color === true);
|
|
553
|
+
if (diagnostics.length === 0) return result?.execution?.cached ? `${formatSummary(diagnostics, result, style)}\n` : "";
|
|
551
554
|
const diagnosticsByFile = /* @__PURE__ */ new Map();
|
|
552
555
|
for (const diagnostic of diagnostics) {
|
|
553
556
|
const fileDiagnostics = diagnosticsByFile.get(diagnostic.filePath);
|
|
@@ -558,7 +561,6 @@ function formatStylish(input, options = {}) {
|
|
|
558
561
|
diagnosticsByFile.set(diagnostic.filePath, [diagnostic]);
|
|
559
562
|
}
|
|
560
563
|
const lines = [];
|
|
561
|
-
const style = createStyle(options.color === true);
|
|
562
564
|
for (const [filePath, fileDiagnostics] of diagnosticsByFile) {
|
|
563
565
|
lines.push(style.file(filePath));
|
|
564
566
|
for (const diagnostic of fileDiagnostics) {
|
|
@@ -569,9 +571,12 @@ function formatStylish(input, options = {}) {
|
|
|
569
571
|
}
|
|
570
572
|
lines.push("");
|
|
571
573
|
}
|
|
572
|
-
lines.push("", formatSummary(diagnostics,
|
|
574
|
+
lines.push("", formatSummary(diagnostics, result, style));
|
|
573
575
|
return `${lines.join("\n")}\n`;
|
|
574
576
|
}
|
|
577
|
+
function countCachedDiagnostics(diagnostics, severity) {
|
|
578
|
+
return diagnostics.filter((diagnostic) => diagnostic.severity === severity && diagnostic.cached === true).length;
|
|
579
|
+
}
|
|
575
580
|
function countDiagnostics$2(diagnostics, severity) {
|
|
576
581
|
return diagnostics.filter((diagnostic) => diagnostic.severity === severity).length;
|
|
577
582
|
}
|
|
@@ -593,13 +598,32 @@ function createStyle(color) {
|
|
|
593
598
|
warning: colors$2.yellow
|
|
594
599
|
};
|
|
595
600
|
}
|
|
596
|
-
function
|
|
601
|
+
function formatDiagnosticCount(total, cached, label) {
|
|
602
|
+
return `${total} ${label}${cached > 0 ? ` (${cached} cached)` : ""}`;
|
|
603
|
+
}
|
|
604
|
+
function formatExecutionSummary(execution) {
|
|
605
|
+
if (!execution || execution.cached === 0) return;
|
|
606
|
+
return `${execution.cached}/${execution.planned} cached`;
|
|
607
|
+
}
|
|
608
|
+
function formatSummary(diagnostics, result, style) {
|
|
597
609
|
const warnCount = countDiagnostics$2(diagnostics, "warn");
|
|
598
610
|
const errorCount = countDiagnostics$2(diagnostics, "error");
|
|
599
|
-
const
|
|
600
|
-
const
|
|
611
|
+
const cachedWarnCount = countCachedDiagnostics(diagnostics, "warn");
|
|
612
|
+
const cachedErrorCount = countCachedDiagnostics(diagnostics, "error");
|
|
613
|
+
const tokens = result === void 0 ? void 0 : formatTokenSummary(result);
|
|
614
|
+
const problemSummary = [style.warning(formatDiagnosticCount(warnCount, cachedWarnCount, "warn")), style.error(formatDiagnosticCount(errorCount, cachedErrorCount, "error"))].join(" / ");
|
|
601
615
|
if (tokens === void 0) return problemSummary;
|
|
602
|
-
|
|
616
|
+
const execution = formatExecutionSummary(result?.execution);
|
|
617
|
+
return [
|
|
618
|
+
problemSummary,
|
|
619
|
+
style.summaryToken(tokens),
|
|
620
|
+
execution
|
|
621
|
+
].filter((segment) => segment !== void 0).join(" | ");
|
|
622
|
+
}
|
|
623
|
+
function formatTokenSummary(result) {
|
|
624
|
+
const liveTokens = result.usage.totalTokens.toLocaleString("en-US");
|
|
625
|
+
const cachedTokens = result.usage.cached?.totalTokens ?? 0;
|
|
626
|
+
return `${liveTokens} tokens${cachedTokens > 0 ? ` (${cachedTokens.toLocaleString("en-US")} cached)` : ""}`;
|
|
603
627
|
}
|
|
604
628
|
function identity(value) {
|
|
605
629
|
return value;
|
|
@@ -640,7 +664,7 @@ function countDiagnostics$1(diagnostics, severity) {
|
|
|
640
664
|
//#region src/cli/reporters/progress/summary.ts
|
|
641
665
|
const colors$1 = createColors({ force: true });
|
|
642
666
|
function createSummaryProgressReporter(options) {
|
|
643
|
-
const now =
|
|
667
|
+
const now = Date.now;
|
|
644
668
|
const state = {
|
|
645
669
|
cached: 0,
|
|
646
670
|
completed: 0,
|
|
@@ -988,10 +1012,10 @@ var NoFilesFoundError = class extends Error {
|
|
|
988
1012
|
this.pattern = pattern;
|
|
989
1013
|
}
|
|
990
1014
|
};
|
|
991
|
-
async function
|
|
1015
|
+
async function findLintTargets(options) {
|
|
992
1016
|
const { config, cwd, errorOnUnmatchedPattern = true, globInputPaths = true, inputs } = options;
|
|
993
1017
|
const gitignore = shouldFilterGitignoredFiles(config) ? new Gitignore() : void 0;
|
|
994
|
-
const
|
|
1018
|
+
const targets = await resolveInputFiles({
|
|
995
1019
|
config,
|
|
996
1020
|
cwd,
|
|
997
1021
|
errorOnUnmatchedPattern,
|
|
@@ -999,13 +1023,16 @@ async function findFiles(options) {
|
|
|
999
1023
|
globInputPaths,
|
|
1000
1024
|
inputs: inputs.length > 0 ? inputs : ["."]
|
|
1001
1025
|
});
|
|
1002
|
-
if (!gitignore ||
|
|
1026
|
+
if (!gitignore || targets.files.length === 0) return targets;
|
|
1003
1027
|
const lintFiles = [];
|
|
1004
|
-
for (const file of
|
|
1028
|
+
for (const file of targets.files) {
|
|
1005
1029
|
if (await gitignore.ignores(resolve(cwd, file))) continue;
|
|
1006
1030
|
lintFiles.push(file);
|
|
1007
1031
|
}
|
|
1008
|
-
return
|
|
1032
|
+
return {
|
|
1033
|
+
directories: targets.directories,
|
|
1034
|
+
files: lintFiles
|
|
1035
|
+
};
|
|
1009
1036
|
}
|
|
1010
1037
|
function collectGlobalIgnorePatterns(config) {
|
|
1011
1038
|
return normalizeConfig(config).flatMap((item) => isGlobalIgnoreItem(item) ? [...item.ignores] : []);
|
|
@@ -1046,6 +1073,7 @@ async function resolveInputFiles(options) {
|
|
|
1046
1073
|
const hasFilePatterns = hasDiscoveryFilePatterns(options.config);
|
|
1047
1074
|
const ignoredPatterns = collectGlobalIgnorePatterns(options.config);
|
|
1048
1075
|
const candidates = [];
|
|
1076
|
+
const directories = [];
|
|
1049
1077
|
for (const input of options.inputs) {
|
|
1050
1078
|
const path = resolve(options.cwd, input);
|
|
1051
1079
|
const stats = await statPath(path);
|
|
@@ -1054,12 +1082,13 @@ async function resolveInputFiles(options) {
|
|
|
1054
1082
|
continue;
|
|
1055
1083
|
}
|
|
1056
1084
|
if (stats?.isDirectory()) {
|
|
1057
|
-
if (!hasFilePatterns) continue;
|
|
1058
1085
|
if (await shouldPruneDirectory(path, {
|
|
1059
1086
|
cwd: options.cwd,
|
|
1060
1087
|
gitignore: options.gitignore,
|
|
1061
1088
|
ignoredPatterns
|
|
1062
1089
|
})) continue;
|
|
1090
|
+
directories.push(input);
|
|
1091
|
+
if (!hasFilePatterns) continue;
|
|
1063
1092
|
const directoryFiles = (await walkFiles(path, {
|
|
1064
1093
|
cwd: options.cwd,
|
|
1065
1094
|
gitignore: options.gitignore,
|
|
@@ -1086,7 +1115,10 @@ async function resolveInputFiles(options) {
|
|
|
1086
1115
|
}
|
|
1087
1116
|
if (options.errorOnUnmatchedPattern) throw new NoFilesFoundError(input, { globInputPaths: options.globInputPaths });
|
|
1088
1117
|
}
|
|
1089
|
-
return
|
|
1118
|
+
return {
|
|
1119
|
+
directories: [...new Set(directories)],
|
|
1120
|
+
files: [...new Set(candidates)]
|
|
1121
|
+
};
|
|
1090
1122
|
}
|
|
1091
1123
|
async function searchGlob(options) {
|
|
1092
1124
|
const root = resolve(options.cwd, getGlobParent(options.pattern));
|
|
@@ -1256,11 +1288,10 @@ function parseSince(time, now) {
|
|
|
1256
1288
|
const DEFAULT_RETENTION_MONTHS = 12;
|
|
1257
1289
|
const STATS_FILE_PATTERN = /^stats-(\d{4})-(\d{2})\.jsonl$/u;
|
|
1258
1290
|
function createJsonlStatsStore(options) {
|
|
1259
|
-
const now = options.clock ?? Date.now;
|
|
1260
1291
|
const retentionMonths = options.retentionMonths ?? DEFAULT_RETENTION_MONTHS;
|
|
1261
1292
|
return {
|
|
1262
|
-
query: (filter) => query(options.dir, filter ?? {}, now),
|
|
1263
|
-
record: (input) => record(options.dir, input, now(), retentionMonths)
|
|
1293
|
+
query: (filter) => query(options.dir, filter ?? {}, Date.now),
|
|
1294
|
+
record: (input) => record(options.dir, input, Date.now(), retentionMonths)
|
|
1264
1295
|
};
|
|
1265
1296
|
}
|
|
1266
1297
|
function accumulate(rows, key, inTok, outTok, totalTok, countRun) {
|
|
@@ -1539,9 +1570,9 @@ function isNodeError(error) {
|
|
|
1539
1570
|
async function runLintCommand(files, options, io, interceptConsoleOutput) {
|
|
1540
1571
|
if (options.config) await assertConfigExists(io.cwd, options.config);
|
|
1541
1572
|
const [setupConfig, config] = await Promise.all([loadMergedSetupConfig(io), loadAlintConfig(io.cwd, options.config)]);
|
|
1542
|
-
let
|
|
1573
|
+
let lintTargets;
|
|
1543
1574
|
try {
|
|
1544
|
-
|
|
1575
|
+
lintTargets = await findLintTargets({
|
|
1545
1576
|
config,
|
|
1546
1577
|
cwd: io.cwd,
|
|
1547
1578
|
errorOnUnmatchedPattern: true,
|
|
@@ -1571,7 +1602,8 @@ async function runLintCommand(files, options, io, interceptConsoleOutput) {
|
|
|
1571
1602
|
result = await runAlint({
|
|
1572
1603
|
config,
|
|
1573
1604
|
cwd: io.cwd,
|
|
1574
|
-
|
|
1605
|
+
directories: lintTargets.directories,
|
|
1606
|
+
files: lintTargets.files,
|
|
1575
1607
|
modelOverride: options.model,
|
|
1576
1608
|
outputLanguage: options.outputLanguage,
|
|
1577
1609
|
progress: mergeProgressReporters(progress?.reporter, statsCollector?.reporter),
|
|
@@ -1591,7 +1623,7 @@ async function runLintCommand(files, options, io, interceptConsoleOutput) {
|
|
|
1591
1623
|
progress?.dispose();
|
|
1592
1624
|
if (statsTarget && statsCollector) await writeRunStats(statsTarget, statsCollector, result, io.cwd);
|
|
1593
1625
|
io.stdout.write(formatDiagnostics(options.format, result, { color: io.stdout.isTTY === true }));
|
|
1594
|
-
return result.diagnostics.
|
|
1626
|
+
return result.diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
|
|
1595
1627
|
}
|
|
1596
1628
|
function shouldEnableProgress(options, io) {
|
|
1597
1629
|
if (options.progress !== void 0) return options.progress;
|
|
@@ -1646,7 +1678,7 @@ async function inspectOutputFile(io, file, options) {
|
|
|
1646
1678
|
io.stderr.write(`${errorMessageFrom$1(error)}\n`);
|
|
1647
1679
|
return 2;
|
|
1648
1680
|
}
|
|
1649
|
-
return parsed.diagnostics.
|
|
1681
|
+
return parsed.diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
|
|
1650
1682
|
}
|
|
1651
1683
|
function isDiagnostic(value) {
|
|
1652
1684
|
if (!isRecord(value)) return false;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as formatJson, n as formatDiagnostics, r as formatStylish, t as executeCli } from "./cli-
|
|
1
|
+
import { i as formatJson, n as formatDiagnostics, r as formatStylish, t as executeCli } from "./cli-BsgD2UWS.mjs";
|
|
2
2
|
import { ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated } from "@alint-js/config";
|
|
3
3
|
import { defineConfig } from "@alint-js/core";
|
|
4
4
|
export { defineConfig, executeCli, formatDiagnostics, formatJson, formatStylish, ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alint-js/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.24",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.mts",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"pathe": "^2.0.3",
|
|
26
26
|
"table": "^6.9.0",
|
|
27
27
|
"tinyrainbow": "^3.1.0",
|
|
28
|
-
"@alint-js/config": "0.0.
|
|
29
|
-
"@alint-js/core": "0.0.
|
|
28
|
+
"@alint-js/config": "0.0.24",
|
|
29
|
+
"@alint-js/core": "0.0.24"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@pnpm/find-workspace-dir": "^1000.1.5",
|