structured-context 0.18.0 → 0.20.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/api.d.ts +1 -0
- package/dist/api.js +1 -0
- package/dist/commands/dump.d.ts +2 -2
- package/dist/commands/dump.js +2 -2
- package/dist/commands/validate-file.d.ts +2 -4
- package/dist/commands/validate-file.js +1 -8
- package/dist/commands/validate.d.ts +2 -5
- package/dist/commands/validate.js +6 -16
- package/dist/errors.d.ts +1 -1
- package/dist/index.js +4 -17
- package/dist/judge/factory.d.ts +1 -3
- package/dist/judge/factory.js +7 -8
- package/dist/load-space-graph.d.ts +7 -7
- package/dist/load-space-graph.js +14 -10
- package/dist/schema/schema.d.ts +6 -0
- package/dist/schema/schema.js +62 -1
- package/dist/validate.d.ts +50 -15
- package/dist/validate.js +36 -39
- package/package.json +1 -1
- package/dist/judge/index.d.ts +0 -13
- package/dist/judge/index.js +0 -8
package/dist/api.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type { Config, SpaceConfig } from './config';
|
|
|
23
23
|
export { loadConfig, resolveConfigPath, resolveSchema, resolveSchemaPath, setConfigPath } from './config';
|
|
24
24
|
export { addSpace } from './config/write';
|
|
25
25
|
export { LOCAL_CONFIG_FILE, PLUGIN_PREFIX } from './constants';
|
|
26
|
+
export { SctxError, type SctxErrorCode } from './errors';
|
|
26
27
|
export { assembleSpaceGraph, loadSpaceGraph } from './load-space-graph';
|
|
27
28
|
export type { ParseHook, ParseResult, PluginContext, RenderFileOutput, RenderFormat, RenderHook, RenderMultiFileOutput, RenderOptions, RenderResult, StructuredContextPlugin, TemplateSyncHook, TemplateSyncOptions, } from './plugins/util';
|
|
28
29
|
export { isRenderMultiFileOutput, resolvePluginDir, resolvePluginSchemasDir, resolveSpacePluginSchemas, } from './plugins/util';
|
package/dist/api.js
CHANGED
|
@@ -22,6 +22,7 @@ export { spaceGraphFrom } from './browser';
|
|
|
22
22
|
export { loadConfig, resolveConfigPath, resolveSchema, resolveSchemaPath, setConfigPath } from './config';
|
|
23
23
|
export { addSpace } from './config/write';
|
|
24
24
|
export { LOCAL_CONFIG_FILE, PLUGIN_PREFIX } from './constants';
|
|
25
|
+
export { SctxError } from './errors';
|
|
25
26
|
export { assembleSpaceGraph, loadSpaceGraph } from './load-space-graph';
|
|
26
27
|
export { isRenderMultiFileOutput, resolvePluginDir, resolvePluginSchemasDir, resolveSpacePluginSchemas, } from './plugins/util';
|
|
27
28
|
export { readSpace } from './read/read-space';
|
package/dist/commands/dump.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ export interface DumpOptions {
|
|
|
10
10
|
/**
|
|
11
11
|
* Build the dump payload: every parsed node, or only nodes matched by a filter.
|
|
12
12
|
*
|
|
13
|
-
* Unfiltered dumps include
|
|
14
|
-
* Filtered dumps match show/render: the filter runs over the graph of
|
|
13
|
+
* Unfiltered dumps include nodes of an unknown type, since dump is a debugging aid.
|
|
14
|
+
* Filtered dumps match show/render: the filter runs over the graph of nodes with a known type.
|
|
15
15
|
*/
|
|
16
16
|
export declare function buildDump(context: SpaceContext, options?: DumpOptions): Promise<ReadSpaceResult>;
|
|
17
17
|
export declare function dump(context: SpaceContext, options?: DumpOptions): Promise<void>;
|
package/dist/commands/dump.js
CHANGED
|
@@ -4,8 +4,8 @@ import { exportSpaceGraph } from '../space-graph-data';
|
|
|
4
4
|
/**
|
|
5
5
|
* Build the dump payload: every parsed node, or only nodes matched by a filter.
|
|
6
6
|
*
|
|
7
|
-
* Unfiltered dumps include
|
|
8
|
-
* Filtered dumps match show/render: the filter runs over the graph of
|
|
7
|
+
* Unfiltered dumps include nodes of an unknown type, since dump is a debugging aid.
|
|
8
|
+
* Filtered dumps match show/render: the filter runs over the graph of nodes with a known type.
|
|
9
9
|
*/
|
|
10
10
|
export async function buildDump(context, options = {}) {
|
|
11
11
|
const readResult = await readSpace(context);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ValidateFileOptions } from '../validate';
|
|
1
2
|
export { validateFile } from '../validate';
|
|
2
3
|
/**
|
|
3
4
|
* CLI command: validate a file and print results to stdout.
|
|
@@ -6,7 +7,4 @@ export { validateFile } from '../validate';
|
|
|
6
7
|
*/
|
|
7
8
|
export declare function validateFileCommand(filePath: string, options?: {
|
|
8
9
|
json?: boolean;
|
|
9
|
-
|
|
10
|
-
semantic?: boolean | string;
|
|
11
|
-
ruleFilter?: string[];
|
|
12
|
-
}): Promise<number>;
|
|
10
|
+
} & Omit<ValidateFileOptions, 'configDir'>): Promise<number>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { loadConfig } from '../config';
|
|
2
|
-
import { judgeForRun } from '../judge/factory';
|
|
3
|
-
import { parseRuleFilter } from '../schema/rule-filter';
|
|
4
2
|
import { createSpaceContext } from '../space-context';
|
|
5
3
|
import { fileNotInSpace, resolveFileSpace, validateResolvedFile } from '../validate';
|
|
6
4
|
export { validateFile } from '../validate';
|
|
@@ -14,12 +12,7 @@ export async function validateFileCommand(filePath, options = {}) {
|
|
|
14
12
|
const resolved = resolveFileSpace(filePath, config);
|
|
15
13
|
let result;
|
|
16
14
|
if (resolved) {
|
|
17
|
-
|
|
18
|
-
result = await validateResolvedFile(filePath, resolved.label, createSpaceContext(resolved.space.name, config), {
|
|
19
|
-
includeGated: options.includeGated,
|
|
20
|
-
judge,
|
|
21
|
-
ruleFilter: options.ruleFilter && parseRuleFilter(options.ruleFilter),
|
|
22
|
-
});
|
|
15
|
+
result = await validateResolvedFile(filePath, resolved.label, createSpaceContext(resolved.space.name, config), options);
|
|
23
16
|
}
|
|
24
17
|
else {
|
|
25
18
|
result = fileNotInSpace(filePath);
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { SpaceContext } from '../types';
|
|
2
|
+
import { type ValidateSpaceOptions } from '../validate';
|
|
2
3
|
export declare function validate(context: SpaceContext, options?: {
|
|
3
4
|
json?: boolean;
|
|
4
|
-
|
|
5
|
-
includeGated?: boolean;
|
|
6
|
-
semantic?: boolean | string;
|
|
7
|
-
ruleFilter?: string[];
|
|
8
|
-
}): Promise<number>;
|
|
5
|
+
} & ValidateSpaceOptions): Promise<number>;
|
|
9
6
|
export declare function watchValidate(context: SpaceContext): Promise<never>;
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
2
|
import chokidar from 'chokidar';
|
|
3
3
|
import { getConfigSourceFiles } from '../config';
|
|
4
|
-
import { judgeForRun } from '../judge/factory';
|
|
5
4
|
import { resolveSpacePluginSchemas } from '../plugins/util';
|
|
6
|
-
import { parseRuleFilter } from '../schema/rule-filter';
|
|
7
5
|
import { bundledSchemasDir } from '../schema/schema';
|
|
8
|
-
import {
|
|
6
|
+
import { formatSource, ruleViolationMessage, validateSpace } from '../validate';
|
|
9
7
|
export async function validate(context, options = {}) {
|
|
10
|
-
const
|
|
11
|
-
const result = await validateSpace(context, {
|
|
12
|
-
depth: options.depth,
|
|
13
|
-
includeGated: options.includeGated,
|
|
14
|
-
judge: judgeForRun(context.config, context.space, options.semantic),
|
|
15
|
-
ruleFilter: options.ruleFilter && parseRuleFilter(options.ruleFilter),
|
|
16
|
-
});
|
|
8
|
+
const result = await validateSpace(context, options);
|
|
17
9
|
const ruleCounts = { error: 0, warning: 0, info: 0 };
|
|
18
10
|
for (const v of result.ruleViolations)
|
|
19
11
|
ruleCounts[v.severity]++;
|
|
@@ -25,9 +17,8 @@ export async function validate(context, options = {}) {
|
|
|
25
17
|
errorsByFile[file] = {};
|
|
26
18
|
errorsByFile[file][key] = severity ? { kind, message, severity } : { kind, message };
|
|
27
19
|
};
|
|
28
|
-
for (const { nodeId,
|
|
29
|
-
const
|
|
30
|
-
for (const { message, dedupeKey } of formatted) {
|
|
20
|
+
for (const { nodeId, issues } of result.nodeErrors) {
|
|
21
|
+
for (const { message, dedupeKey } of issues) {
|
|
31
22
|
addError(nodeId, `schema:${dedupeKey}`, 'schema', message);
|
|
32
23
|
}
|
|
33
24
|
}
|
|
@@ -119,10 +110,9 @@ export async function validate(context, options = {}) {
|
|
|
119
110
|
}
|
|
120
111
|
if (result.nodeErrors.length > 0) {
|
|
121
112
|
console.log(`\nSchema validation errors:`);
|
|
122
|
-
result.nodeErrors.forEach(({ nodeId, source,
|
|
113
|
+
result.nodeErrors.forEach(({ nodeId, source, issues }) => {
|
|
123
114
|
console.log(`\n ${source ? formatSource(source) : nodeId}:`);
|
|
124
|
-
|
|
125
|
-
formatted.forEach(({ message }) => {
|
|
115
|
+
issues.forEach(({ message }) => {
|
|
126
116
|
console.log(` ${message}`);
|
|
127
117
|
});
|
|
128
118
|
});
|
package/dist/errors.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Stable codes for configuration and environment problems. Hooks and agent skills map a code to a
|
|
3
3
|
* fix, so the message wording can change without breaking them.
|
|
4
4
|
*/
|
|
5
|
-
export type SctxErrorCode = 'E_CONFIG_NOT_FOUND' | 'E_CONFIG_INVALID' | 'E_INCLUDE_NOT_FOUND' | 'E_NO_SPACES' | 'E_SPACE_PATH_MISSING' | 'E_SCHEMA_MISSING' | 'E_SCHEMA_NOT_FOUND' | 'E_SCHEMA_INVALID' | 'E_SPACE_EXISTS' | 'E_TARGET_REQUIRED' | 'E_CONFIG_NEEDS_MANUAL_EDIT';
|
|
5
|
+
export type SctxErrorCode = 'E_CONFIG_NOT_FOUND' | 'E_CONFIG_INVALID' | 'E_INCLUDE_NOT_FOUND' | 'E_NO_SPACES' | 'E_SPACE_PATH_MISSING' | 'E_SCHEMA_MISSING' | 'E_SCHEMA_NOT_FOUND' | 'E_SCHEMA_INVALID' | 'E_SPACE_EXISTS' | 'E_TARGET_REQUIRED' | 'E_CONFIG_NEEDS_MANUAL_EDIT' | 'E_MODEL_PROVIDER_INVALID';
|
|
6
6
|
export declare class SctxError extends Error {
|
|
7
7
|
readonly code: SctxErrorCode;
|
|
8
8
|
constructor(code: SctxErrorCode, message: string);
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,6 @@ import { validateFileCommand } from './commands/validate-file';
|
|
|
17
17
|
import { loadConfig, setConfigPath } from './config';
|
|
18
18
|
import { CLI_NAME } from './constants';
|
|
19
19
|
import { SctxError } from './errors';
|
|
20
|
-
import { JudgeConfigError } from './judge/factory';
|
|
21
20
|
import { createSpaceContext, SpaceNotFoundError } from './space-context';
|
|
22
21
|
// Once node:process is loaded (vfile, via unified, loads it), Bun's console.log drops piped output
|
|
23
22
|
// past 64KB when the reader is slow. process.stdout.write delivers all of it before exit.
|
|
@@ -36,18 +35,6 @@ export function buildSpaceContext(spaceName) {
|
|
|
36
35
|
throw err;
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
|
-
/** Run a validate command, reporting a misconfigured model provider as a plain error rather than a stack trace. */
|
|
40
|
-
async function reportJudgeConfigErrors(run) {
|
|
41
|
-
try {
|
|
42
|
-
return await run();
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
if (!(err instanceof JudgeConfigError))
|
|
46
|
-
throw err;
|
|
47
|
-
console.error(`Error: ${err.message}`);
|
|
48
|
-
return 1;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
38
|
const require = createRequire(import.meta.url);
|
|
52
39
|
const packageJson = require('../package.json');
|
|
53
40
|
const program = new Command();
|
|
@@ -68,12 +55,12 @@ program
|
|
|
68
55
|
.option('--rule-filter <dimension=values>', 'Evaluate only matching rules; dimensions: category, severity, type, id (repeatable, e.g. severity=error)', (v, prev = []) => [...prev, v])
|
|
69
56
|
.option('--semantic [provider]', 'Evaluate semantic rules, with the configured model provider or the one named')
|
|
70
57
|
.action(async (filePath, options) => {
|
|
71
|
-
process.exitCode = await
|
|
58
|
+
process.exitCode = await validateFileCommand(filePath, {
|
|
72
59
|
json: options.json,
|
|
73
60
|
includeGated: options.includeGated,
|
|
74
61
|
semantic: options.semantic,
|
|
75
62
|
ruleFilter: options.ruleFilter,
|
|
76
|
-
})
|
|
63
|
+
});
|
|
77
64
|
});
|
|
78
65
|
program
|
|
79
66
|
.command('validate')
|
|
@@ -92,13 +79,13 @@ program
|
|
|
92
79
|
}
|
|
93
80
|
else {
|
|
94
81
|
// exitCode rather than process.exit(): exiting straight away can cut off large piped output
|
|
95
|
-
process.exitCode = await
|
|
82
|
+
process.exitCode = await validate(context, {
|
|
96
83
|
json: options.json,
|
|
97
84
|
depth: options.depth,
|
|
98
85
|
includeGated: options.includeGated,
|
|
99
86
|
semantic: options.semantic,
|
|
100
87
|
ruleFilter: options.ruleFilter,
|
|
101
|
-
})
|
|
88
|
+
});
|
|
102
89
|
}
|
|
103
90
|
});
|
|
104
91
|
program
|
package/dist/judge/factory.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ type Env = Record<string, string | undefined>;
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const BUNDLED_PROVIDERS: Record<string, ModelProviderConfig>;
|
|
9
9
|
/** Semantic evaluation is misconfigured (no provider, unknown provider, missing key). Reported as a plain CLI error. */
|
|
10
|
-
export declare class JudgeConfigError extends Error {
|
|
11
|
-
}
|
|
12
10
|
/**
|
|
13
11
|
* Hydrate a provider definition into concrete values, in one place. Per field: the explicit value
|
|
14
12
|
* wins, then the named environment variable if it is set (a set-but-empty variable is an error, not
|
|
@@ -29,7 +27,7 @@ export declare function judgeForRun(config: Parameters<typeof createJudge>[0], s
|
|
|
29
27
|
/**
|
|
30
28
|
* The provider for a run: the one named by `name` (the `--semantic <provider>` override), else the space's
|
|
31
29
|
* `semantic.provider`, else the top-level one. The name resolves against `modelProviders` first, then
|
|
32
|
-
* the bundled providers. Throws {@link
|
|
30
|
+
* the bundled providers. Throws {@link SctxError} `E_MODEL_PROVIDER_INVALID` when it cannot be built.
|
|
33
31
|
*/
|
|
34
32
|
export declare function createJudge(config: {
|
|
35
33
|
modelProviders?: Record<string, ModelProviderConfig>;
|
package/dist/judge/factory.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SctxError } from '../errors';
|
|
1
2
|
import { AnthropicJudgeProvider, RECOMMENDED_ANTHROPIC_MODEL } from './provider/anthropic';
|
|
2
3
|
import { FakeJudgeProvider } from './provider/fake';
|
|
3
4
|
import { JEV_LATEST, JevJudgeProvider } from './provider/jev';
|
|
@@ -66,8 +67,6 @@ const DEFAULT_KEY_ENV = {
|
|
|
66
67
|
'typesafe-systemone': 'TYPESAFE_API_KEY',
|
|
67
68
|
};
|
|
68
69
|
/** Semantic evaluation is misconfigured (no provider, unknown provider, missing key). Reported as a plain CLI error. */
|
|
69
|
-
export class JudgeConfigError extends Error {
|
|
70
|
-
}
|
|
71
70
|
/**
|
|
72
71
|
* Hydrate a provider definition into concrete values, in one place. Per field: the explicit value
|
|
73
72
|
* wins, then the named environment variable if it is set (a set-but-empty variable is an error, not
|
|
@@ -75,7 +74,7 @@ export class JudgeConfigError extends Error {
|
|
|
75
74
|
*/
|
|
76
75
|
export function hydrateProvider(name, def, env = process.env) {
|
|
77
76
|
if (!MODEL_PROVIDER_APIS.includes(def.api)) {
|
|
78
|
-
throw new
|
|
77
|
+
throw new SctxError('E_MODEL_PROVIDER_INVALID', `Model provider "${name}" has unknown api "${def.api}". Use one of: ${MODEL_PROVIDER_APIS.join(', ')}.`);
|
|
79
78
|
}
|
|
80
79
|
const fromEnv = (value, envName) => {
|
|
81
80
|
if (value !== undefined)
|
|
@@ -84,7 +83,7 @@ export function hydrateProvider(name, def, env = process.env) {
|
|
|
84
83
|
return undefined;
|
|
85
84
|
const envValue = env[envName];
|
|
86
85
|
if (envValue !== undefined && envValue.trim() === '') {
|
|
87
|
-
throw new
|
|
86
|
+
throw new SctxError('E_MODEL_PROVIDER_INVALID', `Model provider "${name}" has ${envName} set but empty; set a value or unset the variable.`);
|
|
88
87
|
}
|
|
89
88
|
return envValue;
|
|
90
89
|
};
|
|
@@ -104,7 +103,7 @@ export function createModelProvider(name, def, env = process.env) {
|
|
|
104
103
|
// OpenAI-compatible endpoints (Ollama, vLLM, ...) may need no key; the others must resolve one.
|
|
105
104
|
// A key never borrows another provider's variable: only the named apiKeyEnv (or literal apiKey) counts.
|
|
106
105
|
if (!h.apiKey && h.api !== 'openai-completions' && h.api !== 'fake') {
|
|
107
|
-
throw new
|
|
106
|
+
throw new SctxError('E_MODEL_PROVIDER_INVALID', `Model provider "${name}" (${h.api}) has no API key. Set ${h.keyEnv} in the environment, or "apiKey" / "apiKeyEnv" on the provider.`);
|
|
108
107
|
}
|
|
109
108
|
switch (h.api) {
|
|
110
109
|
case 'fake':
|
|
@@ -132,17 +131,17 @@ export function judgeForRun(config, space, semantic) {
|
|
|
132
131
|
/**
|
|
133
132
|
* The provider for a run: the one named by `name` (the `--semantic <provider>` override), else the space's
|
|
134
133
|
* `semantic.provider`, else the top-level one. The name resolves against `modelProviders` first, then
|
|
135
|
-
* the bundled providers. Throws {@link
|
|
134
|
+
* the bundled providers. Throws {@link SctxError} `E_MODEL_PROVIDER_INVALID` when it cannot be built.
|
|
136
135
|
*/
|
|
137
136
|
export function createJudge(config, space = {}, name, env = process.env) {
|
|
138
137
|
const chosen = name ?? space.semantic?.provider ?? config.semantic?.provider;
|
|
139
138
|
if (!chosen) {
|
|
140
|
-
throw new
|
|
139
|
+
throw new SctxError('E_MODEL_PROVIDER_INVALID', '--semantic needs a model provider. Set "semantic.provider" in config.json, or pass --semantic <provider>.');
|
|
141
140
|
}
|
|
142
141
|
const def = config.modelProviders?.[chosen] ?? BUNDLED_PROVIDERS[chosen];
|
|
143
142
|
if (!def) {
|
|
144
143
|
const known = [...Object.keys(BUNDLED_PROVIDERS), ...Object.keys(config.modelProviders ?? {})];
|
|
145
|
-
throw new
|
|
144
|
+
throw new SctxError('E_MODEL_PROVIDER_INVALID', `Model provider "${chosen}" is not configured.${known.length ? ` Known providers: ${known.join(', ')}.` : ''}`);
|
|
146
145
|
}
|
|
147
146
|
return createModelProvider(chosen, def, env);
|
|
148
147
|
}
|
|
@@ -10,14 +10,14 @@ export interface AssembleSpaceGraphOptions {
|
|
|
10
10
|
readResult?: ReadSpaceResult;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Assemble a SpaceGraph from a space context: read the space, drop nodes
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* Assemble a SpaceGraph from a space context: read the space, drop nodes whose type the schema
|
|
14
|
+
* does not define, build the graph for the selected hierarchy (the main hierarchy by default),
|
|
15
|
+
* and apply an optional view/filter expression.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* duplicates. Use validateSpace for a full validation report.
|
|
17
|
+
* A node with schema field errors (for example an invalid enum value) stays in the graph, since
|
|
18
|
+
* it still has a type and a place in the hierarchy. Only nodes that cannot be placed are left
|
|
19
|
+
* out. This is NOT a validation pass — nodes may have field errors, broken references, rule
|
|
20
|
+
* violations, or duplicates. Use validateSpace for a full validation report.
|
|
21
21
|
*
|
|
22
22
|
* Shared by the render pipeline and the public loadSpaceGraph API so their
|
|
23
23
|
* graph-assembly behaviour cannot drift.
|
package/dist/load-space-graph.js
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import { filterNodes } from './filter/filter-nodes';
|
|
2
2
|
import { readSpace } from './read/read-space';
|
|
3
|
+
import { extractSchemaTypeNames } from './schema/schema';
|
|
3
4
|
import { createSpaceContext } from './space-context';
|
|
4
5
|
import { buildSpaceGraph, selectHierarchy } from './space-graph';
|
|
5
6
|
/**
|
|
6
|
-
* Assemble a SpaceGraph from a space context: read the space, drop nodes
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Assemble a SpaceGraph from a space context: read the space, drop nodes whose type the schema
|
|
8
|
+
* does not define, build the graph for the selected hierarchy (the main hierarchy by default),
|
|
9
|
+
* and apply an optional view/filter expression.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* duplicates. Use validateSpace for a full validation report.
|
|
11
|
+
* A node with schema field errors (for example an invalid enum value) stays in the graph, since
|
|
12
|
+
* it still has a type and a place in the hierarchy. Only nodes that cannot be placed are left
|
|
13
|
+
* out. This is NOT a validation pass — nodes may have field errors, broken references, rule
|
|
14
|
+
* violations, or duplicates. Use validateSpace for a full validation report.
|
|
14
15
|
*
|
|
15
16
|
* Shared by the render pipeline and the public loadSpaceGraph API so their
|
|
16
17
|
* graph-assembly behaviour cannot drift.
|
|
17
18
|
*/
|
|
18
19
|
export async function assembleSpaceGraph(context, options = {}) {
|
|
19
20
|
const { nodes: allNodes } = options.readResult ?? (await readSpace(context));
|
|
20
|
-
const {
|
|
21
|
-
const
|
|
22
|
-
|
|
21
|
+
const { schema, schemaRefRegistry } = context;
|
|
22
|
+
const schemaTypes = Array.isArray(schema.oneOf) ? extractSchemaTypeNames(schema, schemaRefRegistry) : undefined;
|
|
23
|
+
const placeableNodes = schemaTypes
|
|
24
|
+
? allNodes.filter((node) => schemaTypes.has(String(node.schemaData.type)))
|
|
25
|
+
: allNodes;
|
|
26
|
+
let graph = buildSpaceGraph(placeableNodes, selectHierarchy(context.schema.metadata, options.hierarchy));
|
|
23
27
|
if (options.filter) {
|
|
24
28
|
const expression = context.space.views?.[options.filter]?.expression ?? options.filter;
|
|
25
29
|
graph = await filterNodes(expression, graph);
|
package/dist/schema/schema.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export type PluginSchemaSource = {
|
|
|
17
17
|
* Throws if a lower-precedence schema collides with a reserved $id or violates namespace rules.
|
|
18
18
|
*/
|
|
19
19
|
export declare function buildFullRegistry(schemaPath: string, pluginSchemas?: PluginSchemaSource[]): Map<string, AnySchemaObject>;
|
|
20
|
+
/**
|
|
21
|
+
* Validator for one node type: the schema's shared `allOf` plus only that type's `oneOf` branch.
|
|
22
|
+
* Errors then come only from the node's own type, not from every branch that did not match.
|
|
23
|
+
* Returns undefined when the schema has no such branch, so callers fall back to the full validator.
|
|
24
|
+
*/
|
|
25
|
+
export declare function typeValidatorFor(fullValidator: ValidateFunction, type: string): ValidateFunction | undefined;
|
|
20
26
|
export declare function createValidator(schemaPath: string, pluginSchemas?: PluginSchemaSource[]): ValidateFunction;
|
|
21
27
|
export declare function resolveNodeType(type: string, typeAliases: Record<string, string> | undefined): string;
|
|
22
28
|
export interface EntityInfo {
|
package/dist/schema/schema.js
CHANGED
|
@@ -234,7 +234,68 @@ function compileValidator(targetSchema, schemaRefRegistry) {
|
|
|
234
234
|
continue;
|
|
235
235
|
ajv.addSchema(schema);
|
|
236
236
|
}
|
|
237
|
-
|
|
237
|
+
const validator = ajv.compile(targetSchema);
|
|
238
|
+
typeValidators.set(validator, createTypeValidatorLookup(ajv, targetSchema, schemaRefRegistry));
|
|
239
|
+
return validator;
|
|
240
|
+
}
|
|
241
|
+
/** Root keywords that do not constrain a node: a root with any other keyword cannot be split into per-type checks. */
|
|
242
|
+
const NON_CONSTRAINING_ROOT_KEYWORDS = new Set([
|
|
243
|
+
'$schema',
|
|
244
|
+
'$id',
|
|
245
|
+
'$metadata',
|
|
246
|
+
'$defs',
|
|
247
|
+
'title',
|
|
248
|
+
'description',
|
|
249
|
+
'allOf',
|
|
250
|
+
'oneOf',
|
|
251
|
+
]);
|
|
252
|
+
/** Per-type lookups, keyed by the full-schema validator they were compiled alongside. */
|
|
253
|
+
const typeValidators = new WeakMap();
|
|
254
|
+
/**
|
|
255
|
+
* Validator for one node type: the schema's shared `allOf` plus only that type's `oneOf` branch.
|
|
256
|
+
* Errors then come only from the node's own type, not from every branch that did not match.
|
|
257
|
+
* Returns undefined when the schema has no such branch, so callers fall back to the full validator.
|
|
258
|
+
*/
|
|
259
|
+
export function typeValidatorFor(fullValidator, type) {
|
|
260
|
+
return typeValidators.get(fullValidator)?.(type);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Compiled on first use. The wrapper references the branches inside the already-compiled root,
|
|
264
|
+
* so a branch's relative `$ref`s still resolve against the root.
|
|
265
|
+
*/
|
|
266
|
+
function createTypeValidatorLookup(ajv, rootSchema, schemaRefRegistry) {
|
|
267
|
+
const rootId = rootSchema.$id;
|
|
268
|
+
if (typeof rootId !== 'string' ||
|
|
269
|
+
!Array.isArray(rootSchema.oneOf) ||
|
|
270
|
+
!Object.keys(rootSchema).every((k) => NON_CONSTRAINING_ROOT_KEYWORDS.has(k))) {
|
|
271
|
+
return () => undefined;
|
|
272
|
+
}
|
|
273
|
+
const branchByType = new Map();
|
|
274
|
+
rootSchema.oneOf.forEach((branch, index) => {
|
|
275
|
+
const typeDef = mergeVariantProperties(branch, rootSchema, schemaRefRegistry).properties.type;
|
|
276
|
+
const types = typeDef?.const !== undefined ? [typeDef.const] : Array.isArray(typeDef?.enum) ? typeDef.enum : [];
|
|
277
|
+
for (const t of types)
|
|
278
|
+
if (!branchByType.has(String(t)))
|
|
279
|
+
branchByType.set(String(t), index);
|
|
280
|
+
});
|
|
281
|
+
const shared = Array.isArray(rootSchema.allOf)
|
|
282
|
+
? rootSchema.allOf.map((_, i) => ({ $ref: `${rootId}#/allOf/${i}` }))
|
|
283
|
+
: [];
|
|
284
|
+
const compiled = new Map();
|
|
285
|
+
return (type) => {
|
|
286
|
+
const index = branchByType.get(type);
|
|
287
|
+
if (index === undefined)
|
|
288
|
+
return undefined;
|
|
289
|
+
let validator = compiled.get(index);
|
|
290
|
+
if (!validator) {
|
|
291
|
+
validator = ajv.compile({
|
|
292
|
+
$id: `${rootId}/__type/${index}`,
|
|
293
|
+
allOf: [...shared, { $ref: `${rootId}#/oneOf/${index}` }],
|
|
294
|
+
});
|
|
295
|
+
compiled.set(index, validator);
|
|
296
|
+
}
|
|
297
|
+
return validator;
|
|
298
|
+
};
|
|
238
299
|
}
|
|
239
300
|
export function createValidator(schemaPath, pluginSchemas) {
|
|
240
301
|
return compileValidator(readRawSchema(schemaPath), buildFullRegistry(schemaPath, pluginSchemas));
|
package/dist/validate.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ export interface ValidationResult {
|
|
|
14
14
|
nodeErrors: Array<{
|
|
15
15
|
nodeId: NodeId;
|
|
16
16
|
source?: SourceLocation;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/** Formatted, deduplicated schema problems for the node, one per field problem. */
|
|
18
|
+
issues: FormattedError[];
|
|
19
19
|
}>;
|
|
20
20
|
refErrors: Array<{
|
|
21
21
|
nodeId: NodeId;
|
|
@@ -62,26 +62,64 @@ export interface ValidationResult {
|
|
|
62
62
|
* Groups related errors and extracts helpful context like allowed values.
|
|
63
63
|
*/
|
|
64
64
|
export declare function formatErrors(errors: ErrorObject[], schema: SchemaWithMetadata, schemaRefRegistry: Parameters<typeof extractEntityInfo>[1], nodeData: Record<string, unknown>): FormattedError[];
|
|
65
|
-
|
|
66
|
-
readResult?: ReadSpaceResult;
|
|
67
|
-
/** Limit validation to hierarchy nodes within N breadth-first levels from the top. */
|
|
68
|
-
depth?: number;
|
|
65
|
+
interface CommonValidateOptions {
|
|
69
66
|
/** Evaluate rules on gated nodes anyway (gates are still reported). */
|
|
70
67
|
includeGated?: boolean;
|
|
71
|
-
/** Evaluate only rules matching
|
|
68
|
+
/** Evaluate only rules matching these `dimension=values` filters (category, severity, type, id). */
|
|
69
|
+
ruleFilter?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Evaluate `semantic` rules with the model provider named here, or with the configured one for `true`.
|
|
72
|
+
* Without it, a rule runs only its `expression`, and a semantic-only rule is skipped.
|
|
73
|
+
*/
|
|
74
|
+
semantic?: boolean | string;
|
|
75
|
+
}
|
|
76
|
+
/** What a run evaluates with: the public options after the filter is parsed and the judge is built. */
|
|
77
|
+
export interface RunOptions {
|
|
78
|
+
includeGated?: boolean;
|
|
72
79
|
ruleFilter?: RuleFilter;
|
|
73
|
-
/** Evaluates `semantic` rules. Without one, a rule runs only its `expression`, and a semantic-only rule is skipped. */
|
|
74
80
|
judge?: SemanticJudgeProvider;
|
|
81
|
+
/** Limit judging to one file (and the ancestors that can gate it). */
|
|
82
|
+
judgeTarget?: string;
|
|
83
|
+
}
|
|
84
|
+
export interface ValidateSpaceOptions extends CommonValidateOptions {
|
|
85
|
+
readResult?: ReadSpaceResult;
|
|
86
|
+
/** Limit validation to hierarchy nodes within N breadth-first levels from the top. */
|
|
87
|
+
depth?: number;
|
|
75
88
|
}
|
|
76
89
|
/** `file`, `file:line` or `file:line:column`, for messages. */
|
|
77
90
|
export declare function formatSource({ file, line, column }: SourceLocation): string;
|
|
78
91
|
/** One-line text for a rule violation: rule, description, and any evidence and verdict guidance. */
|
|
79
92
|
export declare function ruleViolationMessage(v: RuleViolation): string;
|
|
93
|
+
/** A node that failed type or schema validation. */
|
|
94
|
+
interface NodeValidationFailure {
|
|
95
|
+
node: SpaceNode;
|
|
96
|
+
issues: FormattedError[];
|
|
97
|
+
}
|
|
98
|
+
/** The outcome of validating a set of nodes, before either view shapes it. */
|
|
99
|
+
export interface SpaceValidationResult {
|
|
100
|
+
validCount: number;
|
|
101
|
+
nodeFailures: NodeValidationFailure[];
|
|
102
|
+
refErrors: ValidationResult['refErrors'];
|
|
103
|
+
duplicateErrors: ValidationResult['duplicateErrors'];
|
|
104
|
+
ruleViolations: RuleViolation[];
|
|
105
|
+
hierarchyViolations: GraphViolation[];
|
|
106
|
+
orphans: SpaceNode[];
|
|
107
|
+
unresolvedContentLinks: ValidationResult['unresolvedContentLinks'];
|
|
108
|
+
coverageGates: CoverageGate[];
|
|
109
|
+
contextTrimmed: ValidationResult['contextTrimmed'];
|
|
110
|
+
}
|
|
80
111
|
/**
|
|
81
112
|
* Nodes that share an id, with where each is defined. A plugin should keep ids unique, so this guards that contract.
|
|
82
113
|
* Display titles may repeat.
|
|
83
114
|
*/
|
|
84
115
|
export declare function findDuplicateIds(nodes: SpaceNode[]): ValidationResult['duplicateErrors'];
|
|
116
|
+
/**
|
|
117
|
+
* The one validation pipeline: type and schema checks, duplicate titles, reference and hierarchy
|
|
118
|
+
* checks, cascade-gated rules, and unresolved content links. Returns every entry; `validateSpace`
|
|
119
|
+
* and `validateFile` are views over it, so a file's results match its entry in a full run.
|
|
120
|
+
* `judgeTarget` limits judging to one file (and the ancestors that can gate it).
|
|
121
|
+
*/
|
|
122
|
+
export declare function validateNodes(context: SpaceContext, nodes: SpaceNode[], unresolvedRefs: ReadSpaceResult['unresolvedRefs'], options?: RunOptions): Promise<SpaceValidationResult>;
|
|
85
123
|
/**
|
|
86
124
|
* Run full validation on a space and return a structured result.
|
|
87
125
|
* Does not output to console or call process.exit.
|
|
@@ -92,14 +130,8 @@ export declare function resolveFileSpace(filePath: string, config: Config): {
|
|
|
92
130
|
space: SpaceConfig;
|
|
93
131
|
label: string;
|
|
94
132
|
} | null;
|
|
95
|
-
export interface ValidateFileOptions {
|
|
133
|
+
export interface ValidateFileOptions extends CommonValidateOptions {
|
|
96
134
|
configDir?: string;
|
|
97
|
-
/** Evaluate rules on gated nodes anyway (gates are still reported). */
|
|
98
|
-
includeGated?: boolean;
|
|
99
|
-
/** Evaluate only rules matching this filter (see `parseRuleFilter`). */
|
|
100
|
-
ruleFilter?: RuleFilter;
|
|
101
|
-
/** Evaluates `semantic` rules. Without one, a rule runs only its `expression`, and a semantic-only rule is skipped. */
|
|
102
|
-
judge?: SemanticJudgeProvider;
|
|
103
135
|
}
|
|
104
136
|
/** The result for a file that belongs to no configured space. */
|
|
105
137
|
export declare function fileNotInSpace(filePath: string): FileNotInSpaceResult;
|
|
@@ -108,6 +140,8 @@ export declare function fileNotInSpace(filePath: string): FileNotInSpaceResult;
|
|
|
108
140
|
* correctness), judging only the file, then selects the file's issues from the result.
|
|
109
141
|
*/
|
|
110
142
|
export declare function validateResolvedFile(filePath: string, label: string, context: SpaceContext, options?: Omit<ValidateFileOptions, 'configDir'>): Promise<FileValidationResult>;
|
|
143
|
+
/** `validateResolvedFile` with the options already resolved, so a caller can supply its own judge. */
|
|
144
|
+
export declare function validateResolvedFileWith(filePath: string, label: string, context: SpaceContext, runOptions: RunOptions): Promise<FileValidationResult>;
|
|
111
145
|
/**
|
|
112
146
|
* Validate a single file within its space.
|
|
113
147
|
*
|
|
@@ -118,3 +152,4 @@ export declare function validateResolvedFile(filePath: string, label: string, co
|
|
|
118
152
|
* If the file is not in any configured space, returns a result with `inSpace: false`.
|
|
119
153
|
*/
|
|
120
154
|
export declare function validateFile(filePath: string, config: Config, options?: ValidateFileOptions): Promise<ValidateFileOutput>;
|
|
155
|
+
export {};
|
package/dist/validate.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { isAbsolute, relative, resolve } from 'node:path';
|
|
2
|
+
import { judgeForRun } from './judge/factory';
|
|
2
3
|
import { readSpace } from './read/read-space';
|
|
3
4
|
import { computeHierarchyDepths, evaluateRulesWithGating } from './schema/gating';
|
|
4
|
-
import { filterRules } from './schema/rule-filter';
|
|
5
|
-
import { extractEntityInfo } from './schema/schema';
|
|
5
|
+
import { filterRules, parseRuleFilter } from './schema/rule-filter';
|
|
6
|
+
import { extractEntityInfo, typeValidatorFor } from './schema/schema';
|
|
6
7
|
import { validateGraph } from './schema/validate-graph';
|
|
7
8
|
import { validateRules } from './schema/validate-rules';
|
|
8
9
|
import { createSpaceContext } from './space-context';
|
|
@@ -94,6 +95,14 @@ export function formatErrors(errors, schema, schemaRefRegistry, nodeData) {
|
|
|
94
95
|
}
|
|
95
96
|
return formatted;
|
|
96
97
|
}
|
|
98
|
+
/** Throws `SctxError` `E_MODEL_PROVIDER_INVALID` when `semantic` names a provider that cannot be built. */
|
|
99
|
+
function runOptionsFrom(context, options) {
|
|
100
|
+
return {
|
|
101
|
+
includeGated: options.includeGated,
|
|
102
|
+
ruleFilter: options.ruleFilter && parseRuleFilter(options.ruleFilter),
|
|
103
|
+
judge: judgeForRun(context.config, context.space, options.semantic),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
97
106
|
/** `file`, `file:line` or `file:line:column`, for messages. */
|
|
98
107
|
export function formatSource({ file, line, column }) {
|
|
99
108
|
return line === undefined ? file : `${file}:${line}${column === undefined ? '' : `:${column}`}`;
|
|
@@ -159,7 +168,7 @@ export function findDuplicateIds(nodes) {
|
|
|
159
168
|
* and `validateFile` are views over it, so a file's results match its entry in a full run.
|
|
160
169
|
* `judgeTarget` limits judging to one file (and the ancestors that can gate it).
|
|
161
170
|
*/
|
|
162
|
-
async function validateNodes(context, nodes, unresolvedRefs, options = {}) {
|
|
171
|
+
export async function validateNodes(context, nodes, unresolvedRefs, options = {}) {
|
|
163
172
|
const { schema, schemaRefRegistry, schemaValidator } = context;
|
|
164
173
|
const metadata = schema.metadata;
|
|
165
174
|
// Pre-extract valid types for early type validation
|
|
@@ -177,31 +186,31 @@ async function validateNodes(context, nodes, unresolvedRefs, options = {}) {
|
|
|
177
186
|
contextTrimmed: { nodeCount: 0, ruleIds: [] },
|
|
178
187
|
};
|
|
179
188
|
for (const node of nodes) {
|
|
180
|
-
//
|
|
189
|
+
// Check the type first: an unknown type reports one error instead of one per oneOf branch.
|
|
181
190
|
const nodeType = node.schemaData.type;
|
|
182
191
|
if (nodeType !== undefined && validTypes.length > 0 && !validTypes.includes(nodeType)) {
|
|
183
192
|
const sortedTypes = [...validTypes].sort();
|
|
184
193
|
result.nodeFailures.push({
|
|
185
194
|
node,
|
|
186
|
-
|
|
187
|
-
errors: [
|
|
195
|
+
issues: [
|
|
188
196
|
{
|
|
189
|
-
instancePath: '/type',
|
|
190
|
-
keyword: 'enum',
|
|
191
197
|
message: `Invalid type "${nodeType}". Valid types are: ${sortedTypes.join(', ')}`,
|
|
192
|
-
|
|
193
|
-
schemaPath: '#/oneOf',
|
|
194
|
-
data: nodeType,
|
|
198
|
+
dedupeKey: `type:${sortedTypes.join(',')}`,
|
|
195
199
|
},
|
|
196
200
|
],
|
|
197
201
|
});
|
|
198
202
|
continue;
|
|
199
203
|
}
|
|
200
|
-
|
|
204
|
+
// A valid type is checked against its own branch only, so errors come from that type alone.
|
|
205
|
+
const validate = (nodeType !== undefined && typeValidatorFor(schemaValidator, nodeType)) || schemaValidator;
|
|
206
|
+
if (validate(node.schemaData)) {
|
|
201
207
|
result.validCount++;
|
|
202
208
|
}
|
|
203
209
|
else {
|
|
204
|
-
result.nodeFailures.push({
|
|
210
|
+
result.nodeFailures.push({
|
|
211
|
+
node,
|
|
212
|
+
issues: formatErrors(validate.errors || [], schema, schemaRefRegistry, node.schemaData),
|
|
213
|
+
});
|
|
205
214
|
}
|
|
206
215
|
}
|
|
207
216
|
result.duplicateErrors.push(...findDuplicateIds(nodes));
|
|
@@ -248,6 +257,7 @@ async function validateNodes(context, nodes, unresolvedRefs, options = {}) {
|
|
|
248
257
|
*/
|
|
249
258
|
export async function validateSpace(context, options = {}) {
|
|
250
259
|
const metadata = context.schema.metadata;
|
|
260
|
+
const runOptions = runOptionsFrom(context, options);
|
|
251
261
|
const readResult = options.readResult ?? (await readSpace(context));
|
|
252
262
|
let nodes = readResult.nodes;
|
|
253
263
|
// Depth limiting: evaluate only hierarchy nodes within N breadth-first levels from the
|
|
@@ -268,19 +278,14 @@ export async function validateSpace(context, options = {}) {
|
|
|
268
278
|
}
|
|
269
279
|
nodes = included;
|
|
270
280
|
}
|
|
271
|
-
const result = await validateNodes(context, nodes, readResult.unresolvedRefs,
|
|
272
|
-
includeGated: options.includeGated,
|
|
273
|
-
ruleFilter: options.ruleFilter,
|
|
274
|
-
judge: options.judge,
|
|
275
|
-
});
|
|
281
|
+
const result = await validateNodes(context, nodes, readResult.unresolvedRefs, runOptions);
|
|
276
282
|
return {
|
|
277
283
|
validCount: result.validCount,
|
|
278
284
|
nodeErrorCount: result.nodeFailures.length,
|
|
279
|
-
nodeErrors: result.nodeFailures.map(({ node,
|
|
285
|
+
nodeErrors: result.nodeFailures.map(({ node, issues }) => ({
|
|
280
286
|
nodeId: node.id,
|
|
281
287
|
...(node.source !== undefined && { source: node.source }),
|
|
282
|
-
|
|
283
|
-
nodeData: node.schemaData,
|
|
288
|
+
issues,
|
|
284
289
|
})),
|
|
285
290
|
refErrors: result.refErrors,
|
|
286
291
|
duplicateErrors: result.duplicateErrors,
|
|
@@ -312,27 +317,17 @@ export function resolveFileSpace(filePath, config) {
|
|
|
312
317
|
* Select one file's entries from a space's validation result: issues keyed and formatted, errors split from warnings.
|
|
313
318
|
* Pure — a file's entries are exactly its slice of the result.
|
|
314
319
|
*/
|
|
315
|
-
function issuesForFile(result, label,
|
|
316
|
-
const { schema, schemaRefRegistry } = context;
|
|
320
|
+
function issuesForFile(result, label, includeGated) {
|
|
317
321
|
const errors = {};
|
|
318
322
|
const warnings = {};
|
|
319
|
-
for (const { node,
|
|
323
|
+
for (const { node, issues } of result.nodeFailures) {
|
|
320
324
|
if (node.id !== label)
|
|
321
325
|
continue;
|
|
322
326
|
const position = {
|
|
323
327
|
...(node.source?.line !== undefined ? { line: node.source.line } : {}),
|
|
324
328
|
...(node.source?.column !== undefined ? { column: node.source.column } : {}),
|
|
325
329
|
};
|
|
326
|
-
|
|
327
|
-
errors[`schema:type:${invalidType.validTypes.join(',')}`] = {
|
|
328
|
-
kind: 'schema',
|
|
329
|
-
message: ajvErrors[0].message,
|
|
330
|
-
...position,
|
|
331
|
-
};
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
const formatted = formatErrors(ajvErrors, schema, schemaRefRegistry, node.schemaData);
|
|
335
|
-
for (const { message, dedupeKey } of formatted) {
|
|
330
|
+
for (const { message, dedupeKey } of issues) {
|
|
336
331
|
errors[`schema:${dedupeKey}`] = { kind: 'schema', message, ...position };
|
|
337
332
|
}
|
|
338
333
|
}
|
|
@@ -401,15 +396,17 @@ export function fileNotInSpace(filePath) {
|
|
|
401
396
|
* Validate a file in an already-resolved space. Checks the whole space (required for graph
|
|
402
397
|
* correctness), judging only the file, then selects the file's issues from the result.
|
|
403
398
|
*/
|
|
404
|
-
export
|
|
399
|
+
export function validateResolvedFile(filePath, label, context, options = {}) {
|
|
400
|
+
return validateResolvedFileWith(filePath, label, context, runOptionsFrom(context, options));
|
|
401
|
+
}
|
|
402
|
+
/** `validateResolvedFile` with the options already resolved, so a caller can supply its own judge. */
|
|
403
|
+
export async function validateResolvedFileWith(filePath, label, context, runOptions) {
|
|
405
404
|
const readResult = await readSpace(context);
|
|
406
405
|
const result = await validateNodes(context, readResult.nodes, readResult.unresolvedRefs, {
|
|
407
|
-
|
|
408
|
-
ruleFilter: options.ruleFilter,
|
|
409
|
-
judge: options.judge,
|
|
406
|
+
...runOptions,
|
|
410
407
|
judgeTarget: label,
|
|
411
408
|
});
|
|
412
|
-
const { errors, warnings } = issuesForFile(result, label,
|
|
409
|
+
const { errors, warnings } = issuesForFile(result, label, runOptions.includeGated);
|
|
413
410
|
return {
|
|
414
411
|
file: isAbsolute(filePath) ? filePath : resolve(process.cwd(), filePath),
|
|
415
412
|
label,
|
package/package.json
CHANGED
package/dist/judge/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export { createJudge, createModelProvider, JudgeConfigError } from './factory';
|
|
2
|
-
export { buildJudgeSystemPrompt, buildJudgeUserPrompt, parseJudgeResponse } from './prompt';
|
|
3
|
-
export type { AnthropicJudgeProviderOptions } from './provider/anthropic';
|
|
4
|
-
export { AnthropicJudgeProvider } from './provider/anthropic';
|
|
5
|
-
export type { FakeAnswer, FakeJudgeHandler } from './provider/fake';
|
|
6
|
-
export { FakeJudgeProvider } from './provider/fake';
|
|
7
|
-
export type { JevJudgeProviderOptions } from './provider/jev';
|
|
8
|
-
export { JevJudgeProvider } from './provider/jev';
|
|
9
|
-
export type { OpenAIJudgeProviderOptions } from './provider/openai';
|
|
10
|
-
export { OpenAIJudgeProvider } from './provider/openai';
|
|
11
|
-
export { PerRuleJudgeProvider } from './provider/per-rule';
|
|
12
|
-
export type { JudgeConfig, ModelProviderConfig, SemanticJudgeInput, SemanticJudgeProvider, SemanticJudgeResult, SemanticJudgeVerdict, SemanticRuleSpec, } from './types';
|
|
13
|
-
export { DEFAULT_VERDICTS, isJudgeError, semanticRuleSpec } from './verdicts';
|
package/dist/judge/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { createJudge, createModelProvider, JudgeConfigError } from './factory';
|
|
2
|
-
export { buildJudgeSystemPrompt, buildJudgeUserPrompt, parseJudgeResponse } from './prompt';
|
|
3
|
-
export { AnthropicJudgeProvider } from './provider/anthropic';
|
|
4
|
-
export { FakeJudgeProvider } from './provider/fake';
|
|
5
|
-
export { JevJudgeProvider } from './provider/jev';
|
|
6
|
-
export { OpenAIJudgeProvider } from './provider/openai';
|
|
7
|
-
export { PerRuleJudgeProvider } from './provider/per-rule';
|
|
8
|
-
export { DEFAULT_VERDICTS, isJudgeError, semanticRuleSpec } from './verdicts';
|