@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.
Files changed (150) hide show
  1. package/README.md +184 -152
  2. package/dist/cli/commands/config.d.ts +47 -0
  3. package/dist/cli/commands/config.js +360 -0
  4. package/dist/cli/commands/dev.d.ts +6 -0
  5. package/dist/cli/commands/dev.js +67 -15
  6. package/dist/cli/commands/doctor.js +49 -13
  7. package/dist/cli/commands/init.d.ts +2 -0
  8. package/dist/cli/commands/init.js +89 -18
  9. package/dist/cli/commands/status.d.ts +10 -0
  10. package/dist/cli/commands/status.js +162 -0
  11. package/dist/cli/index.js +211 -12
  12. package/dist/cli/prompts/init-prompt.d.ts +18 -0
  13. package/dist/cli/prompts/init-prompt.js +159 -99
  14. package/dist/cli/utils/command-error-handler.js +2 -5
  15. package/dist/config/env-checker.d.ts +12 -2
  16. package/dist/config/env-checker.js +88 -38
  17. package/dist/config/env-templates.d.ts +15 -0
  18. package/dist/config/env-templates.js +49 -0
  19. package/dist/config/generator.js +17 -0
  20. package/dist/config/global-loader.d.ts +50 -0
  21. package/dist/config/global-loader.js +244 -0
  22. package/dist/config/loader.d.ts +28 -0
  23. package/dist/config/loader.js +95 -9
  24. package/dist/config/merger.d.ts +37 -0
  25. package/dist/config/merger.js +68 -0
  26. package/dist/config/schema.d.ts +26 -1
  27. package/dist/config/schema.js +73 -8
  28. package/dist/config/types.d.ts +19 -0
  29. package/dist/config/types.js +26 -1
  30. package/dist/constants/messages.d.ts +7 -0
  31. package/dist/constants/messages.js +8 -0
  32. package/dist/constants/paths.d.ts +6 -0
  33. package/dist/constants/paths.js +10 -0
  34. package/dist/events/emitter.js +7 -7
  35. package/dist/index.js +0 -0
  36. package/dist/presentation/config-ui.d.ts +34 -0
  37. package/dist/presentation/config-ui.js +139 -0
  38. package/dist/presentation/doctor-ui.d.ts +11 -0
  39. package/dist/presentation/doctor-ui.js +52 -1
  40. package/dist/presentation/init-ui.d.ts +9 -0
  41. package/dist/presentation/init-ui.js +33 -0
  42. package/dist/runtime/analysis/analyser.js +2 -2
  43. package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +1 -1
  44. package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +1 -1
  45. package/dist/runtime/dev/event-mapper.js +19 -3
  46. package/dist/runtime/dev/session.d.ts +4 -0
  47. package/dist/runtime/dev/session.js +52 -3
  48. package/dist/runtime/llm/ollama.js +4 -4
  49. package/dist/runtime/mcp/client/manager.js +3 -3
  50. package/dist/runtime/sandbox/executor.js +5 -5
  51. package/dist/runtime/test/orchestrator.js +4 -4
  52. package/dist/utils/editor.d.ts +37 -0
  53. package/dist/utils/editor.js +137 -0
  54. package/dist/utils/logger.d.ts +24 -6
  55. package/dist/utils/logger.js +51 -8
  56. package/package.json +23 -23
  57. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +0 -22
  58. package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +0 -30
  59. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +0 -24
  60. package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +0 -52
  61. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +0 -23
  62. package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +0 -73
  63. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +0 -23
  64. package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +0 -47
  65. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +0 -25
  66. package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +0 -73
  67. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +0 -22
  68. package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +0 -57
  69. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +0 -23
  70. package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +0 -56
  71. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +0 -22
  72. package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +0 -84
  73. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +0 -23
  74. package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +0 -89
  75. package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +0 -25
  76. package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +0 -46
  77. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +0 -24
  78. package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +0 -33
  79. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +0 -39
  80. package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +0 -40
  81. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +0 -37
  82. package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +0 -34
  83. package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +0 -39
  84. package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +0 -36
  85. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +0 -42
  86. package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +0 -46
  87. package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +0 -39
  88. package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +0 -36
  89. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +0 -42
  90. package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +0 -46
  91. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +0 -44
  92. package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +0 -66
  93. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +0 -43
  94. package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +0 -42
  95. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +0 -44
  96. package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +0 -66
  97. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +0 -57
  98. package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +0 -80
  99. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +0 -43
  100. package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +0 -42
  101. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +0 -57
  102. package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +0 -80
  103. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +0 -38
  104. package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +0 -37
  105. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +0 -38
  106. package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +0 -37
  107. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +0 -65
  108. package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +0 -109
  109. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +0 -65
  110. package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +0 -109
  111. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +0 -22
  112. package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +0 -39
  113. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +0 -24
  114. package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +0 -40
  115. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +0 -22
  116. package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +0 -84
  117. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +0 -23
  118. package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +0 -96
  119. package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +0 -53
  120. package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +0 -108
  121. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +0 -22
  122. package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +0 -44
  123. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +0 -23
  124. package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +0 -37
  125. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +0 -22
  126. package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +0 -97
  127. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +0 -23
  128. package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +0 -88
  129. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +0 -22
  130. package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +0 -81
  131. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +0 -40
  132. package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +0 -32
  133. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +0 -39
  134. package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +0 -36
  135. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +0 -38
  136. package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +0 -36
  137. package/dist/runtime/test/dependency-tracker.d.ts +0 -66
  138. package/dist/runtime/test/dependency-tracker.js +0 -80
  139. package/dist/runtime/test/formatters.d.ts +0 -18
  140. package/dist/runtime/test/formatters.js +0 -172
  141. package/dist/runtime/test/input-generator.d.ts +0 -33
  142. package/dist/runtime/test/input-generator.js +0 -498
  143. package/dist/runtime/test/mcp-root-detector.d.ts +0 -31
  144. package/dist/runtime/test/mcp-root-detector.js +0 -105
  145. package/dist/runtime/test/retry-tester.d.ts +0 -44
  146. package/dist/runtime/test/retry-tester.js +0 -103
  147. package/dist/runtime/test/synthetic-input-generator.d.ts +0 -11
  148. package/dist/runtime/test/synthetic-input-generator.js +0 -154
  149. package/dist/runtime/test/test-runner.d.ts +0 -28
  150. 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