@alint-js/core 0.0.28 → 0.0.30

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.
@@ -47,4 +47,23 @@ function withAgentRetry(adapter, retries = 2) {
47
47
  };
48
48
  }
49
49
  //#endregion
50
- export { isRetryableAgentError as n, withAgentRetry as r, RetryableAgentError as t };
50
+ //#region src/agent/index.ts
51
+ function combineAbortSignals(...candidates) {
52
+ const signals = candidates.filter((signal) => signal !== void 0);
53
+ if (signals.length === 0) return void 0;
54
+ if (signals.length === 1) return signals[0];
55
+ return AbortSignal.any(signals);
56
+ }
57
+ function defineTool(tool) {
58
+ return tool;
59
+ }
60
+ function requireAgent(context) {
61
+ if (!context.agent) throw new TypeError(`Rule "${context.id}" requires an agent, but none is configured. Set "agent" in alint config (e.g. agent: createApeiraAdapter()).`);
62
+ const agent = context.agent;
63
+ return async (request) => agent({
64
+ ...request,
65
+ signal: request.signal ?? context.signal
66
+ });
67
+ }
68
+ //#endregion
69
+ export { isRetryableAgentError as a, RetryableAgentError as i, defineTool as n, withAgentRetry as o, requireAgent as r, combineAbortSignals as t };
package/dist/agent.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { J as AgentResult, K as AgentAdapter, X as AgentUsage, Y as AgentTool, q as AgentRequest, v as RuleContext } from "./types-BM_nUu_Z.mjs";
1
+ import { A as AgentTool, D as AgentAdapter, O as AgentRequest, j as AgentUsage, k as AgentResult, v as RuleContext } from "./types-CR_Grd6q.mjs";
2
2
  //#region src/agent/retry.d.ts
3
3
  /**
4
4
  * Declares that the complete adapter invocation can be safely replayed.
@@ -10,7 +10,8 @@ declare class RetryableAgentError extends Error {
10
10
  declare function isRetryableAgentError(error: unknown): error is RetryableAgentError;
11
11
  //#endregion
12
12
  //#region src/agent/index.d.ts
13
+ declare function combineAbortSignals(...candidates: Array<AbortSignal | undefined>): AbortSignal | undefined;
13
14
  declare function defineTool(tool: AgentTool): AgentTool;
14
15
  declare function requireAgent(context: Pick<RuleContext, 'agent' | 'id' | 'signal'>): AgentAdapter;
15
16
  //#endregion
16
- export { type AgentAdapter, type AgentRequest, type AgentResult, type AgentTool, type AgentUsage, RetryableAgentError, defineTool, isRetryableAgentError, requireAgent };
17
+ export { type AgentAdapter, type AgentRequest, type AgentResult, type AgentTool, type AgentUsage, RetryableAgentError, combineAbortSignals, defineTool, isRetryableAgentError, requireAgent };
package/dist/agent.mjs CHANGED
@@ -1,15 +1,2 @@
1
- import { n as isRetryableAgentError, t as RetryableAgentError } from "./retry-C4sGjSE5.mjs";
2
- //#region src/agent/index.ts
3
- function defineTool(tool) {
4
- return tool;
5
- }
6
- function requireAgent(context) {
7
- if (!context.agent) throw new TypeError(`Rule "${context.id}" requires an agent, but none is configured. Set "agent" in alint config (e.g. agent: createApeiraAdapter()).`);
8
- const agent = context.agent;
9
- return async (request) => agent({
10
- ...request,
11
- signal: request.signal ?? context.signal
12
- });
13
- }
14
- //#endregion
15
- export { RetryableAgentError, defineTool, isRetryableAgentError, requireAgent };
1
+ import { a as isRetryableAgentError, i as RetryableAgentError, n as defineTool, r as requireAgent, t as combineAbortSignals } from "./agent-weXkvGkc.mjs";
2
+ export { RetryableAgentError, combineAbortSignals, defineTool, isRetryableAgentError, requireAgent };
@@ -0,0 +1,358 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { extname } from "node:path";
3
+ import { clamp } from "es-toolkit";
4
+ import { parseSync } from "oxc-parser";
5
+ //#region src/core/source/runtime.ts
6
+ function createSourceFile(path, text) {
7
+ return {
8
+ language: inferLanguage(path),
9
+ lines: text.split(/\r?\n/),
10
+ path,
11
+ text
12
+ };
13
+ }
14
+ function createSourceRuntime() {
15
+ return {
16
+ getText,
17
+ readFile: async (filePath) => createSourceFile(filePath, await readFile(filePath, "utf8")),
18
+ sliceLines,
19
+ sliceRange
20
+ };
21
+ }
22
+ function getText(target) {
23
+ return target.text;
24
+ }
25
+ function sliceLines(file, range) {
26
+ const startLine = clampLine(range.startLine, file.lines.length);
27
+ const endLine = clampLine(range.endLine, file.lines.length);
28
+ const orderedStartLine = Math.min(startLine, endLine);
29
+ const orderedEndLine = Math.max(startLine, endLine);
30
+ const text = file.lines.slice(orderedStartLine - 1, orderedEndLine).join("\n");
31
+ return {
32
+ filePath: file.path,
33
+ loc: {
34
+ end: {
35
+ column: file.lines[orderedEndLine - 1]?.length ?? 0,
36
+ line: orderedEndLine
37
+ },
38
+ start: {
39
+ column: 0,
40
+ line: orderedStartLine
41
+ }
42
+ },
43
+ text
44
+ };
45
+ }
46
+ function sliceRange(file, range) {
47
+ const start = clampOffset(range.start, file.text.length);
48
+ const end = clampOffset(range.end, file.text.length);
49
+ const orderedStart = Math.min(start, end);
50
+ const orderedEnd = Math.max(start, end);
51
+ return {
52
+ filePath: file.path,
53
+ loc: {
54
+ end: getPosition(file.text, orderedEnd),
55
+ start: getPosition(file.text, orderedStart)
56
+ },
57
+ text: file.text.slice(orderedStart, orderedEnd)
58
+ };
59
+ }
60
+ function clampLine(line, lineCount) {
61
+ if (lineCount === 0) return 1;
62
+ return clamp(Math.trunc(line), 1, lineCount);
63
+ }
64
+ function clampOffset(offset, textLength) {
65
+ return clamp(Math.trunc(offset), 0, textLength);
66
+ }
67
+ function getPosition(text, offset) {
68
+ let line = 1;
69
+ let column = 0;
70
+ let index = 0;
71
+ while (index < offset) {
72
+ const character = text[index];
73
+ if (character === "\r") {
74
+ if (text[index + 1] === "\n" && index + 1 < offset) index += 1;
75
+ line += 1;
76
+ column = 0;
77
+ } else if (character === "\n") {
78
+ line += 1;
79
+ column = 0;
80
+ } else column += 1;
81
+ index += 1;
82
+ }
83
+ return {
84
+ column,
85
+ line
86
+ };
87
+ }
88
+ function inferLanguage(path) {
89
+ switch (extname(path)) {
90
+ case ".cjs":
91
+ case ".js":
92
+ case ".jsx":
93
+ case ".mjs": return "javascript";
94
+ case ".cts":
95
+ case ".mts":
96
+ case ".ts":
97
+ case ".tsx": return "typescript";
98
+ default: return "unknown";
99
+ }
100
+ }
101
+ //#endregion
102
+ //#region src/core/languages/js/parser.ts
103
+ function parseSync$1(filename, sourceText, options) {
104
+ return parseSync(filename, sourceText, options);
105
+ }
106
+ //#endregion
107
+ //#region src/core/languages/js/extract.ts
108
+ function extractJsSourceTargets(file) {
109
+ const result = parseSync$1(file.path, file.text, { sourceType: "module" });
110
+ const state = {
111
+ bindingNodes: /* @__PURE__ */ new Map(),
112
+ exportedNodes: /* @__PURE__ */ new Set(),
113
+ file,
114
+ inferredNames: /* @__PURE__ */ new Map(),
115
+ seenClasses: /* @__PURE__ */ new Set(),
116
+ seenFunctions: /* @__PURE__ */ new Set(),
117
+ targets: [],
118
+ visited: /* @__PURE__ */ new Set()
119
+ };
120
+ collectModuleBindings(result.program, state);
121
+ collectExportedBindings(result.program, state);
122
+ visit(result.program, state);
123
+ const sortedTargets = [...state.targets].sort((left, right) => (left.range?.start ?? 0) - (right.range?.start ?? 0));
124
+ return [createFileTarget(file), ...withStableIdentities(sortedTargets)];
125
+ }
126
+ function addClassTarget(node, state) {
127
+ if (state.seenClasses.has(node)) return;
128
+ const target = createClassTarget(node, state);
129
+ if (!target) return;
130
+ state.seenClasses.add(node);
131
+ state.targets.push(target);
132
+ }
133
+ function addFunctionTarget(node, state) {
134
+ if (state.seenFunctions.has(node)) return;
135
+ const target = createFunctionTarget(node, state);
136
+ if (!target) return;
137
+ state.seenFunctions.add(node);
138
+ state.targets.push(target);
139
+ }
140
+ function asAstNode(value) {
141
+ return isAstNode(value) ? value : void 0;
142
+ }
143
+ function collectDeclarationBindings(node, state) {
144
+ const name = getNodeName(node);
145
+ if (name && (isClassNode(node) || isFunctionNode(node))) {
146
+ state.bindingNodes.set(name, node);
147
+ return;
148
+ }
149
+ if (node.type !== "VariableDeclaration" || !Array.isArray(node.declarations)) return;
150
+ for (const declarator of node.declarations) {
151
+ if (!isAstNode(declarator)) continue;
152
+ const id = asAstNode(declarator.id);
153
+ const initializer = asAstNode(declarator.init);
154
+ if (typeof id?.name === "string" && initializer && (isClassNode(initializer) || isFunctionNode(initializer))) state.bindingNodes.set(id.name, initializer);
155
+ }
156
+ }
157
+ function collectExportedBindings(node, state) {
158
+ if (!node) return;
159
+ if (Array.isArray(node)) {
160
+ for (const child of node) collectExportedBindings(child, state);
161
+ return;
162
+ }
163
+ if (node.type === "ExportNamedDeclaration" && !node.source && Array.isArray(node.specifiers)) for (const specifier of node.specifiers) {
164
+ if (!isAstNode(specifier) || specifier.type !== "ExportSpecifier") continue;
165
+ const local = asAstNode(specifier.local);
166
+ if (typeof local?.name === "string") markExportedBinding(local.name, state);
167
+ }
168
+ else if (node.type === "ExportDefaultDeclaration") {
169
+ const declaration = asAstNode(node.declaration);
170
+ if (typeof declaration?.name === "string") markExportedBinding(declaration.name, state);
171
+ }
172
+ for (const value of Object.values(node)) if (Array.isArray(value)) collectExportedBindings(value.filter(isAstNode), state);
173
+ else if (isAstNode(value)) collectExportedBindings(value, state);
174
+ }
175
+ function collectModuleBindings(program, state) {
176
+ if (!Array.isArray(program.body)) return;
177
+ for (const statement of program.body) {
178
+ if (!isAstNode(statement)) continue;
179
+ const declaration = isExportDeclaration(statement) ? asAstNode(statement.declaration) : statement;
180
+ if (declaration) collectDeclarationBindings(declaration, state);
181
+ }
182
+ }
183
+ function createClassTarget(node, state) {
184
+ const range = getRange(node);
185
+ if (!range) return;
186
+ const source = sliceRange(state.file, range);
187
+ const name = getNodeName(node) ?? state.inferredNames.get(node);
188
+ return {
189
+ file: state.file,
190
+ identity: createRangeIdentity("class", name, range),
191
+ kind: "class",
192
+ language: state.file.language,
193
+ loc: source.loc,
194
+ metadata: { exported: isExportedTarget(node, state) },
195
+ name,
196
+ origin: {
197
+ physicalPath: state.file.path,
198
+ range
199
+ },
200
+ range,
201
+ text: source.text
202
+ };
203
+ }
204
+ function createFileTarget(file) {
205
+ return {
206
+ file,
207
+ identity: "file",
208
+ kind: "file",
209
+ language: file.language,
210
+ origin: { physicalPath: file.path },
211
+ text: file.text
212
+ };
213
+ }
214
+ function createFunctionTarget(node, state) {
215
+ const range = getRange(node);
216
+ if (!range) return;
217
+ const source = sliceRange(state.file, range);
218
+ const functionNode = node.type === "MethodDefinition" ? asAstNode(node.value) : node;
219
+ const name = getNodeName(node) ?? getNodeName(functionNode) ?? state.inferredNames.get(node);
220
+ return {
221
+ file: state.file,
222
+ identity: createRangeIdentity("function", name, range),
223
+ kind: "function",
224
+ language: state.file.language,
225
+ loc: source.loc,
226
+ metadata: {
227
+ async: functionNode?.async === true,
228
+ exported: isExportedTarget(node, state)
229
+ },
230
+ name,
231
+ origin: {
232
+ physicalPath: state.file.path,
233
+ range
234
+ },
235
+ range,
236
+ text: source.text
237
+ };
238
+ }
239
+ function createRangeIdentity(kind, name, range) {
240
+ return `${kind}:${name ?? "anonymous"}:${range.start}:${range.end}`;
241
+ }
242
+ function createSemanticIdentity(target) {
243
+ if (target.kind !== "class" && target.kind !== "function" || !target.name) return;
244
+ return `${target.kind}:${target.name}`;
245
+ }
246
+ function getNodeName(node) {
247
+ if (!node) return;
248
+ if (typeof node.name === "string") return node.name;
249
+ const id = asAstNode(node.id);
250
+ if (typeof id?.name === "string") return id.name;
251
+ const key = asAstNode(node.key);
252
+ if (typeof key?.name === "string") return key.name;
253
+ if (typeof key?.value === "string" || typeof key?.value === "number") return String(key.value);
254
+ }
255
+ function getRange(node) {
256
+ if (typeof node.start === "number" && typeof node.end === "number") return {
257
+ end: node.end,
258
+ start: node.start
259
+ };
260
+ if (Array.isArray(node.range) && node.range.length === 2) return {
261
+ end: node.range[1],
262
+ start: node.range[0]
263
+ };
264
+ }
265
+ function inferChildName(parent, key, child, state) {
266
+ if (state.inferredNames.has(child)) return;
267
+ if (parent.type === "VariableDeclarator" && key === "init") {
268
+ const id = asAstNode(parent.id);
269
+ if (typeof id?.name === "string") state.inferredNames.set(child, id.name);
270
+ }
271
+ if (parent.type === "Property" && key === "value") {
272
+ const name = getNodeName(parent);
273
+ if (name) state.inferredNames.set(child, name);
274
+ }
275
+ }
276
+ function isAstNode(value) {
277
+ return typeof value === "object" && value !== null && typeof value.type === "string";
278
+ }
279
+ function isClassNode(node) {
280
+ return node.type === "ClassDeclaration" || node.type === "ClassExpression";
281
+ }
282
+ function isExportDeclaration(node) {
283
+ return node.type === "ExportDefaultDeclaration" || node.type === "ExportNamedDeclaration";
284
+ }
285
+ function isExportedTarget(node, state) {
286
+ return state.exportedNodes.has(node);
287
+ }
288
+ function isFunctionNode(node) {
289
+ return node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
290
+ }
291
+ function markExportedBinding(name, state) {
292
+ const bindingNode = state.bindingNodes.get(name);
293
+ if (bindingNode) state.exportedNodes.add(bindingNode);
294
+ }
295
+ function markExportedDeclaration(node, state) {
296
+ state.exportedNodes.add(node);
297
+ if (node.type !== "VariableDeclaration" || !Array.isArray(node.declarations)) return;
298
+ for (const declarator of node.declarations) {
299
+ if (!isAstNode(declarator)) continue;
300
+ const initializer = asAstNode(declarator.init);
301
+ if (initializer && (isClassNode(initializer) || isFunctionNode(initializer))) state.exportedNodes.add(initializer);
302
+ }
303
+ }
304
+ function visit(node, state) {
305
+ if (!node) return;
306
+ if (Array.isArray(node)) {
307
+ for (const child of node) visit(child, state);
308
+ return;
309
+ }
310
+ if (state.visited.has(node)) return;
311
+ state.visited.add(node);
312
+ if (node.type === "ExportDefaultDeclaration" || node.type === "ExportNamedDeclaration") {
313
+ if (node.declaration) {
314
+ markExportedDeclaration(node.declaration, state);
315
+ visit(node.declaration, state);
316
+ }
317
+ visitChildren(node, state, /* @__PURE__ */ new Set(["declaration"]));
318
+ return;
319
+ }
320
+ if (isClassNode(node)) addClassTarget(node, state);
321
+ else if (isFunctionNode(node) || node.type === "MethodDefinition") {
322
+ addFunctionTarget(node, state);
323
+ const methodValue = node.type === "MethodDefinition" ? asAstNode(node.value) : void 0;
324
+ if (methodValue) state.seenFunctions.add(methodValue);
325
+ }
326
+ visitChildren(node, state);
327
+ }
328
+ function visitChildren(node, state, skippedKeys = /* @__PURE__ */ new Set()) {
329
+ for (const [key, value] of Object.entries(node)) {
330
+ if (skippedKeys.has(key) || key === "type" || key === "start" || key === "end" || key === "range") continue;
331
+ if (Array.isArray(value)) {
332
+ for (const child of value) if (isAstNode(child)) {
333
+ inferChildName(node, key, child, state);
334
+ visit(child, state);
335
+ }
336
+ } else if (isAstNode(value)) {
337
+ inferChildName(node, key, value, state);
338
+ visit(value, state);
339
+ }
340
+ }
341
+ }
342
+ function withStableIdentities(targets) {
343
+ const semanticIdentityCounts = /* @__PURE__ */ new Map();
344
+ for (const target of targets) {
345
+ const semanticIdentity = createSemanticIdentity(target);
346
+ if (semanticIdentity) semanticIdentityCounts.set(semanticIdentity, (semanticIdentityCounts.get(semanticIdentity) ?? 0) + 1);
347
+ }
348
+ return targets.map((target) => {
349
+ const semanticIdentity = createSemanticIdentity(target);
350
+ if (!semanticIdentity || semanticIdentityCounts.get(semanticIdentity) !== 1) return target;
351
+ return {
352
+ ...target,
353
+ identity: semanticIdentity
354
+ };
355
+ });
356
+ }
357
+ //#endregion
358
+ export { sliceRange as a, sliceLines as i, createSourceFile as n, createSourceRuntime as r, extractJsSourceTargets as t };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { $ as ResolvedModel, A as LanguageContext, B as SourceRuntime, C as RuleSeverity, D as ClassTarget, E as Target, F as ProcessorPostprocessContext, G as SourceText, H as SourceTargetKind, I as SourceFile, L as SourceLocation, M as ProcessedSource, N as ProcessedSourceOrigin, O as FileTarget, P as ProcessorContext, Q as ResolveModelOptions, R as SourcePosition, S as RuleRegistry, T as RuleWithHandler, U as SourceTargetOfKind, V as SourceTarget, W as SourceTargetOrigin, Z as ModelRequirement, _ as RuleConfigEntry, a as AlintLinterOptions, at as RunnerStatsConfig, b as RuleHandlers, c as DiagnosticLocation, d as IgnoreConfig, et as ResolvedProvider, f as LanguageDefinition, g as RuleCacheConfig, h as ProjectTarget, i as AlintConfigItem, it as RunnerConfig, j as LineRange, k as FunctionTarget, l as DirectoryTarget, m as ProcessorDefinition, n as AlintConfigExtends, nt as ProviderDefinition, o as Awaitable, ot as SetupConfig, p as PluginDefinition, r as AlintConfigInput, rt as ProviderType, s as DiagnosticDescriptor, st as SetupModelDefinition, t as AlintConfig, tt as ModelSize, u as EnabledRule, v as RuleContext, w as RuleSpecializedHandlers, x as RuleInferenceUsageRecord, y as RuleDefinition, z as SourceRange } from "./types-BM_nUu_Z.mjs";
1
+ import { B as RunnerStatsConfig, C as RuleSeverity, E as Target, F as ResolvedProvider, H as SetupModelDefinition, I as ModelSize, L as ProviderDefinition, M as ModelRequirement, N as ResolveModelOptions, P as ResolvedModel, R as ProviderType, S as RuleRegistry, T as RuleWithHandler, V as SetupConfig, _ as RuleConfigEntry, a as AlintLinterOptions, b as RuleHandlers, c as DiagnosticLocation, d as IgnoreConfig, f as LanguageDefinition, g as RuleCacheConfig, h as ProjectTarget, i as AlintConfigItem, l as DirectoryTarget, m as ProcessorDefinition, n as AlintConfigExtends, o as Awaitable, p as PluginDefinition, r as AlintConfigInput, s as DiagnosticDescriptor, t as AlintConfig, u as EnabledRule, v as RuleContext, w as RuleSpecializedHandlers, x as RuleInferenceUsageRecord, y as RuleDefinition, z as RunnerConfig } from "./types-CR_Grd6q.mjs";
2
+ import { _ as SourceTargetOfKind, a as LineRange, c as ProcessorContext, d as SourceLocation, f as SourcePosition, g as SourceTargetKind, h as SourceTarget, i as LanguageContext, l as ProcessorPostprocessContext, m as SourceRuntime, n as FileTarget, o as ProcessedSource, p as SourceRange, r as FunctionTarget, s as ProcessedSourceOrigin, t as ClassTarget, u as SourceFile, v as SourceTargetOrigin, y as SourceText } from "./types-DSvXUVZ7.mjs";
2
3
  //#region src/config/config-array.d.ts
3
4
  interface EffectiveAlintConfig {
4
5
  agent?: AlintConfigItem['agent'];
@@ -47,18 +48,11 @@ declare function resolveLanguage(file: SourceFile, registry: LanguageRegistry, o
47
48
  //#region src/core/languages/index.d.ts
48
49
  declare function createBuiltInLanguageRegistry(): LanguageRegistry;
49
50
  //#endregion
50
- //#region src/core/languages/js/extract.d.ts
51
- declare function extractJsSourceTargets(file: SourceFile): SourceTarget[];
52
- //#endregion
53
51
  //#region src/core/types.d.ts
54
52
  interface AlintRunFailure {
55
- filePath?: string;
53
+ job: ProgressJob;
54
+ kind: 'cache-replay' | 'handler' | 'timeout';
56
55
  message: string;
57
- ruleId?: string;
58
- target?: {
59
- kind: ProgressTargetKind;
60
- name?: string;
61
- };
62
56
  }
63
57
  interface Diagnostic {
64
58
  cached?: boolean;
@@ -76,96 +70,70 @@ interface Diagnostic {
76
70
  }
77
71
  interface DiagnosticProgressPayload {
78
72
  diagnostic: Diagnostic;
79
- diagnostics: Diagnostic[];
80
- path?: ProgressPath;
73
+ job: ProgressJob;
81
74
  }
82
- interface FileProgressPayload {
83
- endedAt?: number;
84
- file: ProgressFilePath;
85
- startedAt?: number;
75
+ interface ExecutionCounts {
76
+ cached: number;
77
+ cancelled: number;
78
+ completed: number;
79
+ failed: number;
80
+ planned: number;
81
+ queued: number;
82
+ running: number;
83
+ /** Rules left unexecuted because they missed the cache under {@link RunOptions.cacheOnly}. */
84
+ skipped: number;
86
85
  }
87
86
  type InferenceUsageRecord = Omit<RuleInferenceUsageRecord, 'ruleId'> & {
88
87
  ruleId: string;
89
88
  };
90
- interface ProgressFilePath {
91
- index: number;
92
- path: string;
93
- planned?: number;
94
- total: number;
89
+ interface JobEndPayload extends JobStartPayload {
90
+ cache: 'hit' | 'miss';
91
+ endedAt?: number;
92
+ failure?: AlintRunFailure;
93
+ state: 'cached' | 'cancelled' | 'completed' | 'failed' | 'skipped';
95
94
  }
96
- interface ProgressPath {
97
- file: ProgressFilePath;
98
- rule: {
99
- id: string;
100
- index: number;
101
- total: number;
102
- };
95
+ interface JobQueuedPayload {
96
+ job: ProgressJob;
97
+ }
98
+ interface JobStartPayload {
99
+ job: ProgressJob;
100
+ startedAt?: number;
101
+ }
102
+ interface ProgressJob {
103
+ id: string;
104
+ index: number;
105
+ inputPath: string;
106
+ ruleId: string;
103
107
  target: {
104
- index: number;
108
+ identity: string;
105
109
  kind: ProgressTargetKind;
106
110
  name?: string;
107
- total: number;
108
111
  };
112
+ total: number;
109
113
  }
110
114
  interface ProgressReporter {
111
115
  onDiagnostic?: (payload: DiagnosticProgressPayload) => void;
112
- onFileEnd?: (payload: FileProgressPayload) => void;
113
- onFileStart?: (payload: FileProgressPayload) => void;
114
- onRuleEnd?: (payload: RuleEndPayload) => void;
115
- onRuleStart?: (payload: RuleStartPayload) => void;
116
+ onJobEnd?: (payload: JobEndPayload) => void;
117
+ onJobQueued?: (payload: JobQueuedPayload) => void;
118
+ onJobStart?: (payload: JobStartPayload) => void;
116
119
  onRunEnd?: (payload: RunEndPayload) => void;
117
120
  onRunStart?: (payload: RunStartPayload) => void;
118
- onTargetEnd?: (payload: TargetProgressPayload) => void;
119
- onTargetStart?: (payload: TargetProgressPayload) => void;
120
121
  onUsage?: (payload: UsageProgressPayload) => void;
121
122
  }
122
123
  type ProgressTargetKind = SourceTargetKind;
123
- interface RuleEndPayload {
124
- cache: 'hit' | 'miss';
125
- endedAt?: number;
126
- path: ProgressPath;
127
- startedAt?: number;
128
- /**
129
- * `skipped` only occurs under {@link RunOptions.cacheOnly}: the rule missed the cache and was
130
- * never executed, so it produced no diagnostics. `cache` is still `'miss'` in that case.
131
- */
132
- state: 'completed' | 'errored' | 'skipped';
133
- }
134
- interface RuleStartPayload {
135
- path: ProgressPath;
136
- startedAt?: number;
137
- }
138
124
  interface RunEndPayload {
139
- cached: number;
140
- completed: number;
141
125
  diagnostics: Diagnostic[];
142
126
  endedAt?: number;
143
- errored: number;
144
- planned: number;
145
- /** Rules left unexecuted because they missed the cache under {@link RunOptions.cacheOnly}. Always 0 otherwise. */
146
- skipped: number;
127
+ execution: ExecutionCounts;
147
128
  startedAt?: number;
148
129
  usage: RunUsage;
149
130
  }
150
- interface RunExecution {
151
- cached: number;
152
- completed: number;
153
- errored: number;
154
- planned: number;
155
- /** Rules left unexecuted because they missed the cache under {@link RunOptions.cacheOnly}. Always 0 otherwise. */
156
- skipped: number;
157
- }
131
+ type RunExecution = ExecutionCounts;
158
132
  type RunnerOptions = RunnerConfig;
159
133
  interface RunOptions {
160
134
  /**
161
135
  * Return only diagnostics that are already cached, without calling any model.
162
- *
163
- * Rules that miss the cache are skipped instead of executed, and the run leaves the cache
164
- * file untouched. Read {@link RunExecution.skipped} to see how many rules a full run would
165
- * still have to execute.
166
- *
167
- * Intended for callers that want to show known results for free, such as an editor
168
- * displaying diagnostics on file open.
136
+ * Rules that miss the cache are skipped, and the cache remains read-only.
169
137
  */
170
138
  cacheOnly?: boolean;
171
139
  config?: AlintConfig;
@@ -189,14 +157,11 @@ interface RunOptions {
189
157
  }
190
158
  interface RunResult {
191
159
  diagnostics: Diagnostic[];
192
- execution?: RunExecution;
160
+ execution: ExecutionCounts;
193
161
  usage: RunUsage;
194
162
  }
195
163
  interface RunStartPayload {
196
- files?: ProgressFilePath[];
197
- filesTotal: number;
198
- planned: number;
199
- rulesTotal: number;
164
+ jobsTotal: number;
200
165
  startedAt?: number;
201
166
  }
202
167
  interface RunUsage {
@@ -212,24 +177,28 @@ interface RunUsageTotals {
212
177
  records: InferenceUsageRecord[];
213
178
  totalTokens: number;
214
179
  }
215
- interface TargetProgressPayload {
216
- endedAt?: number;
217
- path: ProgressPath;
218
- startedAt?: number;
219
- }
220
180
  interface UsageProgressPayload {
221
- path?: ProgressPath;
181
+ job: ProgressJob;
222
182
  record: InferenceUsageRecord;
223
- total: RunUsage;
224
183
  }
225
184
  //#endregion
226
185
  //#region src/core/run.d.ts
186
+ declare class AlintRunCancelledError extends Error {
187
+ readonly result: RunResult;
188
+ constructor(result: RunResult, cause?: unknown);
189
+ }
190
+ /** Cancellation error carrying the partial result gathered before the abort. */
191
+ declare class AlintAbortError extends AlintRunCancelledError {
192
+ constructor(result: RunResult, options?: {
193
+ cause?: unknown;
194
+ });
195
+ }
227
196
  declare class AlintRunError extends Error {
228
- readonly failure?: AlintRunFailure;
197
+ readonly failures: AlintRunFailure[];
229
198
  readonly result: RunResult;
230
199
  constructor(message: string, result: RunResult, options?: {
231
200
  cause?: unknown;
232
- failure?: AlintRunFailure;
201
+ failures?: AlintRunFailure[];
233
202
  });
234
203
  }
235
204
  declare function runAlint(options?: RunOptions): Promise<RunResult>;
@@ -251,4 +220,4 @@ declare function buildRuleRegistry(config: Pick<EffectiveAlintConfig, 'plugins'
251
220
  //#region src/models/resolve.d.ts
252
221
  declare function resolveModel(registry: SetupConfig, options?: ResolveModelOptions): ResolvedModel;
253
222
  //#endregion
254
- export { type AlintConfig, type AlintConfigExtends, type AlintConfigInput, type AlintConfigItem, type AlintLinterOptions, AlintRunError, type AlintRunFailure, type Awaitable, type ClassTarget, type Diagnostic, type DiagnosticDescriptor, type DiagnosticLocation, type DiagnosticProgressPayload, type DirectoryTarget, type EffectiveAlintConfig, type EnabledRule, type FileProgressPayload, type FileTarget, type FunctionTarget, type IgnoreConfig, type InferenceUsageRecord, type LanguageContext, type LanguageDefinition, type LanguageRegistry, type LineRange, type ModelRequirement, type ModelSize, type PluginDefinition, type ProcessedSource, type ProcessedSourceOrigin, type ProcessorContext, type ProcessorDefinition, type ProcessorPostprocessContext, type ProgressFilePath, type ProgressPath, type ProgressReporter, type ProgressTargetKind, type ProjectTarget, type ProviderDefinition, type ProviderType, type ResolveConfigResult, type ResolveLanguageOptions, type ResolveModelOptions, type ResolvedModel, type ResolvedProvider, type RuleCacheConfig, type RuleConfigEntry, type RuleContext, type RuleDefinition, type RuleEndPayload, type RuleHandlers, type RuleInferenceUsageRecord, type RuleRegistry, type RuleSeverity, type RuleSpecializedHandlers, type RuleStartPayload, type RuleWithHandler, type RunEndPayload, type RunExecution, type RunOptions, type RunResult, type RunStartPayload, type RunUsage, type RunUsageTotals, type RunnerConfig, type RunnerStatsConfig, type SetupConfig, type SetupModelDefinition, type SourceFile, type SourceLocation, type SourcePosition, type SourceRange, type SourceRuntime, type SourceTarget, type SourceTargetKind, type SourceTargetOfKind, type SourceTargetOrigin, type SourceText, type Target, type TargetProgressPayload, type UsageProgressPayload, buildRuleRegistry, createBuiltInLanguageRegistry, createSourceFile, createSourceRuntime, defineConfig, definePlugin, defineRule, extractJsSourceTargets, hasDiscoveryFilePatterns, matchesDiscoveryFile, normalizeConfig, registerLanguage, resolveConfigForDirectory, resolveConfigForFile, resolveConfigForProject, resolveLanguage, resolveModel, runAlint, sliceLines, sliceRange };
223
+ export { AlintAbortError, type AlintConfig, type AlintConfigExtends, type AlintConfigInput, type AlintConfigItem, type AlintLinterOptions, AlintRunCancelledError, AlintRunError, type AlintRunFailure, type Awaitable, type ClassTarget, type Diagnostic, type DiagnosticDescriptor, type DiagnosticLocation, type DiagnosticProgressPayload, type DirectoryTarget, type EffectiveAlintConfig, type EnabledRule, type ExecutionCounts, type FileTarget, type FunctionTarget, type IgnoreConfig, type InferenceUsageRecord, type JobEndPayload, type JobQueuedPayload, type JobStartPayload, type LanguageContext, type LanguageDefinition, type LanguageRegistry, type LineRange, type ModelRequirement, type ModelSize, type PluginDefinition, type ProcessedSource, type ProcessedSourceOrigin, type ProcessorContext, type ProcessorDefinition, type ProcessorPostprocessContext, type ProgressJob, type ProgressReporter, type ProgressTargetKind, type ProjectTarget, type ProviderDefinition, type ProviderType, type ResolveConfigResult, type ResolveLanguageOptions, type ResolveModelOptions, type ResolvedModel, type ResolvedProvider, type RuleCacheConfig, type RuleConfigEntry, type RuleContext, type RuleDefinition, type RuleHandlers, type RuleInferenceUsageRecord, type RuleRegistry, type RuleSeverity, type RuleSpecializedHandlers, type RuleWithHandler, type RunEndPayload, type RunExecution, type RunOptions, type RunResult, type RunStartPayload, type RunUsage, type RunUsageTotals, type RunnerConfig, type RunnerStatsConfig, type SetupConfig, type SetupModelDefinition, type SourceFile, type SourceLocation, type SourcePosition, type SourceRange, type SourceRuntime, type SourceTarget, type SourceTargetKind, type SourceTargetOfKind, type SourceTargetOrigin, type SourceText, type Target, type UsageProgressPayload, buildRuleRegistry, createBuiltInLanguageRegistry, createSourceFile, createSourceRuntime, defineConfig, definePlugin, defineRule, hasDiscoveryFilePatterns, matchesDiscoveryFile, normalizeConfig, registerLanguage, resolveConfigForDirectory, resolveConfigForFile, resolveConfigForProject, resolveLanguage, resolveModel, runAlint, sliceLines, sliceRange };