@alint-js/config 0.3.1 → 0.4.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/dist/index.d.mts +56 -15
- package/dist/index.mjs +200 -137
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AlintConfig, AlintConfig as AlintConfig$1, AlintConfigItem, ModelSize, PluginDefinition, ProviderDefinition,
|
|
1
|
+
import { AlintConfig, AlintConfig as AlintConfig$1, AlintConfigItem, ModelSize, PluginDefinition, ProviderDefinition, ProviderType, ProviderType as ProviderType$1, RunnerConfig, RunnerConfig as RunnerConfig$1, RunnerStatsConfig, SetupConfig as SetupConfig$1, SetupModelDefinition, SetupModelDefinition as SetupModelDefinition$1 } from "@alint-js/core";
|
|
2
2
|
//#region src/plugins/spec.d.ts
|
|
3
3
|
interface DirectoryPluginSpecifier {
|
|
4
4
|
directory: string;
|
|
@@ -232,25 +232,66 @@ declare function parsePluginLockFile(value: unknown, options: {
|
|
|
232
232
|
}): ParsedPluginLockFile;
|
|
233
233
|
declare function writePluginLockFile(cwd: string, lockFile: PluginLockFile): Promise<void>;
|
|
234
234
|
//#endregion
|
|
235
|
+
//#region src/setup/types.d.ts
|
|
236
|
+
interface AcpModelConfig extends SetupModelDefinition$1 {
|
|
237
|
+
args?: string[];
|
|
238
|
+
command: string;
|
|
239
|
+
cwd?: string;
|
|
240
|
+
driver: 'acp';
|
|
241
|
+
env?: Record<string, string>;
|
|
242
|
+
}
|
|
243
|
+
type ModelConfig = AcpModelConfig | SetupModelDefinition$1;
|
|
244
|
+
/** Raw setup-file provider. CLI model drivers are materialized before core receives it. */
|
|
245
|
+
interface ProviderConfig {
|
|
246
|
+
endpoint?: string;
|
|
247
|
+
headers?: Record<string, string>;
|
|
248
|
+
id: string;
|
|
249
|
+
models: ModelConfig[];
|
|
250
|
+
type?: ProviderType$1;
|
|
251
|
+
}
|
|
252
|
+
interface SetupConfig {
|
|
253
|
+
providers: ProviderConfig[];
|
|
254
|
+
runner?: RunnerConfig$1;
|
|
255
|
+
version: 1;
|
|
256
|
+
}
|
|
257
|
+
declare function isAcpModel(model: ModelConfig): model is AcpModelConfig;
|
|
258
|
+
declare function modelFromAcpModel(model: AcpModelConfig): SetupModelDefinition$1;
|
|
259
|
+
//#endregion
|
|
235
260
|
//#region src/setup/load.d.ts
|
|
236
|
-
declare const emptySetupConfig: SetupConfig
|
|
237
|
-
declare function loadSetupConfig(filePath: string): Promise<SetupConfig
|
|
238
|
-
declare function mergeSetupConfigs(...configs: SetupConfig
|
|
261
|
+
declare const emptySetupConfig: SetupConfig;
|
|
262
|
+
declare function loadSetupConfig(filePath: string): Promise<SetupConfig>;
|
|
263
|
+
declare function mergeSetupConfigs(...configs: SetupConfig[]): SetupConfig;
|
|
239
264
|
//#endregion
|
|
240
265
|
//#region src/setup/mutate.d.ts
|
|
241
|
-
declare function addProviderModels(config: SetupConfig
|
|
242
|
-
declare function pruneProviderModels(config: SetupConfig
|
|
243
|
-
declare function removeProviderModels(config: SetupConfig
|
|
244
|
-
declare function replaceSetupProvider(config: SetupConfig
|
|
245
|
-
declare function setProviderEndpoint(config: SetupConfig
|
|
246
|
-
declare function setProviderHeader(config: SetupConfig
|
|
247
|
-
declare function unsetProviderHeader(config: SetupConfig
|
|
266
|
+
declare function addProviderModels(config: SetupConfig, providerId: string, modelIds: readonly string[]): SetupConfig;
|
|
267
|
+
declare function pruneProviderModels(config: SetupConfig, providerId: string, remoteModelIds: ReadonlySet<string>): SetupConfig;
|
|
268
|
+
declare function removeProviderModels(config: SetupConfig, providerId: string, modelIds: ReadonlySet<string>): SetupConfig;
|
|
269
|
+
declare function replaceSetupProvider(config: SetupConfig, replacement: ProviderConfig): SetupConfig;
|
|
270
|
+
declare function setProviderEndpoint(config: SetupConfig, providerId: string, endpoint: string): SetupConfig;
|
|
271
|
+
declare function setProviderHeader(config: SetupConfig, providerId: string, name: string, value: string): SetupConfig;
|
|
272
|
+
declare function unsetProviderHeader(config: SetupConfig, providerId: string, name: string): SetupConfig;
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/setup/normalize.d.ts
|
|
275
|
+
interface AcpProviderConfig {
|
|
276
|
+
id: string;
|
|
277
|
+
models: AcpModelConfig[];
|
|
278
|
+
}
|
|
279
|
+
interface ModelAdapterProvider {
|
|
280
|
+
endpoint: string;
|
|
281
|
+
headers?: Record<string, string>;
|
|
282
|
+
type: ProviderDefinition['type'];
|
|
283
|
+
}
|
|
284
|
+
interface SetupModelAdapters {
|
|
285
|
+
acp: (provider: AcpProviderConfig) => Promise<ModelAdapterProvider>;
|
|
286
|
+
}
|
|
287
|
+
/** Normalizes setup-file providers while delegating only model-driven transports. */
|
|
288
|
+
declare function normalizeSetupConfig(config: SetupConfig, adapters: SetupModelAdapters): Promise<SetupConfig$1>;
|
|
248
289
|
//#endregion
|
|
249
290
|
//#region src/setup/toml.d.ts
|
|
250
|
-
declare function parseSetupConfigToml(toml: string): SetupConfig
|
|
251
|
-
declare function stringifySetupConfigToml(config: SetupConfig
|
|
291
|
+
declare function parseSetupConfigToml(toml: string): SetupConfig;
|
|
292
|
+
declare function stringifySetupConfigToml(config: SetupConfig): string;
|
|
252
293
|
//#endregion
|
|
253
294
|
//#region src/setup/write.d.ts
|
|
254
|
-
declare function writeSetupConfig(filePath: string, config: SetupConfig
|
|
295
|
+
declare function writeSetupConfig(filePath: string, config: SetupConfig): Promise<void>;
|
|
255
296
|
//#endregion
|
|
256
|
-
export { type AlintConfig, BuiltInAgentName, CreateDeclarativePluginOptions, CreateReportScopeOptions, DeclarativeFinding, DeclarativeFindingResponse, DeclarativeRuleDefinition, type DirectoryPluginLockEntry, type GlobalSetupConfigPathOptions, LoadDeclarativeRulesOptions, type ModelSize, type ParseStaticConfigOptions, type ParsedDirectoryPluginLockEntry, type ParsedPluginLockEntry, type ParsedPluginLockFile, type ParsedPluginSpecifier, type ParsedRegistryPluginLockEntry, type ParsedStaticConfig, type ParsedStaticConfigGroup, type PluginLockEntry, type PluginLockFile, type ProviderDefinition, type ProviderType, type RegistryPluginLockEntry, ReportScope, type RunnerConfig, type RunnerStatsConfig, type SetupConfig, type SetupModelDefinition, type StaticConfigInput, type StaticConfigItem, type StaticPluginInstallOptions, type StaticPluginInstallResult, type StaticPluginReference, type StaticPluginResolver, type ToAlintConfigOptions, addProviderModels, builtInAgentNames, createDeclarativePlugin, createEmptyPluginLockFile, createReportScope, declarativeFindingResponseSchema, declarativeFindingSchema, declarativeRuleFilePattern, emptySetupConfig, getGlobalSetupConfigPath, getProjectPluginLockPath, getProjectPluginStorePath, getProjectSetupConfigPath, getStatsDir, hasDeclarativeRuleFiles, ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated, installStaticPlugins, isBuiltInAgentName, listMissing, listUnresolved, loadAlintConfig, loadDeclarativeRules, loadPluginLockFile, loadSetupConfig, loadStaticConfig, mergeSetupConfigs, parsePluginLockFile, parsePluginSpecifier, parseSetupConfigToml, parseStaticConfig, pruneProviderModels, removeProviderModels, replaceSetupProvider, setProviderEndpoint, setProviderHeader, stringifySetupConfigToml, toAlintConfig, unsetProviderHeader, writePluginLockFile, writeSetupConfig };
|
|
297
|
+
export { type AcpModelConfig, type AcpProviderConfig, type AlintConfig, BuiltInAgentName, CreateDeclarativePluginOptions, CreateReportScopeOptions, DeclarativeFinding, DeclarativeFindingResponse, DeclarativeRuleDefinition, type DirectoryPluginLockEntry, type GlobalSetupConfigPathOptions, LoadDeclarativeRulesOptions, type ModelAdapterProvider, type ModelConfig, type ModelSize, type ParseStaticConfigOptions, type ParsedDirectoryPluginLockEntry, type ParsedPluginLockEntry, type ParsedPluginLockFile, type ParsedPluginSpecifier, type ParsedRegistryPluginLockEntry, type ParsedStaticConfig, type ParsedStaticConfigGroup, type PluginLockEntry, type PluginLockFile, type ProviderConfig, type ProviderConfig as ProviderDefinition, type ProviderType, type RegistryPluginLockEntry, ReportScope, type RunnerConfig, type RunnerStatsConfig, type SetupConfig, type SetupModelAdapters, type SetupModelDefinition, type StaticConfigInput, type StaticConfigItem, type StaticPluginInstallOptions, type StaticPluginInstallResult, type StaticPluginReference, type StaticPluginResolver, type ToAlintConfigOptions, addProviderModels, builtInAgentNames, createDeclarativePlugin, createEmptyPluginLockFile, createReportScope, declarativeFindingResponseSchema, declarativeFindingSchema, declarativeRuleFilePattern, emptySetupConfig, getGlobalSetupConfigPath, getProjectPluginLockPath, getProjectPluginStorePath, getProjectSetupConfigPath, getStatsDir, hasDeclarativeRuleFiles, ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated, installStaticPlugins, isAcpModel, isBuiltInAgentName, listMissing, listUnresolved, loadAlintConfig, loadDeclarativeRules, loadPluginLockFile, loadSetupConfig, loadStaticConfig, mergeSetupConfigs, modelFromAcpModel, normalizeSetupConfig, parsePluginLockFile, parsePluginSpecifier, parseSetupConfigToml, parseStaticConfig, pruneProviderModels, removeProviderModels, replaceSetupProvider, setProviderEndpoint, setProviderHeader, stringifySetupConfigToml, toAlintConfig, unsetProviderHeader, writePluginLockFile, writeSetupConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { loadConfig } from "c12";
|
|
|
3
3
|
import { createJiti } from "jiti/static";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
5
|
import { access, mkdir, open, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
6
|
-
import { array, boolean, check, description, literal, looseObject, number, object, optional, parse, picklist, pipe, record, strictObject, string, tupleWithRest, union, unknown, variant } from "valibot";
|
|
6
|
+
import { array, boolean, check, description, finite, integer, literal, looseObject, minValue, nonEmpty, number, object, optional, parse, picklist, pipe, record, strictObject, string, transform, tupleWithRest, undefined_, union, unknown, variant } from "valibot";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { dirname as dirname$1, extname, join as join$1, normalize as normalize$1 } from "pathe";
|
|
@@ -23,6 +23,7 @@ import tar from "tar-stream";
|
|
|
23
23
|
import { ofetch } from "ofetch";
|
|
24
24
|
import { pathToFileURL } from "node:url";
|
|
25
25
|
import { isPlainObject } from "es-toolkit/compat";
|
|
26
|
+
import { merge } from "@moeru/std/merge";
|
|
26
27
|
import { parse as parse$1, stringify } from "smol-toml";
|
|
27
28
|
//#region src/paths.ts
|
|
28
29
|
function getGlobalSetupConfigPath(env = process.env, options = {}) {
|
|
@@ -156,12 +157,12 @@ async function findDeclarativeRuleFiles(root) {
|
|
|
156
157
|
await collectDeclarativeRuleFiles(root, files);
|
|
157
158
|
return files.sort((left, right) => left.localeCompare(right));
|
|
158
159
|
}
|
|
159
|
-
function isPlainObject$
|
|
160
|
+
function isPlainObject$2(value) {
|
|
160
161
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
161
162
|
}
|
|
162
163
|
async function loadDeclarativeRuleFile(filePath) {
|
|
163
164
|
const input = await loadDeclarativeRuleFileContent(filePath);
|
|
164
|
-
if (!isPlainObject$
|
|
165
|
+
if (!isPlainObject$2(input)) throw new Error(`Declarative rule file ${filePath} must contain an object.`);
|
|
165
166
|
const parsed = parseDeclarativeRuleFileInput(input, filePath);
|
|
166
167
|
return {
|
|
167
168
|
builtInAgent: parsed.builtInAgent,
|
|
@@ -1086,7 +1087,7 @@ async function toAlintConfig(config, options) {
|
|
|
1086
1087
|
const pluginCache = /* @__PURE__ */ new Map();
|
|
1087
1088
|
return Promise.all(config.groups.map((group) => resolveStaticPlugins(group, options, pluginCache)));
|
|
1088
1089
|
}
|
|
1089
|
-
function isPlainObject$
|
|
1090
|
+
function isPlainObject$1(value) {
|
|
1090
1091
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1091
1092
|
}
|
|
1092
1093
|
function isTomlConfig(configFile) {
|
|
@@ -1104,14 +1105,14 @@ function parseStaticConfigItems(value) {
|
|
|
1104
1105
|
return value.map(parseStaticConfigItem);
|
|
1105
1106
|
}
|
|
1106
1107
|
function readConfigGroup(value) {
|
|
1107
|
-
if (!isPlainObject$
|
|
1108
|
+
if (!isPlainObject$1(value)) return;
|
|
1108
1109
|
const wrapper = value;
|
|
1109
1110
|
if (wrapper.config === void 0) return;
|
|
1110
|
-
if (!isPlainObject$
|
|
1111
|
+
if (!isPlainObject$1(wrapper.config) || !Array.isArray(wrapper.config.group)) throw new TypeError("Static config field \"config.group\" must be an array.");
|
|
1111
1112
|
return wrapper.config.group;
|
|
1112
1113
|
}
|
|
1113
1114
|
function readStaticPluginReferences(item, pluginsByAlias, options) {
|
|
1114
|
-
if (!isPlainObject$
|
|
1115
|
+
if (!isPlainObject$1(item.plugins)) return [];
|
|
1115
1116
|
const references = [];
|
|
1116
1117
|
for (const [alias, plugin] of Object.entries(item.plugins)) {
|
|
1117
1118
|
if (typeof plugin !== "string") continue;
|
|
@@ -1298,22 +1299,90 @@ async function installStaticPlugins(options) {
|
|
|
1298
1299
|
};
|
|
1299
1300
|
}
|
|
1300
1301
|
//#endregion
|
|
1302
|
+
//#region src/setup/types.ts
|
|
1303
|
+
function isAcpModel(model) {
|
|
1304
|
+
return "driver" in model && model.driver === "acp";
|
|
1305
|
+
}
|
|
1306
|
+
function modelFromAcpModel(model) {
|
|
1307
|
+
const { args: _, command: _command, cwd: _cwd, driver: _driver, env: _env, ...definition } = model;
|
|
1308
|
+
return definition;
|
|
1309
|
+
}
|
|
1310
|
+
//#endregion
|
|
1301
1311
|
//#region src/setup/toml.ts
|
|
1302
|
-
const
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1312
|
+
const modelEntries = {
|
|
1313
|
+
aliases: optional(array(string())),
|
|
1314
|
+
capabilities: optional(array(string())),
|
|
1315
|
+
context_window: optional(number()),
|
|
1316
|
+
default_params: optional(record(string(), unknown())),
|
|
1317
|
+
driver: optional(undefined_()),
|
|
1318
|
+
id: pipe(string(), nonEmpty("Model id must be a non-empty string.")),
|
|
1319
|
+
name: optional(string()),
|
|
1320
|
+
size: optional(picklist([
|
|
1321
|
+
"large",
|
|
1322
|
+
"medium",
|
|
1323
|
+
"small"
|
|
1324
|
+
]))
|
|
1325
|
+
};
|
|
1326
|
+
const providerModelSchema = object(modelEntries);
|
|
1327
|
+
const acpModelSchema = object({
|
|
1328
|
+
...modelEntries,
|
|
1329
|
+
args: optional(array(string())),
|
|
1330
|
+
command: pipe(string(), nonEmpty("ACP model command must be a non-empty string.")),
|
|
1331
|
+
cwd: optional(pipe(string(), nonEmpty("ACP model cwd must be a non-empty string."))),
|
|
1332
|
+
driver: literal("acp"),
|
|
1333
|
+
env: optional(record(string(), string()))
|
|
1334
|
+
});
|
|
1335
|
+
const modelSchema = pipe(variant("driver", [acpModelSchema, providerModelSchema]), transform(({ context_window: contextWindow, default_params: defaultParams, ...model }) => ({
|
|
1336
|
+
...model,
|
|
1337
|
+
...contextWindow === void 0 ? {} : { contextWindow },
|
|
1338
|
+
...defaultParams === void 0 ? {} : { defaultParams }
|
|
1339
|
+
})));
|
|
1340
|
+
const providerSchema = pipe(object({
|
|
1341
|
+
endpoint: optional(pipe(string(), nonEmpty("Provider endpoint must be a non-empty string."))),
|
|
1342
|
+
headers: optional(record(string(), string())),
|
|
1343
|
+
id: pipe(string(), nonEmpty("Provider id must be a non-empty string.")),
|
|
1344
|
+
models: array(modelSchema),
|
|
1345
|
+
type: optional(literal("openai-compatible"))
|
|
1346
|
+
}), check((provider) => provider.models.every(isAcpModel) || provider.type === "openai-compatible", (issue) => `Invalid provider "${issue.input.id}": type is required for models without a driver.`), check((provider) => provider.models.every(isAcpModel) || provider.endpoint !== void 0, (issue) => `Invalid provider "${issue.input.id}": endpoint is required for models without a driver.`));
|
|
1347
|
+
const runnerCacheSchema = union([boolean(), object({
|
|
1348
|
+
enabled: optional(boolean()),
|
|
1349
|
+
location: optional(pipe(string("Invalid runner cache location: must be a string."), nonEmpty("Invalid runner cache location: must be a non-empty string.")))
|
|
1350
|
+
})]);
|
|
1351
|
+
const positiveIntegerSchemas = {
|
|
1352
|
+
retentionMonths: pipe(number("Invalid runner stats retention_months: must be a positive integer."), integer("Invalid runner stats retention_months: must be a positive integer."), minValue(1, "Invalid runner stats retention_months: must be a positive integer.")),
|
|
1353
|
+
ruleConcurrency: pipe(number("Invalid runner rule_concurrency: must be a positive integer."), integer("Invalid runner rule_concurrency: must be a positive integer."), minValue(1, "Invalid runner rule_concurrency: must be a positive integer.")),
|
|
1354
|
+
timeoutMs: pipe(number("Invalid runner timeout_ms: must be a positive integer."), integer("Invalid runner timeout_ms: must be a positive integer."), minValue(1, "Invalid runner timeout_ms: must be a positive integer."))
|
|
1355
|
+
};
|
|
1356
|
+
const runnerStatsSchema = union([boolean(), pipe(object({
|
|
1357
|
+
enabled: optional(boolean()),
|
|
1358
|
+
location: optional(pipe(string("Invalid runner stats location: must be a string."), nonEmpty("Invalid runner stats location: must be a non-empty string."))),
|
|
1359
|
+
retention_months: optional(positiveIntegerSchemas.retentionMonths)
|
|
1360
|
+
}), transform(({ retention_months: retentionMonths, ...stats }) => ({
|
|
1361
|
+
...stats,
|
|
1362
|
+
...retentionMonths === void 0 ? {} : { retentionMonths }
|
|
1363
|
+
})))]);
|
|
1364
|
+
const runnerSchema = pipe(object({
|
|
1365
|
+
agent_retries: optional(pipe(number("Invalid runner agent_retries: must be a finite number."), finite("Invalid runner agent_retries: must be a finite number."))),
|
|
1366
|
+
cache: optional(runnerCacheSchema),
|
|
1367
|
+
rule_concurrency: optional(positiveIntegerSchemas.ruleConcurrency),
|
|
1368
|
+
stats: optional(runnerStatsSchema),
|
|
1369
|
+
timeout_ms: optional(positiveIntegerSchemas.timeoutMs)
|
|
1370
|
+
}), transform(({ agent_retries: agentRetries, rule_concurrency: ruleConcurrency, timeout_ms: timeoutMs, ...runner }) => ({
|
|
1371
|
+
...runner,
|
|
1372
|
+
...agentRetries === void 0 ? {} : { agentRetries },
|
|
1373
|
+
...ruleConcurrency === void 0 ? {} : { ruleConcurrency },
|
|
1374
|
+
...timeoutMs === void 0 ? {} : { timeoutMs }
|
|
1375
|
+
})));
|
|
1376
|
+
const setupConfigSchema = pipe(object({
|
|
1377
|
+
providers: optional(array(providerSchema), []),
|
|
1378
|
+
runner: optional(runnerSchema),
|
|
1379
|
+
version: literal(1, "Invalid setup config: version must be 1.")
|
|
1380
|
+
}), transform(({ runner, ...config }) => ({
|
|
1381
|
+
...config,
|
|
1382
|
+
...runner === void 0 ? {} : { runner }
|
|
1383
|
+
})));
|
|
1307
1384
|
function parseSetupConfigToml(toml) {
|
|
1308
|
-
|
|
1309
|
-
if (rawConfig.version !== 1) throw new Error("Invalid setup config: version must be 1.");
|
|
1310
|
-
if (!Array.isArray(rawConfig.providers)) throw new TypeError("Invalid setup config: providers must be an array.");
|
|
1311
|
-
const parsedConfig = {
|
|
1312
|
-
providers: rawConfig.providers.map((provider) => parseProvider(provider)),
|
|
1313
|
-
version: 1
|
|
1314
|
-
};
|
|
1315
|
-
if (rawConfig.runner !== void 0) parsedConfig.runner = parseRunner(rawConfig.runner);
|
|
1316
|
-
return parsedConfig;
|
|
1385
|
+
return parse(setupConfigSchema, parse$1(toml));
|
|
1317
1386
|
}
|
|
1318
1387
|
function stringifySetupConfigToml(config) {
|
|
1319
1388
|
const stringifiableConfig = {
|
|
@@ -1323,103 +1392,15 @@ function stringifySetupConfigToml(config) {
|
|
|
1323
1392
|
if (config.runner !== void 0) stringifiableConfig.runner = toTomlRunner(config.runner);
|
|
1324
1393
|
return stringify(stringifiableConfig);
|
|
1325
1394
|
}
|
|
1326
|
-
function
|
|
1327
|
-
return
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
const parsedModel = { id };
|
|
1335
|
-
if (model.name !== void 0) parsedModel.name = readString(model.name, `model "${id}" name`);
|
|
1336
|
-
if (model.aliases !== void 0) parsedModel.aliases = readStringArray(model.aliases, `model "${id}" aliases`);
|
|
1337
|
-
if (model.capabilities !== void 0) parsedModel.capabilities = readStringArray(model.capabilities, `model "${id}" capabilities`);
|
|
1338
|
-
if (model.size !== void 0) {
|
|
1339
|
-
if (!isModelSize(model.size)) throw new Error(`Invalid model "${id}": size must be "small", "medium", or "large".`);
|
|
1340
|
-
parsedModel.size = model.size;
|
|
1341
|
-
}
|
|
1342
|
-
if (model.context_window !== void 0) parsedModel.contextWindow = readFiniteNumber(model.context_window, `model "${id}" context_window`);
|
|
1343
|
-
if (model.default_params !== void 0) parsedModel.defaultParams = readRecord(model.default_params, `model "${id}" default_params`);
|
|
1344
|
-
return parsedModel;
|
|
1345
|
-
}
|
|
1346
|
-
function parsePositiveInteger(value, label) {
|
|
1347
|
-
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) throw new TypeError(`Invalid ${label}: must be a positive integer.`);
|
|
1348
|
-
return value;
|
|
1349
|
-
}
|
|
1350
|
-
function parseProvider(provider) {
|
|
1351
|
-
const id = readNonEmptyString(provider.id, "provider id");
|
|
1352
|
-
if (provider.type !== "openai-compatible") throw new Error(`Invalid provider "${id}": type must be "openai-compatible".`);
|
|
1353
|
-
const endpoint = readNonEmptyString(provider.endpoint, `provider "${id}" endpoint`);
|
|
1354
|
-
if (!Array.isArray(provider.models)) throw new TypeError(`Invalid provider "${id}": models must be an array.`);
|
|
1355
|
-
const parsedProvider = {
|
|
1356
|
-
endpoint,
|
|
1357
|
-
id,
|
|
1358
|
-
models: provider.models.map((model) => parseModel(id, model)),
|
|
1359
|
-
type: provider.type
|
|
1395
|
+
function toTomlAcpModel(model) {
|
|
1396
|
+
return {
|
|
1397
|
+
...toTomlModel(model),
|
|
1398
|
+
args: model.args,
|
|
1399
|
+
command: model.command,
|
|
1400
|
+
cwd: model.cwd,
|
|
1401
|
+
driver: "acp",
|
|
1402
|
+
env: model.env
|
|
1360
1403
|
};
|
|
1361
|
-
if (provider.headers !== void 0) parsedProvider.headers = readStringMap(provider.headers, `provider "${id}" headers`);
|
|
1362
|
-
return parsedProvider;
|
|
1363
|
-
}
|
|
1364
|
-
function parseRunner(runner) {
|
|
1365
|
-
const parsedRunner = {};
|
|
1366
|
-
if (runner.agent_retries !== void 0) parsedRunner.agentRetries = readFiniteNumber(runner.agent_retries, "runner agent_retries");
|
|
1367
|
-
if (runner.cache !== void 0) parsedRunner.cache = parseRunnerCache(runner.cache);
|
|
1368
|
-
if (runner.rule_concurrency !== void 0) parsedRunner.ruleConcurrency = parsePositiveInteger(runner.rule_concurrency, "runner rule_concurrency");
|
|
1369
|
-
if (runner.stats !== void 0) parsedRunner.stats = parseRunnerStats(runner.stats);
|
|
1370
|
-
if (runner.timeout_ms !== void 0) parsedRunner.timeoutMs = parsePositiveInteger(runner.timeout_ms, "runner timeout_ms");
|
|
1371
|
-
return parsedRunner;
|
|
1372
|
-
}
|
|
1373
|
-
function parseRunnerCache(cache) {
|
|
1374
|
-
if (typeof cache === "boolean") return cache;
|
|
1375
|
-
if (!isPlainObject$1(cache)) throw new TypeError("Invalid runner cache: must be a boolean or table.");
|
|
1376
|
-
const tomlCache = cache;
|
|
1377
|
-
const parsedCache = {};
|
|
1378
|
-
if (tomlCache.enabled !== void 0) {
|
|
1379
|
-
if (typeof tomlCache.enabled !== "boolean") throw new TypeError("Invalid runner cache enabled: must be a boolean.");
|
|
1380
|
-
parsedCache.enabled = tomlCache.enabled;
|
|
1381
|
-
}
|
|
1382
|
-
if (tomlCache.location !== void 0) parsedCache.location = readNonEmptyString(tomlCache.location, "runner cache location");
|
|
1383
|
-
return parsedCache;
|
|
1384
|
-
}
|
|
1385
|
-
function parseRunnerStats(stats) {
|
|
1386
|
-
if (typeof stats === "boolean") return stats;
|
|
1387
|
-
if (!isPlainObject$1(stats)) throw new TypeError("Invalid runner stats: must be a boolean or an object.");
|
|
1388
|
-
const tomlStats = stats;
|
|
1389
|
-
const parsedStats = {};
|
|
1390
|
-
if (tomlStats.enabled !== void 0) {
|
|
1391
|
-
if (typeof tomlStats.enabled !== "boolean") throw new TypeError("Invalid runner stats enabled: must be a boolean.");
|
|
1392
|
-
parsedStats.enabled = tomlStats.enabled;
|
|
1393
|
-
}
|
|
1394
|
-
if (tomlStats.location !== void 0) parsedStats.location = readNonEmptyString(tomlStats.location, "runner stats location");
|
|
1395
|
-
if (tomlStats.retention_months !== void 0) parsedStats.retentionMonths = parsePositiveInteger(tomlStats.retention_months, "runner stats retention_months");
|
|
1396
|
-
return parsedStats;
|
|
1397
|
-
}
|
|
1398
|
-
function readFiniteNumber(value, label) {
|
|
1399
|
-
if (typeof value !== "number" || !Number.isFinite(value)) throw new TypeError(`Invalid ${label}: must be a finite number.`);
|
|
1400
|
-
return value;
|
|
1401
|
-
}
|
|
1402
|
-
function readNonEmptyString(value, label) {
|
|
1403
|
-
const stringValue = readString(value, label);
|
|
1404
|
-
if (stringValue.length === 0) throw new Error(`Invalid ${label}: must be a non-empty string.`);
|
|
1405
|
-
return stringValue;
|
|
1406
|
-
}
|
|
1407
|
-
function readRecord(value, label) {
|
|
1408
|
-
if (!isPlainObject$1(value)) throw new Error(`Invalid ${label}: must be a table.`);
|
|
1409
|
-
return value;
|
|
1410
|
-
}
|
|
1411
|
-
function readString(value, label) {
|
|
1412
|
-
if (typeof value !== "string") throw new TypeError(`Invalid ${label}: must be a string.`);
|
|
1413
|
-
return value;
|
|
1414
|
-
}
|
|
1415
|
-
function readStringArray(value, label) {
|
|
1416
|
-
if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) throw new Error(`Invalid ${label}: must be an array of strings.`);
|
|
1417
|
-
return value;
|
|
1418
|
-
}
|
|
1419
|
-
function readStringMap(value, label) {
|
|
1420
|
-
const record = readRecord(value, label);
|
|
1421
|
-
if (!Object.values(record).every((item) => typeof item === "string")) throw new Error(`Invalid ${label}: must be a string map.`);
|
|
1422
|
-
return record;
|
|
1423
1404
|
}
|
|
1424
1405
|
function toTomlModel(model) {
|
|
1425
1406
|
const tomlModel = { id: model.id };
|
|
@@ -1435,7 +1416,7 @@ function toTomlProvider(provider) {
|
|
|
1435
1416
|
const tomlProvider = {
|
|
1436
1417
|
endpoint: provider.endpoint,
|
|
1437
1418
|
id: provider.id,
|
|
1438
|
-
models: provider.models.map(toTomlModel),
|
|
1419
|
+
models: provider.models.map((model) => "driver" in model && model.driver === "acp" ? toTomlAcpModel(model) : toTomlModel(model)),
|
|
1439
1420
|
type: provider.type
|
|
1440
1421
|
};
|
|
1441
1422
|
if (provider.headers !== void 0) tomlProvider.headers = provider.headers;
|
|
@@ -1494,8 +1475,8 @@ function mergeSetupConfigs(...configs) {
|
|
|
1494
1475
|
configProviders.push(mergedProvider);
|
|
1495
1476
|
continue;
|
|
1496
1477
|
}
|
|
1497
|
-
existingProvider.endpoint = provider.endpoint;
|
|
1498
|
-
existingProvider.type = provider.type;
|
|
1478
|
+
if (provider.endpoint !== void 0) existingProvider.endpoint = provider.endpoint;
|
|
1479
|
+
if (provider.type !== void 0) existingProvider.type = provider.type;
|
|
1499
1480
|
configProviders.push(existingProvider);
|
|
1500
1481
|
if (provider.headers !== void 0) existingProvider.headers = {
|
|
1501
1482
|
...existingProvider.headers,
|
|
@@ -1505,7 +1486,7 @@ function mergeSetupConfigs(...configs) {
|
|
|
1505
1486
|
for (const incomingModel of provider.models) {
|
|
1506
1487
|
const existingModelIndex = existingProvider.models.findIndex((model) => model.id === incomingModel.id);
|
|
1507
1488
|
if (existingModelIndex === -1) {
|
|
1508
|
-
nextModels.push(cloneModel$
|
|
1489
|
+
nextModels.push(cloneModel$2(incomingModel));
|
|
1509
1490
|
continue;
|
|
1510
1491
|
}
|
|
1511
1492
|
const existingModel = existingProvider.models[existingModelIndex];
|
|
@@ -1523,8 +1504,12 @@ function mergeSetupConfigs(...configs) {
|
|
|
1523
1504
|
if (runner !== void 0) mergedConfig.runner = runner;
|
|
1524
1505
|
return mergedConfig;
|
|
1525
1506
|
}
|
|
1526
|
-
function cloneModel$
|
|
1527
|
-
const clonedModel =
|
|
1507
|
+
function cloneModel$2(model) {
|
|
1508
|
+
const clonedModel = isAcpModel(model) ? {
|
|
1509
|
+
...model,
|
|
1510
|
+
args: model.args ? [...model.args] : void 0,
|
|
1511
|
+
env: model.env ? { ...model.env } : void 0
|
|
1512
|
+
} : { ...model };
|
|
1528
1513
|
if (model.aliases !== void 0) clonedModel.aliases = [...model.aliases];
|
|
1529
1514
|
if (model.capabilities !== void 0) clonedModel.capabilities = [...model.capabilities];
|
|
1530
1515
|
if (model.defaultParams !== void 0) clonedModel.defaultParams = { ...model.defaultParams };
|
|
@@ -1533,7 +1518,7 @@ function cloneModel$1(model) {
|
|
|
1533
1518
|
function cloneProvider$1(provider) {
|
|
1534
1519
|
const clonedProvider = {
|
|
1535
1520
|
...provider,
|
|
1536
|
-
models: provider.models.map(cloneModel$
|
|
1521
|
+
models: provider.models.map(cloneModel$2)
|
|
1537
1522
|
};
|
|
1538
1523
|
if (provider.headers !== void 0) clonedProvider.headers = { ...provider.headers };
|
|
1539
1524
|
return clonedProvider;
|
|
@@ -1545,15 +1530,9 @@ function createEmptySetupConfig() {
|
|
|
1545
1530
|
};
|
|
1546
1531
|
}
|
|
1547
1532
|
function mergeModel(existingModel, incomingModel) {
|
|
1548
|
-
const existing = cloneModel$
|
|
1549
|
-
const incoming = cloneModel$
|
|
1550
|
-
return
|
|
1551
|
-
...existing,
|
|
1552
|
-
...incoming,
|
|
1553
|
-
aliases: incoming.aliases ?? existing.aliases,
|
|
1554
|
-
capabilities: incoming.capabilities ?? existing.capabilities,
|
|
1555
|
-
defaultParams: incoming.defaultParams ?? existing.defaultParams
|
|
1556
|
-
};
|
|
1533
|
+
const existing = cloneModel$2(existingModel);
|
|
1534
|
+
const incoming = cloneModel$2(incomingModel);
|
|
1535
|
+
return merge(existing, incoming);
|
|
1557
1536
|
}
|
|
1558
1537
|
function prioritizeProviders(providers, prioritizedProviders) {
|
|
1559
1538
|
const prioritizedProviderIds = new Set(prioritizedProviders.map((provider) => provider.id));
|
|
@@ -1582,7 +1561,7 @@ function addProviderModels(config, providerId, modelIds) {
|
|
|
1582
1561
|
function pruneProviderModels(config, providerId, remoteModelIds) {
|
|
1583
1562
|
return updateProvider(config, providerId, (provider) => ({
|
|
1584
1563
|
...provider,
|
|
1585
|
-
models: provider.models.filter((model) => remoteModelIds.has(model.id))
|
|
1564
|
+
models: provider.models.filter((model) => isAcpModel(model) || remoteModelIds.has(model.id))
|
|
1586
1565
|
}));
|
|
1587
1566
|
}
|
|
1588
1567
|
function removeProviderModels(config, providerId, modelIds) {
|
|
@@ -1619,7 +1598,7 @@ function unsetProviderHeader(config, providerId, name) {
|
|
|
1619
1598
|
};
|
|
1620
1599
|
});
|
|
1621
1600
|
}
|
|
1622
|
-
function cloneModel(model) {
|
|
1601
|
+
function cloneModel$1(model) {
|
|
1623
1602
|
return {
|
|
1624
1603
|
...model,
|
|
1625
1604
|
aliases: model.aliases === void 0 ? void 0 : [...model.aliases],
|
|
@@ -1631,7 +1610,7 @@ function cloneProvider(provider) {
|
|
|
1631
1610
|
return {
|
|
1632
1611
|
...provider,
|
|
1633
1612
|
headers: provider.headers === void 0 ? void 0 : { ...provider.headers },
|
|
1634
|
-
models: provider.models.map(cloneModel)
|
|
1613
|
+
models: provider.models.map(cloneModel$1)
|
|
1635
1614
|
};
|
|
1636
1615
|
}
|
|
1637
1616
|
function headersWithoutName(headers, name) {
|
|
@@ -1650,10 +1629,94 @@ function updateProvider(config, providerId, update) {
|
|
|
1650
1629
|
};
|
|
1651
1630
|
}
|
|
1652
1631
|
//#endregion
|
|
1632
|
+
//#region src/setup/normalize.ts
|
|
1633
|
+
/** Normalizes setup-file providers while delegating only model-driven transports. */
|
|
1634
|
+
async function normalizeSetupConfig(config, adapters) {
|
|
1635
|
+
const providers = [];
|
|
1636
|
+
for (const provider of config.providers) {
|
|
1637
|
+
const acpModels = provider.models.filter(isAcpModel);
|
|
1638
|
+
if (acpModels.length === 0) {
|
|
1639
|
+
if (provider.models.length > 0) {
|
|
1640
|
+
const normalizedProvider = providerFromConfig(provider);
|
|
1641
|
+
normalizedProvider.models.push(...provider.models.map(cloneModel));
|
|
1642
|
+
providers.push(normalizedProvider);
|
|
1643
|
+
}
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
const acpProvider = await adapters.acp({
|
|
1647
|
+
id: provider.id,
|
|
1648
|
+
models: acpModels.map(cloneAcpModel)
|
|
1649
|
+
});
|
|
1650
|
+
let activeDriver;
|
|
1651
|
+
let activeProvider;
|
|
1652
|
+
for (const model of provider.models) {
|
|
1653
|
+
const driver = isAcpModel(model) ? "acp" : "provider";
|
|
1654
|
+
const normalizedModel = cloneModel(isAcpModel(model) ? modelFromAcpModel(model) : model);
|
|
1655
|
+
if (driver === activeDriver && activeProvider !== void 0) {
|
|
1656
|
+
activeProvider.models.push(normalizedModel);
|
|
1657
|
+
continue;
|
|
1658
|
+
}
|
|
1659
|
+
activeDriver = driver;
|
|
1660
|
+
activeProvider = driver === "acp" ? providerFromAdapter(provider.id, acpProvider) : providerFromConfig(provider);
|
|
1661
|
+
activeProvider.models.push(normalizedModel);
|
|
1662
|
+
providers.push(activeProvider);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
return {
|
|
1666
|
+
providers,
|
|
1667
|
+
...config.runner === void 0 ? {} : { runner: cloneRunner(config.runner) },
|
|
1668
|
+
version: 1
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
function cloneAcpModel(model) {
|
|
1672
|
+
return {
|
|
1673
|
+
...model,
|
|
1674
|
+
aliases: model.aliases ? [...model.aliases] : void 0,
|
|
1675
|
+
args: model.args ? [...model.args] : void 0,
|
|
1676
|
+
capabilities: model.capabilities ? [...model.capabilities] : void 0,
|
|
1677
|
+
defaultParams: model.defaultParams ? { ...model.defaultParams } : void 0,
|
|
1678
|
+
env: model.env ? { ...model.env } : void 0
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
function cloneModel(model) {
|
|
1682
|
+
return {
|
|
1683
|
+
...model,
|
|
1684
|
+
aliases: model.aliases ? [...model.aliases] : void 0,
|
|
1685
|
+
capabilities: model.capabilities ? [...model.capabilities] : void 0,
|
|
1686
|
+
defaultParams: model.defaultParams ? { ...model.defaultParams } : void 0
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
function cloneRunner(runner) {
|
|
1690
|
+
return {
|
|
1691
|
+
...runner,
|
|
1692
|
+
cache: typeof runner.cache === "object" ? { ...runner.cache } : runner.cache,
|
|
1693
|
+
stats: typeof runner.stats === "object" ? { ...runner.stats } : runner.stats
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
function providerFromAdapter(id, provider) {
|
|
1697
|
+
return {
|
|
1698
|
+
...provider,
|
|
1699
|
+
headers: provider.headers ? { ...provider.headers } : void 0,
|
|
1700
|
+
id,
|
|
1701
|
+
models: []
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
function providerFromConfig(provider) {
|
|
1705
|
+
if (provider.endpoint === void 0) throw new Error(`Provider "${provider.id}" requires endpoint for models without a driver.`);
|
|
1706
|
+
if (provider.type === void 0) throw new Error(`Provider "${provider.id}" requires type for models without a driver.`);
|
|
1707
|
+
return {
|
|
1708
|
+
endpoint: provider.endpoint,
|
|
1709
|
+
headers: provider.headers ? { ...provider.headers } : void 0,
|
|
1710
|
+
id: provider.id,
|
|
1711
|
+
models: [],
|
|
1712
|
+
type: provider.type
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
//#endregion
|
|
1653
1716
|
//#region src/setup/write.ts
|
|
1654
1717
|
async function writeSetupConfig(filePath, config) {
|
|
1655
1718
|
await mkdir(dirname$1(filePath), { recursive: true });
|
|
1656
1719
|
await writeFile(filePath, stringifySetupConfigToml(config), "utf8");
|
|
1657
1720
|
}
|
|
1658
1721
|
//#endregion
|
|
1659
|
-
export { addProviderModels, builtInAgentNames, createDeclarativePlugin, createEmptyPluginLockFile, createReportScope, declarativeFindingResponseSchema, declarativeFindingSchema, declarativeRuleFilePattern, emptySetupConfig, getGlobalSetupConfigPath, getProjectPluginLockPath, getProjectPluginStorePath, getProjectSetupConfigPath, getStatsDir, hasDeclarativeRuleFiles, ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated, installStaticPlugins, isBuiltInAgentName, listMissing, listUnresolved, loadAlintConfig, loadDeclarativeRules, loadPluginLockFile, loadSetupConfig, loadStaticConfig, mergeSetupConfigs, parsePluginLockFile, parsePluginSpecifier, parseSetupConfigToml, parseStaticConfig, pruneProviderModels, removeProviderModels, replaceSetupProvider, setProviderEndpoint, setProviderHeader, stringifySetupConfigToml, toAlintConfig, unsetProviderHeader, writePluginLockFile, writeSetupConfig };
|
|
1722
|
+
export { addProviderModels, builtInAgentNames, createDeclarativePlugin, createEmptyPluginLockFile, createReportScope, declarativeFindingResponseSchema, declarativeFindingSchema, declarativeRuleFilePattern, emptySetupConfig, getGlobalSetupConfigPath, getProjectPluginLockPath, getProjectPluginStorePath, getProjectSetupConfigPath, getStatsDir, hasDeclarativeRuleFiles, ignorePatternsAIAgents, ignorePatternsBuildOutputs, ignorePatternsCaches, ignorePatternsCommon, ignorePatternsEslintDefaults, ignorePatternsGenerated, installStaticPlugins, isAcpModel, isBuiltInAgentName, listMissing, listUnresolved, loadAlintConfig, loadDeclarativeRules, loadPluginLockFile, loadSetupConfig, loadStaticConfig, mergeSetupConfigs, modelFromAcpModel, normalizeSetupConfig, parsePluginLockFile, parsePluginSpecifier, parseSetupConfigToml, parseStaticConfig, pruneProviderModels, removeProviderModels, replaceSetupProvider, setProviderEndpoint, setProviderHeader, stringifySetupConfigToml, toAlintConfig, unsetProviderHeader, writePluginLockFile, writeSetupConfig };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alint-js/config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.mts",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"tar-stream": "^3.2.0",
|
|
29
29
|
"valibot": "^1.4.2",
|
|
30
30
|
"xdg-basedir": "^5.1.0",
|
|
31
|
-
"@alint-js/core": "0.
|
|
32
|
-
"@alint-js/tools-fs": "0.
|
|
31
|
+
"@alint-js/core": "0.4.0",
|
|
32
|
+
"@alint-js/tools-fs": "0.4.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/tar-stream": "^3.1.4",
|