@syrin/cli 1.3.2 → 1.4.1
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 +184 -152
- package/dist/cli/commands/config.d.ts +47 -0
- package/dist/cli/commands/config.js +360 -0
- package/dist/cli/commands/dev.d.ts +6 -0
- package/dist/cli/commands/dev.js +67 -15
- package/dist/cli/commands/doctor.js +49 -13
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +89 -18
- package/dist/cli/commands/status.d.ts +10 -0
- package/dist/cli/commands/status.js +162 -0
- package/dist/cli/index.js +211 -12
- package/dist/cli/prompts/init-prompt.d.ts +18 -0
- package/dist/cli/prompts/init-prompt.js +159 -99
- package/dist/cli/utils/command-error-handler.js +2 -5
- package/dist/config/env-checker.d.ts +12 -2
- package/dist/config/env-checker.js +88 -38
- package/dist/config/env-templates.d.ts +15 -0
- package/dist/config/env-templates.js +49 -0
- package/dist/config/generator.js +17 -0
- package/dist/config/global-loader.d.ts +50 -0
- package/dist/config/global-loader.js +244 -0
- package/dist/config/loader.d.ts +28 -0
- package/dist/config/loader.js +95 -9
- package/dist/config/merger.d.ts +37 -0
- package/dist/config/merger.js +68 -0
- package/dist/config/schema.d.ts +26 -1
- package/dist/config/schema.js +73 -8
- package/dist/config/types.d.ts +19 -0
- package/dist/config/types.js +26 -1
- package/dist/constants/messages.d.ts +7 -0
- package/dist/constants/messages.js +8 -0
- package/dist/constants/paths.d.ts +6 -0
- package/dist/constants/paths.js +10 -0
- package/dist/events/emitter.js +7 -7
- package/dist/index.js +0 -0
- package/dist/presentation/config-ui.d.ts +34 -0
- package/dist/presentation/config-ui.js +139 -0
- package/dist/presentation/doctor-ui.d.ts +11 -0
- package/dist/presentation/doctor-ui.js +52 -1
- package/dist/presentation/init-ui.d.ts +9 -0
- package/dist/presentation/init-ui.js +33 -0
- package/dist/runtime/analysis/analyser.js +2 -2
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +1 -1
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +1 -1
- package/dist/runtime/dev/event-mapper.js +19 -3
- package/dist/runtime/dev/session.d.ts +4 -0
- package/dist/runtime/dev/session.js +52 -3
- package/dist/runtime/llm/ollama.js +4 -4
- package/dist/runtime/mcp/client/manager.js +3 -3
- package/dist/runtime/sandbox/executor.js +5 -5
- package/dist/runtime/test/orchestrator.js +4 -4
- package/dist/utils/editor.d.ts +37 -0
- package/dist/utils/editor.js +137 -0
- package/dist/utils/logger.d.ts +24 -6
- package/dist/utils/logger.js +51 -8
- package/package.json +23 -23
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +0 -22
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +0 -30
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +0 -24
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +0 -52
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +0 -23
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +0 -73
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +0 -23
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +0 -47
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +0 -25
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +0 -73
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +0 -22
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +0 -57
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +0 -23
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +0 -56
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +0 -22
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +0 -84
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +0 -23
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +0 -89
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +0 -25
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +0 -46
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +0 -24
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +0 -33
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +0 -39
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +0 -40
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +0 -37
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +0 -34
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +0 -39
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +0 -36
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +0 -42
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +0 -46
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +0 -39
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +0 -36
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +0 -42
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +0 -46
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +0 -44
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +0 -66
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +0 -43
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +0 -42
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +0 -44
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +0 -66
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +0 -57
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +0 -80
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +0 -43
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +0 -42
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +0 -57
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +0 -80
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +0 -38
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +0 -37
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +0 -38
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +0 -37
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +0 -65
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +0 -109
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +0 -65
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +0 -109
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +0 -22
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +0 -39
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +0 -24
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +0 -40
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +0 -22
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +0 -84
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +0 -23
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +0 -96
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +0 -53
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +0 -108
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +0 -22
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +0 -44
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +0 -23
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +0 -37
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +0 -22
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +0 -97
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +0 -23
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +0 -88
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +0 -22
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +0 -81
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +0 -40
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +0 -32
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +0 -39
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +0 -36
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +0 -38
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +0 -36
- package/dist/runtime/test/dependency-tracker.d.ts +0 -66
- package/dist/runtime/test/dependency-tracker.js +0 -80
- package/dist/runtime/test/formatters.d.ts +0 -18
- package/dist/runtime/test/formatters.js +0 -172
- package/dist/runtime/test/input-generator.d.ts +0 -33
- package/dist/runtime/test/input-generator.js +0 -498
- package/dist/runtime/test/mcp-root-detector.d.ts +0 -31
- package/dist/runtime/test/mcp-root-detector.js +0 -105
- package/dist/runtime/test/retry-tester.d.ts +0 -44
- package/dist/runtime/test/retry-tester.js +0 -103
- package/dist/runtime/test/synthetic-input-generator.d.ts +0 -11
- package/dist/runtime/test/synthetic-input-generator.js +0 -154
- package/dist/runtime/test/test-runner.d.ts +0 -28
- package/dist/runtime/test/test-runner.js +0 -55
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E008: Circular Tool Dependency
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool dependency graph contains a cycle
|
|
6
|
-
*
|
|
7
|
-
* Why:
|
|
8
|
-
* - LLMs cannot reason about cycles
|
|
9
|
-
* - Execution becomes undefined
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
13
|
-
declare class E008CircularDependencyRule extends BaseRule {
|
|
14
|
-
readonly id: "E008";
|
|
15
|
-
readonly severity: "error";
|
|
16
|
-
readonly ruleName = "Circular Tool Dependency";
|
|
17
|
-
readonly description = "Circular dependency detected between tools. Execution becomes undefined.";
|
|
18
|
-
check(ctx: AnalysisContext): Diagnostic[];
|
|
19
|
-
}
|
|
20
|
-
export declare const E008CircularDependency: E008CircularDependencyRule;
|
|
21
|
-
export {};
|
|
22
|
-
//# sourceMappingURL=e008-circular-dependency.d.ts.map
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E008: Circular Tool Dependency
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool dependency graph contains a cycle
|
|
6
|
-
*
|
|
7
|
-
* Why:
|
|
8
|
-
* - LLMs cannot reason about cycles
|
|
9
|
-
* - Execution becomes undefined
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
13
|
-
/**
|
|
14
|
-
* Detect cycles in the dependency graph using DFS.
|
|
15
|
-
*/
|
|
16
|
-
function detectCycles(dependencies) {
|
|
17
|
-
// Build adjacency list
|
|
18
|
-
const graph = new Map();
|
|
19
|
-
for (const dep of dependencies) {
|
|
20
|
-
if (!graph.has(dep.fromTool)) {
|
|
21
|
-
graph.set(dep.fromTool, []);
|
|
22
|
-
}
|
|
23
|
-
graph.get(dep.fromTool).push(dep.toTool);
|
|
24
|
-
}
|
|
25
|
-
const cycles = [];
|
|
26
|
-
const visited = new Set();
|
|
27
|
-
const recStack = new Set();
|
|
28
|
-
function dfs(tool, path) {
|
|
29
|
-
visited.add(tool);
|
|
30
|
-
recStack.add(tool);
|
|
31
|
-
path.push(tool);
|
|
32
|
-
const neighbors = graph.get(tool) || [];
|
|
33
|
-
for (const neighbor of neighbors) {
|
|
34
|
-
if (!visited.has(neighbor)) {
|
|
35
|
-
dfs(neighbor, [...path]);
|
|
36
|
-
}
|
|
37
|
-
else if (recStack.has(neighbor)) {
|
|
38
|
-
// Found a cycle
|
|
39
|
-
const cycleStart = path.indexOf(neighbor);
|
|
40
|
-
if (cycleStart !== -1) {
|
|
41
|
-
cycles.push([...path.slice(cycleStart), neighbor]);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
recStack.delete(tool);
|
|
46
|
-
}
|
|
47
|
-
// Check all tools
|
|
48
|
-
for (const dep of dependencies) {
|
|
49
|
-
if (!visited.has(dep.fromTool)) {
|
|
50
|
-
dfs(dep.fromTool, []);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return cycles;
|
|
54
|
-
}
|
|
55
|
-
class E008CircularDependencyRule extends BaseRule {
|
|
56
|
-
id = ERROR_CODES.E008;
|
|
57
|
-
severity = 'error';
|
|
58
|
-
ruleName = 'Circular Tool Dependency';
|
|
59
|
-
description = 'Circular dependency detected between tools. Execution becomes undefined.';
|
|
60
|
-
check(ctx) {
|
|
61
|
-
const diagnostics = [];
|
|
62
|
-
// Only check high-confidence dependencies (>= 0.8) for cycles
|
|
63
|
-
const highConfidenceDeps = ctx.dependencies.filter(d => d.confidence >= 0.8);
|
|
64
|
-
if (highConfidenceDeps.length === 0) {
|
|
65
|
-
return diagnostics;
|
|
66
|
-
}
|
|
67
|
-
const cycles = detectCycles(highConfidenceDeps);
|
|
68
|
-
// Report each cycle
|
|
69
|
-
const reportedCycles = new Set();
|
|
70
|
-
for (const cycle of cycles) {
|
|
71
|
-
// Create a canonical representation of the cycle (sort a copy to avoid mutating original)
|
|
72
|
-
const cycleKey = [...cycle].sort().join(' → ');
|
|
73
|
-
if (reportedCycles.has(cycleKey)) {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
reportedCycles.add(cycleKey);
|
|
77
|
-
const cycleStr = cycle.join(' → ');
|
|
78
|
-
diagnostics.push(this.createDiagnostic(`Circular dependency detected between tools: ${cycleStr}.`, undefined, undefined, `Break the cycle by removing or restructuring dependencies between: ${cycle.join(', ')}.`));
|
|
79
|
-
}
|
|
80
|
-
return diagnostics;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
export const E008CircularDependency = new E008CircularDependencyRule();
|
|
84
|
-
//# sourceMappingURL=e008-circular-dependency.js.map
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E009: Tool Depends on User Input Indirectly
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool expects data
|
|
6
|
-
* - Only source is implicit user memory / conversation
|
|
7
|
-
* - No explicit tool provides it
|
|
8
|
-
*
|
|
9
|
-
* Why:
|
|
10
|
-
* - Relies on hallucinated context
|
|
11
|
-
*/
|
|
12
|
-
import { BaseRule } from '../base.js';
|
|
13
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
14
|
-
declare class E009ImplicitUserInputRule extends BaseRule {
|
|
15
|
-
readonly id: "E009";
|
|
16
|
-
readonly severity: "error";
|
|
17
|
-
readonly ruleName = "Tool Depends on User Input Indirectly";
|
|
18
|
-
readonly description = "Tool depends on implicit user context with no explicit source.";
|
|
19
|
-
check(ctx: AnalysisContext): Diagnostic[];
|
|
20
|
-
}
|
|
21
|
-
export declare const E009ImplicitUserInput: E009ImplicitUserInputRule;
|
|
22
|
-
export {};
|
|
23
|
-
//# sourceMappingURL=e009-implicit-user-input.d.ts.map
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E009: Tool Depends on User Input Indirectly
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool expects data
|
|
6
|
-
* - Only source is implicit user memory / conversation
|
|
7
|
-
* - No explicit tool provides it
|
|
8
|
-
*
|
|
9
|
-
* Why:
|
|
10
|
-
* - Relies on hallucinated context
|
|
11
|
-
*/
|
|
12
|
-
import { BaseRule } from '../base.js';
|
|
13
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
14
|
-
class E009ImplicitUserInputRule extends BaseRule {
|
|
15
|
-
id = ERROR_CODES.E009;
|
|
16
|
-
severity = 'error';
|
|
17
|
-
ruleName = 'Tool Depends on User Input Indirectly';
|
|
18
|
-
description = 'Tool depends on implicit user context with no explicit source.';
|
|
19
|
-
check(ctx) {
|
|
20
|
-
const diagnostics = [];
|
|
21
|
-
for (const tool of ctx.tools) {
|
|
22
|
-
for (const input of tool.inputs) {
|
|
23
|
-
if (!input.required) {
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
// Check if there's any tool that provides this input
|
|
27
|
-
// Look for output fields with similar names
|
|
28
|
-
const fieldName = input.name.toLowerCase();
|
|
29
|
-
let hasExplicitSource = false;
|
|
30
|
-
for (const otherTool of ctx.tools) {
|
|
31
|
-
if (otherTool.name === tool.name) {
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
for (const output of otherTool.outputs) {
|
|
35
|
-
const outputName = output.name.toLowerCase();
|
|
36
|
-
// Check for exact match or token-based match
|
|
37
|
-
if (outputName === fieldName) {
|
|
38
|
-
hasExplicitSource = true;
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
// Token-based matching: split on non-alphanumeric and camelCase boundaries
|
|
42
|
-
const fieldTokens = new Set(fieldName
|
|
43
|
-
.split(/[^\w]+|(?<=[a-z])(?=[A-Z])/)
|
|
44
|
-
.filter(t => t.length > 0));
|
|
45
|
-
const outputTokens = new Set(outputName
|
|
46
|
-
.split(/[^\w]+|(?<=[a-z])(?=[A-Z])/)
|
|
47
|
-
.filter(t => t.length > 0));
|
|
48
|
-
// Check for token intersection
|
|
49
|
-
const hasTokenMatch = Array.from(fieldTokens).some(token => outputTokens.has(token) && token.length >= 3) ||
|
|
50
|
-
Array.from(outputTokens).some(token => fieldTokens.has(token) && token.length >= 3);
|
|
51
|
-
if (hasTokenMatch) {
|
|
52
|
-
hasExplicitSource = true;
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (hasExplicitSource) {
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Also check dependencies
|
|
61
|
-
if (!hasExplicitSource) {
|
|
62
|
-
const hasDependency = ctx.dependencies.some(d => d.toTool === tool.name &&
|
|
63
|
-
d.toField === input.name &&
|
|
64
|
-
d.confidence >= 0.6);
|
|
65
|
-
if (hasDependency) {
|
|
66
|
-
hasExplicitSource = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// If no explicit source found and input name suggests user data
|
|
70
|
-
const userDataIndicators = [
|
|
71
|
-
'user',
|
|
72
|
-
'person',
|
|
73
|
-
'name',
|
|
74
|
-
'email',
|
|
75
|
-
'location',
|
|
76
|
-
'address',
|
|
77
|
-
'preference',
|
|
78
|
-
];
|
|
79
|
-
const looksLikeUserData = userDataIndicators.some(indicator => fieldName.includes(indicator));
|
|
80
|
-
if (!hasExplicitSource && looksLikeUserData) {
|
|
81
|
-
diagnostics.push(this.createDiagnostic(`Tool "${tool.name}" depends on implicit user context (parameter: "${input.name}") with no explicit source.`, tool.name, input.name, `Create an explicit tool to provide "${input.name}", or ensure it's clearly documented as user input.`));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return diagnostics;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
export const E009ImplicitUserInput = new E009ImplicitUserInputRule();
|
|
89
|
-
//# sourceMappingURL=e009-implicit-user-input.js.map
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E010: Non-Serializable Output
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Output schema contains:
|
|
6
|
-
* - functions
|
|
7
|
-
* - class instances
|
|
8
|
-
* - unsupported types
|
|
9
|
-
*
|
|
10
|
-
* Why:
|
|
11
|
-
* - Breaks MCP contract
|
|
12
|
-
* - Breaks recording & replay later
|
|
13
|
-
*/
|
|
14
|
-
import { BaseRule } from '../base.js';
|
|
15
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
16
|
-
declare class E010NonSerializableRule extends BaseRule {
|
|
17
|
-
readonly id: "E010";
|
|
18
|
-
readonly severity: "error";
|
|
19
|
-
readonly ruleName = "Non-Serializable Output";
|
|
20
|
-
readonly description = "Output of tool is not serializable. Breaks MCP contract.";
|
|
21
|
-
check(ctx: AnalysisContext): Diagnostic[];
|
|
22
|
-
}
|
|
23
|
-
export declare const E010NonSerializable: E010NonSerializableRule;
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=e010-non-serializable.d.ts.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E010: Non-Serializable Output
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Output schema contains:
|
|
6
|
-
* - functions
|
|
7
|
-
* - class instances
|
|
8
|
-
* - unsupported types
|
|
9
|
-
*
|
|
10
|
-
* Why:
|
|
11
|
-
* - Breaks MCP contract
|
|
12
|
-
* - Breaks recording & replay later
|
|
13
|
-
*/
|
|
14
|
-
import { BaseRule } from '../base.js';
|
|
15
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
16
|
-
/**
|
|
17
|
-
* Check if a type is non-serializable.
|
|
18
|
-
*/
|
|
19
|
-
function isNonSerializableType(type) {
|
|
20
|
-
const nonSerializableTypes = new Set([
|
|
21
|
-
'function',
|
|
22
|
-
'undefined',
|
|
23
|
-
'symbol',
|
|
24
|
-
'bigint',
|
|
25
|
-
]);
|
|
26
|
-
return nonSerializableTypes.has(type.toLowerCase());
|
|
27
|
-
}
|
|
28
|
-
class E010NonSerializableRule extends BaseRule {
|
|
29
|
-
id = ERROR_CODES.E010;
|
|
30
|
-
severity = 'error';
|
|
31
|
-
ruleName = 'Non-Serializable Output';
|
|
32
|
-
description = 'Output of tool is not serializable. Breaks MCP contract.';
|
|
33
|
-
check(ctx) {
|
|
34
|
-
const diagnostics = [];
|
|
35
|
-
for (const tool of ctx.tools) {
|
|
36
|
-
for (const output of tool.outputs) {
|
|
37
|
-
if (isNonSerializableType(output.type)) {
|
|
38
|
-
diagnostics.push(this.createDiagnostic(`Output of "${tool.name}" (field: "${output.name}") has non-serializable type "${output.type}".`, tool.name, output.name, `Change the output type to a serializable type (string, number, boolean, object, array).`));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return diagnostics;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export const E010NonSerializable = new E010NonSerializableRule();
|
|
46
|
-
//# sourceMappingURL=e010-non-serializable.js.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E011: Missing Tool Description
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool has no description OR
|
|
6
|
-
* - Tool description is empty or only whitespace
|
|
7
|
-
*
|
|
8
|
-
* Why:
|
|
9
|
-
* - LLM cannot understand what the tool does
|
|
10
|
-
* - Tool selection becomes ambiguous
|
|
11
|
-
* - Critical for tool discovery and usage
|
|
12
|
-
*/
|
|
13
|
-
import { BaseRule } from '../base.js';
|
|
14
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
15
|
-
declare class E011MissingToolDescriptionRule extends BaseRule {
|
|
16
|
-
readonly id: "E011";
|
|
17
|
-
readonly severity: "error";
|
|
18
|
-
readonly ruleName = "Missing Tool Description";
|
|
19
|
-
readonly description = "Tool is missing a description. LLM cannot understand what the tool does.";
|
|
20
|
-
check(ctx: AnalysisContext): Diagnostic[];
|
|
21
|
-
}
|
|
22
|
-
export declare const E011MissingToolDescription: E011MissingToolDescriptionRule;
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=e011-missing-tool-description.d.ts.map
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E011: Missing Tool Description
|
|
3
|
-
*
|
|
4
|
-
* Condition:
|
|
5
|
-
* - Tool has no description OR
|
|
6
|
-
* - Tool description is empty or only whitespace
|
|
7
|
-
*
|
|
8
|
-
* Why:
|
|
9
|
-
* - LLM cannot understand what the tool does
|
|
10
|
-
* - Tool selection becomes ambiguous
|
|
11
|
-
* - Critical for tool discovery and usage
|
|
12
|
-
*/
|
|
13
|
-
import { BaseRule } from '../base.js';
|
|
14
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
15
|
-
class E011MissingToolDescriptionRule extends BaseRule {
|
|
16
|
-
id = ERROR_CODES.E011;
|
|
17
|
-
severity = 'error';
|
|
18
|
-
ruleName = 'Missing Tool Description';
|
|
19
|
-
description = 'Tool is missing a description. LLM cannot understand what the tool does.';
|
|
20
|
-
check(ctx) {
|
|
21
|
-
const diagnostics = [];
|
|
22
|
-
for (const tool of ctx.tools) {
|
|
23
|
-
// Check if description is missing or empty/whitespace only
|
|
24
|
-
const hasDescription = Boolean(tool.description && tool.description.trim().length > 0);
|
|
25
|
-
if (!hasDescription) {
|
|
26
|
-
diagnostics.push(this.createDiagnostic(`Tool "${tool.name}" is missing a description.`, tool.name, undefined, `Add a clear description to "${tool.name}" explaining what it does, what inputs it expects, and what it returns.`));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return diagnostics;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export const E011MissingToolDescription = new E011MissingToolDescriptionRule();
|
|
33
|
-
//# sourceMappingURL=e011-missing-tool-description.js.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E012: Side Effect Detected
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool attempts filesystem writes to project files (not temp directory)
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Tools should not mutate project state
|
|
8
|
-
* - Breaks isolation and testability
|
|
9
|
-
* - Makes behavior unpredictable
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Context for behavioral validation results.
|
|
15
|
-
* This extends the static analysis context with runtime observation data.
|
|
16
|
-
*/
|
|
17
|
-
export interface BehavioralContext {
|
|
18
|
-
/** Tool name */
|
|
19
|
-
toolName: string;
|
|
20
|
-
/** Side effects detected */
|
|
21
|
-
sideEffects: Array<{
|
|
22
|
-
operation: string;
|
|
23
|
-
path: string;
|
|
24
|
-
}>;
|
|
25
|
-
}
|
|
26
|
-
declare class E012SideEffectDetectedRule extends BaseRule {
|
|
27
|
-
readonly id: "E012";
|
|
28
|
-
readonly severity: "error";
|
|
29
|
-
readonly ruleName = "Side Effect Detected";
|
|
30
|
-
readonly description = "Tool attempted filesystem write to project files. Tools should not mutate project state.";
|
|
31
|
-
check(_ctx: AnalysisContext): Diagnostic[];
|
|
32
|
-
/**
|
|
33
|
-
* Check with behavioral context (called from test orchestrator).
|
|
34
|
-
*/
|
|
35
|
-
checkWithBehavioralContext(behavioralCtx: BehavioralContext): Diagnostic[];
|
|
36
|
-
}
|
|
37
|
-
export declare const E012SideEffectDetected: E012SideEffectDetectedRule;
|
|
38
|
-
export {};
|
|
39
|
-
//# sourceMappingURL=e012-side-effect-detected.d.ts.map
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E012: Side Effect Detected
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool attempts filesystem writes to project files (not temp directory)
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Tools should not mutate project state
|
|
8
|
-
* - Breaks isolation and testability
|
|
9
|
-
* - Makes behavior unpredictable
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
13
|
-
class E012SideEffectDetectedRule extends BaseRule {
|
|
14
|
-
id = ERROR_CODES.E012;
|
|
15
|
-
severity = 'error';
|
|
16
|
-
ruleName = 'Side Effect Detected';
|
|
17
|
-
description = 'Tool attempted filesystem write to project files. Tools should not mutate project state.';
|
|
18
|
-
check(_ctx) {
|
|
19
|
-
const diagnostics = [];
|
|
20
|
-
// This rule requires behavioral context (from runtime testing)
|
|
21
|
-
// It will be called with behavioral data from the test orchestrator
|
|
22
|
-
// For now, return empty - actual checking happens in test orchestrator
|
|
23
|
-
return diagnostics;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Check with behavioral context (called from test orchestrator).
|
|
27
|
-
*/
|
|
28
|
-
checkWithBehavioralContext(behavioralCtx) {
|
|
29
|
-
const diagnostics = [];
|
|
30
|
-
if (behavioralCtx.sideEffects.length > 0) {
|
|
31
|
-
const sideEffectList = behavioralCtx.sideEffects
|
|
32
|
-
.map(se => ` - ${se.operation}: ${se.path}`)
|
|
33
|
-
.join('\n');
|
|
34
|
-
diagnostics.push(this.createDiagnostic(`Tool "${behavioralCtx.toolName}" attempted filesystem operations on project files:\n${sideEffectList}`, behavioralCtx.toolName, undefined, 'Remove filesystem writes or write only to temp directory. Tools should not mutate project state.'));
|
|
35
|
-
}
|
|
36
|
-
return diagnostics;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export const E012SideEffectDetected = new E012SideEffectDetectedRule();
|
|
40
|
-
//# sourceMappingURL=e012-side-effect-detected.js.map
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E013: Non-Deterministic Output
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool produces different outputs for the same input across multiple runs
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Breaks agent reliability
|
|
8
|
-
* - Makes testing impossible
|
|
9
|
-
* - LLM cannot reason about tool behavior
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Context for non-determinism detection.
|
|
15
|
-
*/
|
|
16
|
-
export interface NonDeterminismContext {
|
|
17
|
-
/** Tool name */
|
|
18
|
-
toolName: string;
|
|
19
|
-
/** Number of runs that produced different outputs */
|
|
20
|
-
differentRuns: number;
|
|
21
|
-
/** Total number of runs */
|
|
22
|
-
totalRuns: number;
|
|
23
|
-
}
|
|
24
|
-
declare class E013NonDeterministicOutputRule extends BaseRule {
|
|
25
|
-
readonly id: any;
|
|
26
|
-
readonly severity: "error";
|
|
27
|
-
readonly ruleName = "Non-Deterministic Output";
|
|
28
|
-
readonly description = "Tool produces different outputs for the same input across multiple runs. This breaks agent reliability.";
|
|
29
|
-
check(_ctx: AnalysisContext): Diagnostic[];
|
|
30
|
-
/**
|
|
31
|
-
* Check with behavioral context (called from test orchestrator).
|
|
32
|
-
*/
|
|
33
|
-
checkWithBehavioralContext(behavioralCtx: NonDeterminismContext): Diagnostic[];
|
|
34
|
-
}
|
|
35
|
-
export declare const E013NonDeterministicOutput: E013NonDeterministicOutputRule;
|
|
36
|
-
export {};
|
|
37
|
-
//# sourceMappingURL=e013-non-deterministic-output.d.ts.map
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E013: Non-Deterministic Output
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool produces different outputs for the same input across multiple runs
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Breaks agent reliability
|
|
8
|
-
* - Makes testing impossible
|
|
9
|
-
* - LLM cannot reason about tool behavior
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
13
|
-
class E013NonDeterministicOutputRule extends BaseRule {
|
|
14
|
-
id = ERROR_CODES.E013;
|
|
15
|
-
severity = 'error';
|
|
16
|
-
ruleName = 'Non-Deterministic Output';
|
|
17
|
-
description = 'Tool produces different outputs for the same input across multiple runs. This breaks agent reliability.';
|
|
18
|
-
check(_ctx) {
|
|
19
|
-
// This rule requires behavioral context
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Check with behavioral context (called from test orchestrator).
|
|
24
|
-
*/
|
|
25
|
-
checkWithBehavioralContext(behavioralCtx) {
|
|
26
|
-
const diagnostics = [];
|
|
27
|
-
if (behavioralCtx.differentRuns > 0) {
|
|
28
|
-
diagnostics.push(this.createDiagnostic(`Tool "${behavioralCtx.toolName}" produced different outputs across ${behavioralCtx.totalRuns} runs. ${behavioralCtx.differentRuns} run(s) produced different results.`, behavioralCtx.toolName, undefined, 'Ensure tool produces consistent outputs for the same input. Remove sources of non-determinism (random values, timestamps, etc.).'));
|
|
29
|
-
}
|
|
30
|
-
return diagnostics;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export const E013NonDeterministicOutput = new E013NonDeterministicOutputRule();
|
|
34
|
-
//# sourceMappingURL=e013-non-deterministic-output.js.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E013: Output Explosion
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool output exceeds declared size limit
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Large outputs overwhelm LLM context
|
|
8
|
-
* - Breaks agent reasoning
|
|
9
|
-
* - Indicates design issue (pagination, filtering needed)
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Context for output size validation.
|
|
15
|
-
*/
|
|
16
|
-
export interface OutputSizeContext {
|
|
17
|
-
/** Tool name */
|
|
18
|
-
toolName: string;
|
|
19
|
-
/** Actual output size in bytes */
|
|
20
|
-
actualSize: number;
|
|
21
|
-
/** Maximum allowed size in bytes */
|
|
22
|
-
maxSize: number;
|
|
23
|
-
/** Size limit string from contract (e.g., "50kb") */
|
|
24
|
-
limitString: string;
|
|
25
|
-
}
|
|
26
|
-
declare class E013OutputExplosionRule extends BaseRule {
|
|
27
|
-
readonly id: "E013";
|
|
28
|
-
readonly severity: "error";
|
|
29
|
-
readonly ruleName = "Output Explosion";
|
|
30
|
-
readonly description = "Tool output exceeds declared size limit. Large outputs overwhelm LLM context and break agent reasoning.";
|
|
31
|
-
check(_ctx: AnalysisContext): Diagnostic[];
|
|
32
|
-
/**
|
|
33
|
-
* Check with behavioral context (called from test orchestrator).
|
|
34
|
-
*/
|
|
35
|
-
checkWithBehavioralContext(behavioralCtx: OutputSizeContext): Diagnostic[];
|
|
36
|
-
}
|
|
37
|
-
export declare const E013OutputExplosion: E013OutputExplosionRule;
|
|
38
|
-
export {};
|
|
39
|
-
//# sourceMappingURL=e013-output-explosion.d.ts.map
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E013: Output Explosion
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool output exceeds declared size limit
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Large outputs overwhelm LLM context
|
|
8
|
-
* - Breaks agent reasoning
|
|
9
|
-
* - Indicates design issue (pagination, filtering needed)
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
13
|
-
class E013OutputExplosionRule extends BaseRule {
|
|
14
|
-
id = ERROR_CODES.E013;
|
|
15
|
-
severity = 'error';
|
|
16
|
-
ruleName = 'Output Explosion';
|
|
17
|
-
description = 'Tool output exceeds declared size limit. Large outputs overwhelm LLM context and break agent reasoning.';
|
|
18
|
-
check(_ctx) {
|
|
19
|
-
// This rule requires behavioral context
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Check with behavioral context (called from test orchestrator).
|
|
24
|
-
*/
|
|
25
|
-
checkWithBehavioralContext(behavioralCtx) {
|
|
26
|
-
const diagnostics = [];
|
|
27
|
-
if (behavioralCtx.actualSize > behavioralCtx.maxSize) {
|
|
28
|
-
const actualSizeKB = (behavioralCtx.actualSize / 1024).toFixed(2);
|
|
29
|
-
const maxSizeKB = (behavioralCtx.maxSize / 1024).toFixed(2);
|
|
30
|
-
diagnostics.push(this.createDiagnostic(`Tool "${behavioralCtx.toolName}" returned ${actualSizeKB}KB, exceeding declared limit of ${behavioralCtx.limitString} (${maxSizeKB}KB).`, behavioralCtx.toolName, undefined, `Reduce output size by: paginating results, adding filters, or updating contract limit if legitimate (max_output_size: ${Math.ceil(behavioralCtx.actualSize / 1024)}kb).`));
|
|
31
|
-
}
|
|
32
|
-
return diagnostics;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
export const E013OutputExplosion = new E013OutputExplosionRule();
|
|
36
|
-
//# sourceMappingURL=e013-output-explosion.js.map
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E014: Hidden Dependency
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool calls other tools during execution without declaring them in contract
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Breaks isolation assumption
|
|
8
|
-
* - Creates hidden coupling
|
|
9
|
-
* - Makes tool behavior unpredictable
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import type { AnalysisContext, Diagnostic } from '../../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Context for hidden dependency detection.
|
|
15
|
-
*/
|
|
16
|
-
export interface HiddenDependencyContext {
|
|
17
|
-
/** Tool name */
|
|
18
|
-
toolName: string;
|
|
19
|
-
/** List of tool calls that are not declared */
|
|
20
|
-
hiddenDependencies: Array<{
|
|
21
|
-
toolName: string;
|
|
22
|
-
timestamp: number;
|
|
23
|
-
}>;
|
|
24
|
-
/** List of declared dependencies that don't exist in the MCP server */
|
|
25
|
-
missingDependencies?: string[];
|
|
26
|
-
/** Declared dependencies from contract — reserved for future validation/consumer use */
|
|
27
|
-
declaredDependencies: string[];
|
|
28
|
-
}
|
|
29
|
-
declare class E014HiddenDependencyRule extends BaseRule {
|
|
30
|
-
readonly id: "E014";
|
|
31
|
-
readonly severity: "error";
|
|
32
|
-
readonly ruleName = "Hidden Dependency";
|
|
33
|
-
readonly description = "Tool calls other tools during execution without declaring them in contract. This breaks isolation.";
|
|
34
|
-
check(_ctx: AnalysisContext): Diagnostic[];
|
|
35
|
-
/**
|
|
36
|
-
* Check with behavioral context (called from test orchestrator).
|
|
37
|
-
*/
|
|
38
|
-
checkWithBehavioralContext(behavioralCtx: HiddenDependencyContext): Diagnostic[];
|
|
39
|
-
}
|
|
40
|
-
export declare const E014HiddenDependency: E014HiddenDependencyRule;
|
|
41
|
-
export {};
|
|
42
|
-
//# sourceMappingURL=e014-hidden-dependency.d.ts.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E014: Hidden Dependency
|
|
3
|
-
*
|
|
4
|
-
* Condition: Tool calls other tools during execution without declaring them in contract
|
|
5
|
-
*
|
|
6
|
-
* Why this is fatal:
|
|
7
|
-
* - Breaks isolation assumption
|
|
8
|
-
* - Creates hidden coupling
|
|
9
|
-
* - Makes tool behavior unpredictable
|
|
10
|
-
*/
|
|
11
|
-
import { BaseRule } from '../base.js';
|
|
12
|
-
import { ERROR_CODES } from '../error-codes.js';
|
|
13
|
-
class E014HiddenDependencyRule extends BaseRule {
|
|
14
|
-
id = ERROR_CODES.E014;
|
|
15
|
-
severity = 'error';
|
|
16
|
-
ruleName = 'Hidden Dependency';
|
|
17
|
-
description = 'Tool calls other tools during execution without declaring them in contract. This breaks isolation.';
|
|
18
|
-
check(_ctx) {
|
|
19
|
-
// This rule requires behavioral context
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Check with behavioral context (called from test orchestrator).
|
|
24
|
-
*/
|
|
25
|
-
checkWithBehavioralContext(behavioralCtx) {
|
|
26
|
-
const diagnostics = [];
|
|
27
|
-
// Check for hidden dependencies (tools called but not declared)
|
|
28
|
-
if (behavioralCtx.hiddenDependencies.length > 0) {
|
|
29
|
-
const dependencyList = behavioralCtx.hiddenDependencies
|
|
30
|
-
.map(dep => ` - ${dep.toolName}`)
|
|
31
|
-
.join('\n');
|
|
32
|
-
diagnostics.push(this.createDiagnostic(`Tool "${behavioralCtx.toolName}" called other tools without declaring them:\n${dependencyList}`, behavioralCtx.toolName, undefined, `Declare dependencies in contract (guarantees.dependencies: [${behavioralCtx.hiddenDependencies.map(d => `"${d.toolName}"`).join(', ')}]) or remove the tool calls.`));
|
|
33
|
-
}
|
|
34
|
-
// Check for missing dependencies (declared but don't exist in MCP server)
|
|
35
|
-
if (behavioralCtx.missingDependencies &&
|
|
36
|
-
behavioralCtx.missingDependencies.length > 0) {
|
|
37
|
-
const missingList = behavioralCtx.missingDependencies
|
|
38
|
-
.map(dep => ` - ${dep}`)
|
|
39
|
-
.join('\n');
|
|
40
|
-
diagnostics.push(this.createDiagnostic(`Tool "${behavioralCtx.toolName}" declares dependencies that don't exist in the MCP server:\n${missingList}`, behavioralCtx.toolName, undefined, `Remove non-existent dependencies from contract (guarantees.dependencies) or ensure these tools are implemented: [${behavioralCtx.missingDependencies.map(d => `"${d}"`).join(', ')}]`));
|
|
41
|
-
}
|
|
42
|
-
return diagnostics;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export const E014HiddenDependency = new E014HiddenDependencyRule();
|
|
46
|
-
//# sourceMappingURL=e014-hidden-dependency.js.map
|