@alint-js/core 0.4.0 → 0.5.0
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 +55 -1
- package/dist/agent.d.mts +1 -1
- package/dist/{define-CJ2QJPZ8.d.mts → define-CNfm3wZW.d.mts} +1 -1
- package/dist/dsl.d.mts +2 -2
- package/dist/{extract-DoHeLdG1.mjs → extract-CLXRRiJW.mjs} +4 -4
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +6 -3
- package/dist/languages-js.mjs +1 -1
- package/dist/structured-output.d.mts +1 -1
- package/dist/structured-output.mjs +16 -4
- package/dist/{types-deBCDA4_.d.mts → types-BK5CADYK.d.mts} +4 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ This package provides the core SDK and run engine APIs used by plugins, rules, l
|
|
|
10
10
|
- `runAlint`
|
|
11
11
|
- rule registry and flat config normalization
|
|
12
12
|
- source runtime helpers
|
|
13
|
-
- built-in JavaScript source extraction
|
|
13
|
+
- built-in JavaScript source extraction, with additional language support for others
|
|
14
14
|
- model resolution by size and capability
|
|
15
15
|
- diagnostics and progress payload types
|
|
16
16
|
- framework-neutral agent contracts under `@alint-js/core/agent`
|
|
@@ -105,6 +105,60 @@ description defaults to the schema's valibot `description(...)`. `toolParameters
|
|
|
105
105
|
that build their own tools or prompts. Use `ctx.agent` instead when the model needs to
|
|
106
106
|
explore with tools before answering, because a forced tool call is a single shot, not a loop.
|
|
107
107
|
|
|
108
|
+
### Languages
|
|
109
|
+
|
|
110
|
+
Core parses JavaScript and TypeScript. Everything else is registered by a plugin, so a rule says
|
|
111
|
+
which languages it can read and core decides what to hand it:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
defineRule({
|
|
115
|
+
create: () => ({ onTargetFunction: (target) => { /* ... */ } }),
|
|
116
|
+
languages: 'any',
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
| `languages` | the rule receives | a named language nothing registered |
|
|
121
|
+
| --- | --- | --- |
|
|
122
|
+
| omitted | file targets only, never functions or classes | not applicable |
|
|
123
|
+
| `'any'` | every language except `plaintext` | never fails |
|
|
124
|
+
| `['go', 'rust']` | those languages only | run fails, `alint/missing-language` |
|
|
125
|
+
| `{ ids: ['go'], skipMissing: true }` | those languages only | skipped quietly |
|
|
126
|
+
|
|
127
|
+
`'any'` excludes `plaintext` on purpose. Plain text is what a file falls back to when no language
|
|
128
|
+
claims its extension, so a rule that asked for a language would otherwise be handed unparsed text.
|
|
129
|
+
When that happens the run reports `alint/unregistered-language` once per extension — a warning by
|
|
130
|
+
default, configurable through `linterOptions.reportUnregisteredLanguages`.
|
|
131
|
+
|
|
132
|
+
Declaring a list is the stricter choice. It fails the run when the user has not installed a pack
|
|
133
|
+
that provides one of them, rather than letting the rule match nothing and look like a pass.
|
|
134
|
+
|
|
135
|
+
A plugin registers a language by describing how to turn a file into targets:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
definePlugin({
|
|
139
|
+
languages: {
|
|
140
|
+
zig: {
|
|
141
|
+
extensions: ['.zig'],
|
|
142
|
+
extract: file => [/* SourceTarget[] */],
|
|
143
|
+
name: 'zig',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Ids are the identifiers editors use — `go`, `python`, `typescript`, `plaintext`. Registering fails
|
|
150
|
+
on a duplicate name or extension, so two plugins can never claim the same language.
|
|
151
|
+
|
|
152
|
+
Put a `FunctionInfo` under `metadata.function` on each function target, and the file's call sites
|
|
153
|
+
under `metadata.calls` on the file target. Those two keys are what let a rule read any language
|
|
154
|
+
without a parser of its own.
|
|
155
|
+
|
|
156
|
+
`@alint-js/languages` provides Go, Python and Rust this way.
|
|
157
|
+
|
|
158
|
+
To parse a file the run was not asked to lint, such as when building a workspace-wide index, use
|
|
159
|
+
`ctx.src.extract(path)`. It resolves that file's own config and language, and returns nothing for a
|
|
160
|
+
file the config ignores rather than throwing.
|
|
161
|
+
|
|
108
162
|
## When to use
|
|
109
163
|
|
|
110
164
|
- You are writing an `alint` plugin or rule package.
|
package/dist/agent.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as AgentTool, I as AgentUsage, M as AgentAdapter, N as AgentRequest, P as AgentResult, b as RuleContext } from "./types-
|
|
1
|
+
import { F as AgentTool, I as AgentUsage, M as AgentAdapter, N as AgentRequest, P as AgentResult, b as RuleContext } from "./types-BK5CADYK.mjs";
|
|
2
2
|
//#region src/agent/retry.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Declares that the complete adapter invocation can be safely replayed.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as RuleOptionsSchema, i as AlintConfigItem, p as PluginDefinition, t as AlintConfig, w as RuleOptionsInput, x as RuleDefinition, y as RuleConfigEntry } from "./types-
|
|
1
|
+
import { E as RuleOptionsSchema, i as AlintConfigItem, p as PluginDefinition, t as AlintConfig, w as RuleOptionsInput, x as RuleDefinition, y as RuleConfigEntry } from "./types-BK5CADYK.mjs";
|
|
2
2
|
//#region src/dsl/define.d.ts
|
|
3
3
|
type AnyRuleDefinition = RuleDefinition<any>;
|
|
4
4
|
type ConfigItemWithPluginRules<Plugins, Rules> = Omit<AlintConfigItem, 'plugins' | 'rules'> & {
|
package/dist/dsl.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as RuleWithHandler, C as RuleInferenceUsageRecord, D as RuleRegistry, E as RuleOptionsSchema, O as RuleSeverity, S as RuleHandlers, T as RuleOptionsOutput, _ as ProjectTargetEntry, a as AlintLinterOptions, b as RuleContext, c as DiagnosticLocation, d as IgnoreConfig, f as LanguageDefinition, g as ProjectTarget, h as ProjectFileEntry, i as AlintConfigItem, j as Target, k as RuleSpecializedHandlers, 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 RuleCacheConfig, w as RuleOptionsInput, x as RuleDefinition, y as RuleConfigEntry } from "./types-
|
|
2
|
-
import { n as definePlugin, r as defineRule, t as defineConfig } from "./define-
|
|
1
|
+
import { A as RuleWithHandler, C as RuleInferenceUsageRecord, D as RuleRegistry, E as RuleOptionsSchema, O as RuleSeverity, S as RuleHandlers, T as RuleOptionsOutput, _ as ProjectTargetEntry, a as AlintLinterOptions, b as RuleContext, c as DiagnosticLocation, d as IgnoreConfig, f as LanguageDefinition, g as ProjectTarget, h as ProjectFileEntry, i as AlintConfigItem, j as Target, k as RuleSpecializedHandlers, 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 RuleCacheConfig, w as RuleOptionsInput, x as RuleDefinition, y as RuleConfigEntry } from "./types-BK5CADYK.mjs";
|
|
2
|
+
import { n as definePlugin, r as defineRule, t as defineConfig } from "./define-CNfm3wZW.mjs";
|
|
3
3
|
export { type AlintConfig, type AlintConfigExtends, type AlintConfigInput, type AlintConfigItem, type AlintLinterOptions, type Awaitable, type DiagnosticDescriptor, type DiagnosticLocation, type DirectoryTarget, type EnabledRule, type IgnoreConfig, type LanguageDefinition, type PluginDefinition, type ProcessorDefinition, type ProjectFileEntry, type ProjectTarget, type ProjectTargetEntry, type RuleCacheConfig, type RuleConfigEntry, type RuleContext, type RuleDefinition, type RuleHandlers, type RuleInferenceUsageRecord, type RuleOptionsInput, type RuleOptionsOutput, type RuleOptionsSchema, type RuleRegistry, type RuleSeverity, type RuleSpecializedHandlers, type RuleWithHandler, type Target, defineConfig, definePlugin, defineRule };
|
|
@@ -173,11 +173,11 @@ function targetIdentity(kind, name, range) {
|
|
|
173
173
|
/**
|
|
174
174
|
* Swaps a target's positional identity for its name, where that name is unique among these targets.
|
|
175
175
|
*
|
|
176
|
-
*
|
|
177
|
-
* sharing a name cannot be told apart
|
|
176
|
+
* Caches are keyed by identity, so a function that only moved should keep the identity it had. Two
|
|
177
|
+
* targets sharing a name cannot be told apart by name, so those keep the positional form.
|
|
178
178
|
*
|
|
179
|
-
* Run every function and class target through this.
|
|
180
|
-
*
|
|
179
|
+
* Run every function and class target through this. Miss it in one language and the same function
|
|
180
|
+
* gets a different identity depending on which language read it.
|
|
181
181
|
*/
|
|
182
182
|
function withStableIdentities(targets) {
|
|
183
183
|
const nameCounts = /* @__PURE__ */ new Map();
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as RuleWithHandler, B as ResolvedProvider, C as RuleInferenceUsageRecord, D as RuleRegistry, G as RunnerStatsConfig, H as ProviderDefinition, K as SetupConfig, L as ModelRequirement, O as RuleSeverity, R as ResolveModelOptions, S as RuleHandlers, U as ProviderType, V as ModelSize, W as RunnerConfig, _ as ProjectTargetEntry, a as AlintLinterOptions, b as RuleContext, c as DiagnosticLocation, d as IgnoreConfig, f as LanguageDefinition, g as ProjectTarget, h as ProjectFileEntry, i as AlintConfigItem, j as Target, k as RuleSpecializedHandlers, l as DirectoryTarget, m as ProcessorDefinition, n as AlintConfigExtends, o as Awaitable, p as PluginDefinition, q as SetupModelDefinition, r as AlintConfigInput, s as DiagnosticDescriptor, t as AlintConfig, u as EnabledRule, v as RuleCacheConfig, x as RuleDefinition, y as RuleConfigEntry, z as ResolvedModel } from "./types-
|
|
1
|
+
import { A as RuleWithHandler, B as ResolvedProvider, C as RuleInferenceUsageRecord, D as RuleRegistry, G as RunnerStatsConfig, H as ProviderDefinition, K as SetupConfig, L as ModelRequirement, O as RuleSeverity, R as ResolveModelOptions, S as RuleHandlers, U as ProviderType, V as ModelSize, W as RunnerConfig, _ as ProjectTargetEntry, a as AlintLinterOptions, b as RuleContext, c as DiagnosticLocation, d as IgnoreConfig, f as LanguageDefinition, g as ProjectTarget, h as ProjectFileEntry, i as AlintConfigItem, j as Target, k as RuleSpecializedHandlers, l as DirectoryTarget, m as ProcessorDefinition, n as AlintConfigExtends, o as Awaitable, p as PluginDefinition, q as SetupModelDefinition, r as AlintConfigInput, s as DiagnosticDescriptor, t as AlintConfig, u as EnabledRule, v as RuleCacheConfig, x as RuleDefinition, y as RuleConfigEntry, z as ResolvedModel } from "./types-BK5CADYK.mjs";
|
|
2
2
|
import { C as SourceTarget, D as SourceTargetOrigin, E as SourceTargetOfKind, O as SourceText, S as SourceRuntime, T as SourceTargetMetadata, _ as SourceLocation, a as FunctionInfo, b as SourcePosition, c as LineRange, d as ProcessedSource, f as ProcessedSourceOrigin, g as SourceFile, h as SourceExtractOptions, i as FileTarget, l as PlannedSourceTarget, m as ProcessorPostprocessContext, n as CallSite, o as FunctionTarget, p as ProcessorContext, r as ClassTarget, s as LanguageContext, t as BaseSourceFile, u as PlannedSourceTargetOfKind, v as SourceMetadataObject, w as SourceTargetKind, x as SourceRange, y as SourceMetadataValue } from "./types-DM4idR4w.mjs";
|
|
3
|
-
import { n as definePlugin, r as defineRule, t as defineConfig } from "./define-
|
|
3
|
+
import { n as definePlugin, r as defineRule, t as defineConfig } from "./define-CNfm3wZW.mjs";
|
|
4
4
|
//#region src/config/config-array.d.ts
|
|
5
5
|
interface EffectiveAlintConfig {
|
|
6
6
|
agent?: AlintConfigItem['agent'];
|
|
@@ -286,11 +286,11 @@ declare function targetIdentity(kind: SourceTargetKind, name: string | undefined
|
|
|
286
286
|
/**
|
|
287
287
|
* Swaps a target's positional identity for its name, where that name is unique among these targets.
|
|
288
288
|
*
|
|
289
|
-
*
|
|
290
|
-
* sharing a name cannot be told apart
|
|
289
|
+
* Caches are keyed by identity, so a function that only moved should keep the identity it had. Two
|
|
290
|
+
* targets sharing a name cannot be told apart by name, so those keep the positional form.
|
|
291
291
|
*
|
|
292
|
-
* Run every function and class target through this.
|
|
293
|
-
*
|
|
292
|
+
* Run every function and class target through this. Miss it in one language and the same function
|
|
293
|
+
* gets a different identity depending on which language read it.
|
|
294
294
|
*/
|
|
295
295
|
declare function withStableIdentities(targets: readonly SourceTarget[]): SourceTarget[];
|
|
296
296
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { o as withAgentRetry, t as combineAbortSignals } from "./agent-B6GG68NX.mjs";
|
|
2
2
|
import { n as definePlugin, r as defineRule, t as defineConfig } from "./define-Da342Fcx.mjs";
|
|
3
|
-
import { a as createSourceFile, c as sliceRange, d as stableHash, i as SourceChangedError, l as withLanguage, n as targetIdentity, o as createSourceRuntime, r as withStableIdentities, s as sliceLines, t as extractJsSourceTargets, u as createStableHasher } from "./extract-
|
|
3
|
+
import { a as createSourceFile, c as sliceRange, d as stableHash, i as SourceChangedError, l as withLanguage, n as targetIdentity, o as createSourceRuntime, r as withStableIdentities, s as sliceLines, t as extractJsSourceTargets, u as createStableHasher } from "./extract-CLXRRiJW.mjs";
|
|
4
4
|
import { minimatch } from "minimatch";
|
|
5
5
|
import { basename, extname, isAbsolute, relative, resolve } from "pathe";
|
|
6
6
|
import { access, mkdir, open, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
@@ -299,7 +299,10 @@ function resolveLanguage(file, registry, options) {
|
|
|
299
299
|
function resolveLanguageForPath(filePath, registry, options) {
|
|
300
300
|
const languageName = options.language ?? options.processedLanguage ?? registry.byExtension.get(extname$1(filePath)) ?? "plaintext";
|
|
301
301
|
const language = registry.languages.get(languageName);
|
|
302
|
-
if (!language)
|
|
302
|
+
if (!language) {
|
|
303
|
+
const registered = [...registry.languages.keys()].sort().join(", ");
|
|
304
|
+
throw new Error(`Unknown language "${languageName}". Languages come from plugins, and these are registered: ${registered}.`);
|
|
305
|
+
}
|
|
303
306
|
return language;
|
|
304
307
|
}
|
|
305
308
|
//#endregion
|
|
@@ -602,7 +605,7 @@ function recordMissingLanguages(into, rules, registry, path) {
|
|
|
602
605
|
}
|
|
603
606
|
//#endregion
|
|
604
607
|
//#region package.json
|
|
605
|
-
var version = "0.
|
|
608
|
+
var version = "0.5.0";
|
|
606
609
|
//#endregion
|
|
607
610
|
//#region src/core/cache/types.ts
|
|
608
611
|
const CACHE_MAGIC = "ALINT_CACHE";
|
package/dist/languages-js.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as extractJsSourceTargets } from "./extract-
|
|
1
|
+
import { t as extractJsSourceTargets } from "./extract-CLXRRiJW.mjs";
|
|
2
2
|
export { extractJsSourceTargets };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as RuleContext, z as ResolvedModel } from "./types-
|
|
1
|
+
import { b as RuleContext, z as ResolvedModel } from "./types-BK5CADYK.mjs";
|
|
2
2
|
import { GenericSchema, InferOutput } from "valibot";
|
|
3
3
|
import { JsonSchema } from "@valibot/to-json-schema";
|
|
4
4
|
import { Message } from "@xsai/shared-chat";
|
|
@@ -152,20 +152,32 @@ function parseStructuredResponse(schema, toolName, response) {
|
|
|
152
152
|
retriable: true
|
|
153
153
|
};
|
|
154
154
|
const toolResults = response.toolResults.filter((result) => result.toolName === toolName);
|
|
155
|
-
|
|
155
|
+
const toolCalls = response.toolCalls.filter((call) => call.toolName === toolName);
|
|
156
|
+
const matches = toolResults.length + toolCalls.length;
|
|
157
|
+
if (matches === 0) return {
|
|
156
158
|
error: `Missing ${toolName} tool result; finishReason=${response.finishReason}`,
|
|
157
159
|
ok: false,
|
|
158
160
|
retriable: true
|
|
159
161
|
};
|
|
160
|
-
if (
|
|
161
|
-
error: `Expected one ${toolName} tool result, received ${
|
|
162
|
+
if (matches > 1) return {
|
|
163
|
+
error: `Expected one ${toolName} tool result, received ${matches}`,
|
|
162
164
|
ok: false,
|
|
163
165
|
retriable: true
|
|
164
166
|
};
|
|
167
|
+
let value;
|
|
168
|
+
try {
|
|
169
|
+
value = toolResults[0] !== void 0 ? toolResults[0].result : JSON.parse(toolCalls[0].args);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
return {
|
|
172
|
+
error: `Tool call failed before validation: ${errorMessageFrom(error) ?? String(error)}`,
|
|
173
|
+
ok: false,
|
|
174
|
+
retriable: true
|
|
175
|
+
};
|
|
176
|
+
}
|
|
165
177
|
try {
|
|
166
178
|
return {
|
|
167
179
|
ok: true,
|
|
168
|
-
value: parse(schema,
|
|
180
|
+
value: parse(schema, value)
|
|
169
181
|
};
|
|
170
182
|
} catch (error) {
|
|
171
183
|
return {
|
|
@@ -263,8 +263,10 @@ interface RuleInferenceUsageRecord {
|
|
|
263
263
|
totalTokens?: number;
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
266
|
-
* - `'any'` — every
|
|
267
|
-
*
|
|
266
|
+
* - `'any'` — every language except `plaintext`, and never a failure. Plain text is what a file
|
|
267
|
+
* falls back to when no language claims it, so a rule asking for any language is asking for a
|
|
268
|
+
* real one. Rules that work from `FunctionInfo` alone want this: install another language pack
|
|
269
|
+
* and they cover it too, unchanged.
|
|
268
270
|
* - A list of language ids — `LanguageDefinition.name` values such as `go` or `typescript`, never
|
|
269
271
|
* file extensions. The rule handles exactly these. Files of other languages are skipped
|
|
270
272
|
* rather than failed, so one plugin can carry rules for several languages behind one `files:`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alint-js/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.mts",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@moeru/std": "^0.1.0-beta.20",
|
|
33
33
|
"@valibot/to-json-schema": "^1.7.1",
|
|
34
|
-
"@xsai/generate-text": "^0.5.0-beta.
|
|
35
|
-
"@xsai/shared-chat": "^0.5.0-beta.
|
|
36
|
-
"@xsai/stream-text": "^0.5.0-beta.
|
|
37
|
-
"@xsai/tool": "^0.5.0-beta.
|
|
34
|
+
"@xsai/generate-text": "^0.5.0-beta.8",
|
|
35
|
+
"@xsai/shared-chat": "^0.5.0-beta.8",
|
|
36
|
+
"@xsai/stream-text": "^0.5.0-beta.8",
|
|
37
|
+
"@xsai/tool": "^0.5.0-beta.8",
|
|
38
38
|
"es-toolkit": "^1.50.0",
|
|
39
39
|
"minimatch": "^10.2.6",
|
|
40
40
|
"oxc-parser": "^0.142.0",
|