webmcp-cli 1.1.0 → 1.2.2
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/agent/features/simulation-judge.js +2 -1
- package/dist/agent/features/simulation-judge.js.map +1 -1
- package/dist/agent/features/test-case-generator.js +2 -1
- package/dist/agent/features/test-case-generator.js.map +1 -1
- package/dist/agent/llm-client.js +14 -2
- package/dist/agent/llm-client.js.map +1 -1
- package/dist/bin/webmcp.js +5 -1
- package/dist/bin/webmcp.js.map +1 -1
- package/dist/browser/audit-runner.js +4 -1
- package/dist/browser/audit-runner.js.map +1 -1
- package/dist/cli/commands/audit.js +144 -135
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/interactive.js +3 -7
- package/dist/cli/commands/interactive.js.map +1 -1
- package/dist/cli/options/parse-audit-options.js +28 -3
- package/dist/cli/options/parse-audit-options.js.map +1 -1
- package/dist/core/types/tool.d.ts +1 -1
- package/dist/detection/declarative.js +5 -1
- package/dist/detection/declarative.js.map +1 -1
- package/dist/detection/imperative.js +2 -6
- package/dist/detection/imperative.js.map +1 -1
- package/dist/llm/advice-service.d.ts +5 -8
- package/dist/llm/advice-service.js +158 -201
- package/dist/llm/advice-service.js.map +1 -1
- package/dist/rules/coverage/COV-001.d.ts +3 -4
- package/dist/rules/coverage/COV-001.js +35 -48
- package/dist/rules/coverage/COV-001.js.map +1 -1
- package/dist/scoring/calculator.js +3 -24
- package/dist/scoring/calculator.js.map +1 -1
- package/dist/scoring/grades.d.ts +1 -1
- package/dist/scoring/grades.js +2 -2
- package/dist/scoring/grades.js.map +1 -1
- package/dist/ui/banner.js +3 -3
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/design-tokens.d.ts +23 -0
- package/dist/ui/design-tokens.js +58 -0
- package/dist/ui/design-tokens.js.map +1 -0
- package/dist/ui/findings.js +5 -4
- package/dist/ui/findings.js.map +1 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/ink/FullScreenLayout.js +1 -10
- package/dist/ui/ink/FullScreenLayout.js.map +1 -1
- package/dist/ui/ink/RealAuditApp.js +5 -17
- package/dist/ui/ink/RealAuditApp.js.map +1 -1
- package/dist/ui/ink/components/AsciiLogo.js +1 -1
- package/dist/ui/ink/components/AsciiLogo.js.map +1 -1
- package/dist/ui/ink/components/Header.js +1 -10
- package/dist/ui/ink/components/Header.js.map +1 -1
- package/dist/ui/ink/components/SimulationResults.js +4 -2
- package/dist/ui/ink/components/SimulationResults.js.map +1 -1
- package/dist/ui/ink/components/ToolCard.js +4 -2
- package/dist/ui/ink/components/ToolCard.js.map +1 -1
- package/dist/ui/ink/components/shared/Badge.js +7 -6
- package/dist/ui/ink/components/shared/Badge.js.map +1 -1
- package/dist/ui/ink/components/shared/LoadingWithTimeout.js +1 -1
- package/dist/ui/ink/components/shared/LoadingWithTimeout.js.map +1 -1
- package/dist/ui/ink/components/views/CrawlingView.js +2 -11
- package/dist/ui/ink/components/views/CrawlingView.js.map +1 -1
- package/dist/ui/ink/components/views/FindingDetailView.js +1 -1
- package/dist/ui/ink/components/views/FindingDetailView.js.map +1 -1
- package/dist/ui/ink/components/views/TestCaseDetailView.js +1 -1
- package/dist/ui/ink/components/views/ToolDetailView.js +1 -1
- package/dist/ui/ink/components/views/ToolDetailView.js.map +1 -1
- package/dist/ui/ink/theme.d.ts +6 -4
- package/dist/ui/ink/theme.js +8 -27
- package/dist/ui/ink/theme.js.map +1 -1
- package/dist/ui/score-display.js +24 -43
- package/dist/ui/score-display.js.map +1 -1
- package/dist/ui/spinner.js +3 -1
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/utils.d.ts +13 -0
- package/dist/ui/utils.js +25 -0
- package/dist/ui/utils.js.map +1 -0
- package/package.json +12 -15
- package/dist/bin/agentready.d.ts +0 -5
- package/dist/bin/agentready.js +0 -10
- package/dist/bin/agentready.js.map +0 -1
- package/dist/cli/utils/errors.d.ts +0 -53
- package/dist/cli/utils/errors.js +0 -87
- package/dist/cli/utils/errors.js.map +0 -1
|
@@ -2,43 +2,27 @@
|
|
|
2
2
|
* Smart Advice Service
|
|
3
3
|
*
|
|
4
4
|
* Generates LLM-powered contextual advice for audit findings
|
|
5
|
+
* by calling the centralized WebMCP Advice Server.
|
|
5
6
|
*/
|
|
6
7
|
import { createHash } from 'crypto';
|
|
7
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
8
9
|
import { homedir } from 'os';
|
|
9
10
|
import { join } from 'path';
|
|
10
|
-
import { getRequestCache } from './request-cache.js';
|
|
11
|
-
import { parseJsonObject } from './json-response.js';
|
|
12
11
|
const CACHE_DIR = join(homedir(), '.webmcp', 'cache');
|
|
13
12
|
const ADVICE_CACHE_FILE = join(CACHE_DIR, 'smart-advice.json');
|
|
14
13
|
const CACHE_TTL = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
15
|
-
const
|
|
16
|
-
Analyze audit findings and provide actionable advice that maximizes agent effectiveness.
|
|
17
|
-
|
|
18
|
-
For each finding, respond with JSON containing:
|
|
19
|
-
1. currentState: Analyze the specific problem and its impact on AI agents
|
|
20
|
-
2. enhanced: Provide a concrete improved version with explanation
|
|
21
|
-
3. benefits: List 3-5 specific ways this improvement helps AI agents
|
|
22
|
-
|
|
23
|
-
Focus on:
|
|
24
|
-
- Agent routing accuracy (will AI pick the right tool?)
|
|
25
|
-
- Parameter inference (will AI fill parameters correctly?)
|
|
26
|
-
- Reducing hallucinations (is context specific enough?)
|
|
27
|
-
- Disambiguation (avoiding confusion with other tools)
|
|
28
|
-
- Task completion success rate
|
|
29
|
-
|
|
30
|
-
Be specific and actionable. Include actual improved text when relevant.`;
|
|
14
|
+
const DEFAULT_SERVER_URL = 'https://webmcp-advice-production.up.railway.app';
|
|
31
15
|
export class AdviceService {
|
|
32
16
|
cache;
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
serverUrl;
|
|
18
|
+
clientVersion;
|
|
35
19
|
constructor(config) {
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
20
|
+
this.serverUrl = config?.serverUrl || process.env['WEBMCP_SERVER_URL'] || DEFAULT_SERVER_URL;
|
|
21
|
+
this.clientVersion = 'webmcp-cli/1.1.0';
|
|
38
22
|
this.cache = this.loadCache();
|
|
39
23
|
}
|
|
40
24
|
isAvailable() {
|
|
41
|
-
return
|
|
25
|
+
return true;
|
|
42
26
|
}
|
|
43
27
|
async generateAdvice(finding, tool, siteUrl) {
|
|
44
28
|
const cacheKey = this.getCacheKey(finding, tool);
|
|
@@ -46,110 +30,30 @@ export class AdviceService {
|
|
|
46
30
|
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
47
31
|
return { ...cached.advice, cached: true };
|
|
48
32
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return `FINDING TO ANALYZE:
|
|
58
|
-
- Rule ID: ${finding.ruleId}
|
|
59
|
-
- Severity: ${finding.severity}
|
|
60
|
-
- Issue: ${finding.message}
|
|
61
|
-
- Score Impact: -${finding.scoreImpact} points
|
|
62
|
-
${finding.fix ? `- Basic Suggestion: ${finding.fix}` : ''}
|
|
63
|
-
|
|
64
|
-
${tool ? `AFFECTED TOOL:
|
|
65
|
-
- Name: ${tool.name}
|
|
66
|
-
- Current Description: "${tool.description}"
|
|
67
|
-
- Schema: ${JSON.stringify(tool.inputSchema, null, 2)}
|
|
68
|
-
` : ''}
|
|
69
|
-
|
|
70
|
-
${siteUrl ? `Site: ${siteUrl}` : ''}
|
|
71
|
-
|
|
72
|
-
Respond with JSON only:
|
|
73
|
-
{
|
|
74
|
-
"currentState": {
|
|
75
|
-
"description": "Clear analysis of the current problem",
|
|
76
|
-
"problemAreas": ["specific issue 1", "specific issue 2"],
|
|
77
|
-
"agentImpact": "How this affects AI agent performance"
|
|
78
|
-
},
|
|
79
|
-
"enhanced": {
|
|
80
|
-
"suggestedFix": "The improved version (actual text if applicable)",
|
|
81
|
-
"explanation": "Why this improvement works better for AI agents",
|
|
82
|
-
"codeExample": "Optional code showing the fix"
|
|
83
|
-
},
|
|
84
|
-
"benefits": {
|
|
85
|
-
"title": "How this will help AI agents",
|
|
86
|
-
"items": [
|
|
87
|
-
"Benefit 1: specific improvement for agents",
|
|
88
|
-
"Benefit 2: another specific benefit",
|
|
89
|
-
"Benefit 3: third benefit"
|
|
90
|
-
]
|
|
91
|
-
},
|
|
92
|
-
"confidence": 0.95
|
|
93
|
-
}`;
|
|
94
|
-
}
|
|
95
|
-
async callLLM(prompt) {
|
|
96
|
-
const requestCache = getRequestCache();
|
|
97
|
-
const requestBody = {
|
|
98
|
-
model: this.model,
|
|
99
|
-
messages: [
|
|
100
|
-
{ role: 'system', content: SYSTEM_PROMPT },
|
|
101
|
-
{ role: 'user', content: prompt }
|
|
102
|
-
],
|
|
103
|
-
temperature: 0.2,
|
|
104
|
-
max_tokens: 1500
|
|
105
|
-
};
|
|
106
|
-
// Check request cache first (full request body hash)
|
|
107
|
-
const cached = requestCache.get(requestBody);
|
|
108
|
-
if (cached) {
|
|
109
|
-
return cached;
|
|
110
|
-
}
|
|
111
|
-
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
112
|
-
method: 'POST',
|
|
113
|
-
headers: {
|
|
114
|
-
'Authorization': `Bearer ${this.apiKey}`,
|
|
115
|
-
'Content-Type': 'application/json',
|
|
116
|
-
'HTTP-Referer': 'https://web-mcp.net',
|
|
117
|
-
'X-Title': 'WebMCP CLI'
|
|
33
|
+
const body = {
|
|
34
|
+
finding: {
|
|
35
|
+
ruleId: finding.ruleId,
|
|
36
|
+
severity: finding.severity,
|
|
37
|
+
message: finding.message,
|
|
38
|
+
tool: finding.tool,
|
|
39
|
+
fix: finding.fix,
|
|
40
|
+
scoreImpact: finding.scoreImpact,
|
|
118
41
|
},
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const content = data.choices?.[0]?.message?.content || '';
|
|
126
|
-
// Cache the response
|
|
127
|
-
requestCache.set(requestBody, content, this.model);
|
|
128
|
-
return content;
|
|
129
|
-
}
|
|
130
|
-
parseResponse(response) {
|
|
131
|
-
try {
|
|
132
|
-
return parseJsonObject(response);
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
// Fallback for parsing errors
|
|
136
|
-
return {
|
|
137
|
-
currentState: {
|
|
138
|
-
description: 'Unable to analyze automatically',
|
|
139
|
-
problemAreas: ['Analysis failed'],
|
|
140
|
-
agentImpact: 'Manual review recommended'
|
|
141
|
-
},
|
|
142
|
-
enhanced: {
|
|
143
|
-
suggestedFix: 'Please review the finding manually',
|
|
144
|
-
explanation: 'Automated advice generation encountered an error'
|
|
145
|
-
},
|
|
146
|
-
benefits: {
|
|
147
|
-
title: 'Potential benefits',
|
|
148
|
-
items: ['Improved agent accuracy', 'Better tool selection', 'Reduced errors']
|
|
149
|
-
},
|
|
150
|
-
confidence: 0
|
|
42
|
+
};
|
|
43
|
+
if (tool) {
|
|
44
|
+
body['tool'] = {
|
|
45
|
+
name: tool.name,
|
|
46
|
+
description: tool.description,
|
|
47
|
+
inputSchema: tool.inputSchema,
|
|
151
48
|
};
|
|
152
49
|
}
|
|
50
|
+
if (siteUrl) {
|
|
51
|
+
body['siteUrl'] = siteUrl;
|
|
52
|
+
}
|
|
53
|
+
const advice = await this.callServer('/api/advice/finding', body);
|
|
54
|
+
this.cache.entries[cacheKey] = { advice, timestamp: Date.now() };
|
|
55
|
+
this.saveCache();
|
|
56
|
+
return advice;
|
|
153
57
|
}
|
|
154
58
|
/**
|
|
155
59
|
* Generate proactive optimization advice for a tool
|
|
@@ -161,50 +65,21 @@ Respond with JSON only:
|
|
|
161
65
|
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
162
66
|
return { ...cached.advice, cached: true };
|
|
163
67
|
}
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
68
|
+
const body = {
|
|
69
|
+
tool: {
|
|
70
|
+
name: tool.name,
|
|
71
|
+
description: tool.description,
|
|
72
|
+
inputSchema: tool.inputSchema,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
if (siteUrl) {
|
|
76
|
+
body['siteUrl'] = siteUrl;
|
|
77
|
+
}
|
|
78
|
+
const advice = await this.callServer('/api/advice/tool', body);
|
|
167
79
|
this.cache.entries[cacheKey] = { advice, timestamp: Date.now() };
|
|
168
80
|
this.saveCache();
|
|
169
81
|
return advice;
|
|
170
82
|
}
|
|
171
|
-
buildToolPrompt(tool, siteUrl) {
|
|
172
|
-
return `TOOL TO OPTIMIZE FOR AI AGENTS:
|
|
173
|
-
- Name: ${tool.name}
|
|
174
|
-
- Description: "${tool.description}"
|
|
175
|
-
- Schema: ${JSON.stringify(tool.inputSchema, null, 2)}
|
|
176
|
-
${siteUrl ? `- Site: ${siteUrl}` : ''}
|
|
177
|
-
|
|
178
|
-
Analyze this tool definition and suggest improvements to maximize AI agent effectiveness.
|
|
179
|
-
Consider:
|
|
180
|
-
- Is the description specific enough for agents to know when to use this tool?
|
|
181
|
-
- Are parameter descriptions clear enough for agents to fill them correctly?
|
|
182
|
-
- Is there any ambiguity that could cause agents to misuse this tool?
|
|
183
|
-
- What improvements would increase task completion success rate?
|
|
184
|
-
|
|
185
|
-
Respond with JSON only:
|
|
186
|
-
{
|
|
187
|
-
"currentState": {
|
|
188
|
-
"description": "Analysis of current tool definition quality",
|
|
189
|
-
"problemAreas": ["specific issue 1", "specific issue 2"],
|
|
190
|
-
"agentImpact": "How current state affects AI agent performance"
|
|
191
|
-
},
|
|
192
|
-
"enhanced": {
|
|
193
|
-
"suggestedFix": "Improved tool description and any suggested changes",
|
|
194
|
-
"explanation": "Why these improvements help AI agents",
|
|
195
|
-
"codeExample": "Optional improved schema snippet"
|
|
196
|
-
},
|
|
197
|
-
"benefits": {
|
|
198
|
-
"title": "How these improvements will help AI agents",
|
|
199
|
-
"items": [
|
|
200
|
-
"Benefit 1: specific improvement",
|
|
201
|
-
"Benefit 2: another benefit",
|
|
202
|
-
"Benefit 3: third benefit"
|
|
203
|
-
]
|
|
204
|
-
},
|
|
205
|
-
"confidence": 0.9
|
|
206
|
-
}`;
|
|
207
|
-
}
|
|
208
83
|
/**
|
|
209
84
|
* Pre-fetch advice for all findings and tools in parallel
|
|
210
85
|
* Call this after audit completes, before displaying TUI
|
|
@@ -213,48 +88,130 @@ Respond with JSON only:
|
|
|
213
88
|
const findingAdvice = new Map();
|
|
214
89
|
const toolAdvice = new Map();
|
|
215
90
|
const total = findings.length + tools.length;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
91
|
+
// Check how many are already cached
|
|
92
|
+
const uncachedFindings = [];
|
|
93
|
+
const uncachedTools = [];
|
|
94
|
+
for (let i = 0; i < findings.length; i++) {
|
|
95
|
+
const finding = findings[i];
|
|
96
|
+
const relatedTool = finding.tool ? tools.find(t => t.name === finding.tool) : undefined;
|
|
97
|
+
const cacheKey = this.getCacheKey(finding, relatedTool);
|
|
98
|
+
const cached = this.cache.entries[cacheKey];
|
|
99
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
100
|
+
findingAdvice.set(`finding-${i}`, { ...cached.advice, cached: true });
|
|
224
101
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
onProgress?.(completed, total);
|
|
228
|
-
});
|
|
229
|
-
// Create tasks for tool advice
|
|
230
|
-
const toolTasks = tools.map(async (tool, i) => {
|
|
231
|
-
const id = `tool-${i}`;
|
|
232
|
-
try {
|
|
233
|
-
const advice = await this.generateToolAdvice(tool, siteUrl);
|
|
234
|
-
toolAdvice.set(id, advice);
|
|
102
|
+
else {
|
|
103
|
+
uncachedFindings.push({ index: i, finding, tool: relatedTool });
|
|
235
104
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
105
|
+
}
|
|
106
|
+
for (let i = 0; i < tools.length; i++) {
|
|
107
|
+
const tool = tools[i];
|
|
108
|
+
const cacheKey = this.getToolCacheKey(tool);
|
|
109
|
+
const cached = this.cache.entries[cacheKey];
|
|
110
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
111
|
+
toolAdvice.set(`tool-${i}`, { ...cached.advice, cached: true });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
uncachedTools.push({ index: i, tool });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let completed = findingAdvice.size + toolAdvice.size;
|
|
118
|
+
onProgress?.(completed, total);
|
|
119
|
+
// If everything is cached, return early
|
|
120
|
+
if (uncachedFindings.length === 0 && uncachedTools.length === 0) {
|
|
121
|
+
return { findingAdvice, toolAdvice };
|
|
122
|
+
}
|
|
123
|
+
// Call server batch endpoint for uncached items
|
|
124
|
+
try {
|
|
125
|
+
const body = {
|
|
126
|
+
findings: uncachedFindings.map(f => ({
|
|
127
|
+
ruleId: f.finding.ruleId,
|
|
128
|
+
severity: f.finding.severity,
|
|
129
|
+
message: f.finding.message,
|
|
130
|
+
tool: f.finding.tool,
|
|
131
|
+
fix: f.finding.fix,
|
|
132
|
+
scoreImpact: f.finding.scoreImpact,
|
|
133
|
+
})),
|
|
134
|
+
tools: uncachedTools.map(t => ({
|
|
135
|
+
name: t.tool.name,
|
|
136
|
+
description: t.tool.description,
|
|
137
|
+
inputSchema: t.tool.inputSchema,
|
|
138
|
+
})),
|
|
139
|
+
};
|
|
140
|
+
if (siteUrl) {
|
|
141
|
+
body['siteUrl'] = siteUrl;
|
|
142
|
+
}
|
|
143
|
+
const response = await fetch(`${this.serverUrl}/api/advice/prefetch`, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: {
|
|
146
|
+
'Content-Type': 'application/json',
|
|
147
|
+
'X-Client-Version': this.clientVersion,
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify(body),
|
|
150
|
+
});
|
|
151
|
+
if (response.ok) {
|
|
152
|
+
const data = (await response.json());
|
|
153
|
+
// Map server response indices back to original indices
|
|
154
|
+
for (let i = 0; i < uncachedFindings.length; i++) {
|
|
155
|
+
const item = uncachedFindings[i];
|
|
156
|
+
const advice = data.findingAdvice[`finding-${i}`];
|
|
157
|
+
if (advice) {
|
|
158
|
+
findingAdvice.set(`finding-${item.index}`, advice);
|
|
159
|
+
const cacheKey = this.getCacheKey(item.finding, item.tool);
|
|
160
|
+
this.cache.entries[cacheKey] = { advice, timestamp: Date.now() };
|
|
161
|
+
}
|
|
162
|
+
completed++;
|
|
163
|
+
onProgress?.(completed, total);
|
|
164
|
+
}
|
|
165
|
+
for (let i = 0; i < uncachedTools.length; i++) {
|
|
166
|
+
const item = uncachedTools[i];
|
|
167
|
+
const advice = data.toolAdvice[`tool-${i}`];
|
|
168
|
+
if (advice) {
|
|
169
|
+
toolAdvice.set(`tool-${item.index}`, advice);
|
|
170
|
+
const cacheKey = this.getToolCacheKey(item.tool);
|
|
171
|
+
this.cache.entries[cacheKey] = { advice, timestamp: Date.now() };
|
|
172
|
+
}
|
|
173
|
+
completed++;
|
|
174
|
+
onProgress?.(completed, total);
|
|
175
|
+
}
|
|
176
|
+
this.saveCache();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
throw new Error(`Advice prefetch failed: ${response.status}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Batch failed - fall back to individual requests
|
|
184
|
+
const individualTasks = [];
|
|
185
|
+
for (const item of uncachedFindings) {
|
|
186
|
+
individualTasks.push(this.generateAdvice(item.finding, item.tool, siteUrl)
|
|
187
|
+
.then(advice => { findingAdvice.set(`finding-${item.index}`, advice); })
|
|
188
|
+
.catch(() => { })
|
|
189
|
+
.finally(() => { completed++; onProgress?.(completed, total); }));
|
|
190
|
+
}
|
|
191
|
+
for (const item of uncachedTools) {
|
|
192
|
+
individualTasks.push(this.generateToolAdvice(item.tool, siteUrl)
|
|
193
|
+
.then(advice => { toolAdvice.set(`tool-${item.index}`, advice); })
|
|
194
|
+
.catch(() => { })
|
|
195
|
+
.finally(() => { completed++; onProgress?.(completed, total); }));
|
|
196
|
+
}
|
|
197
|
+
await Promise.all(individualTasks);
|
|
198
|
+
}
|
|
242
199
|
return { findingAdvice, toolAdvice };
|
|
243
200
|
}
|
|
244
|
-
async
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
201
|
+
async callServer(path, body) {
|
|
202
|
+
const response = await fetch(`${this.serverUrl}${path}`, {
|
|
203
|
+
method: 'POST',
|
|
204
|
+
headers: {
|
|
205
|
+
'Content-Type': 'application/json',
|
|
206
|
+
'X-Client-Version': this.clientVersion,
|
|
207
|
+
},
|
|
208
|
+
body: JSON.stringify(body),
|
|
209
|
+
});
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
throw new Error(`Advice server error: ${response.status}`);
|
|
256
212
|
}
|
|
257
|
-
await
|
|
213
|
+
const data = (await response.json());
|
|
214
|
+
return data.advice;
|
|
258
215
|
}
|
|
259
216
|
getToolCacheKey(tool) {
|
|
260
217
|
const input = `tool:${tool.name}:${tool.description?.slice(0, 100) || ''}:${JSON.stringify(tool.inputSchema).slice(0, 200)}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advice-service.js","sourceRoot":"","sources":["../../src/llm/advice-service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"advice-service.js","sourceRoot":"","sources":["../../src/llm/advice-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* COV-001:
|
|
2
|
+
* COV-001: Form Coverage
|
|
3
3
|
*
|
|
4
|
-
* Checks
|
|
5
|
-
*
|
|
4
|
+
* Checks if all interactive forms on the page are exposed as MCP tools.
|
|
5
|
+
* Unregistered forms represent missed opportunities for tool coverage.
|
|
6
6
|
*/
|
|
7
7
|
import type { Rule } from '../../core/types/rule.js';
|
|
8
8
|
export declare const COV_001: Rule;
|
|
9
|
-
export default COV_001;
|
|
@@ -1,64 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* COV-001:
|
|
2
|
+
* COV-001: Form Coverage
|
|
3
3
|
*
|
|
4
|
-
* Checks
|
|
5
|
-
*
|
|
4
|
+
* Checks if all interactive forms on the page are exposed as MCP tools.
|
|
5
|
+
* Unregistered forms represent missed opportunities for tool coverage.
|
|
6
6
|
*/
|
|
7
7
|
import { createRuleResult } from '../runner.js';
|
|
8
8
|
export const COV_001 = {
|
|
9
9
|
id: 'COV-001',
|
|
10
10
|
category: 'coverage',
|
|
11
|
-
name: '
|
|
12
|
-
description: '
|
|
13
|
-
severity: '
|
|
14
|
-
maxScore:
|
|
11
|
+
name: 'Form Coverage',
|
|
12
|
+
description: 'All interactive forms should be exposed as MCP tools',
|
|
13
|
+
severity: 'warning',
|
|
14
|
+
maxScore: 5,
|
|
15
15
|
async check(context) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (opportunities > 0) {
|
|
23
|
-
return createRuleResult('COV-001', 20, {
|
|
24
|
-
passed: false,
|
|
25
|
-
score: 5,
|
|
26
|
-
message: `No WebMCP tools registered, but ${opportunities} form(s) could be converted`,
|
|
27
|
-
suggestions: [
|
|
28
|
-
'Add toolname attribute to forms to expose them as AI agent tools',
|
|
29
|
-
'Use navigator.modelContext.registerTool() to register JavaScript-based tools',
|
|
30
|
-
'Consider which user actions could benefit from AI agent automation',
|
|
31
|
-
],
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return createRuleResult('COV-001', 20, {
|
|
35
|
-
passed: false,
|
|
36
|
-
score: 0,
|
|
37
|
-
message: 'No WebMCP tools registered',
|
|
38
|
-
suggestions: [
|
|
39
|
-
'Register tools using navigator.modelContext.registerTool()',
|
|
40
|
-
'Add toolname attribute to HTML forms for declarative tools',
|
|
41
|
-
'Identify key user actions that AI agents should be able to perform',
|
|
42
|
-
],
|
|
16
|
+
const { tools, opportunities } = context;
|
|
17
|
+
if (tools.length === 0 && opportunities.length === 0) {
|
|
18
|
+
return createRuleResult('COV-001', 5, {
|
|
19
|
+
passed: true,
|
|
20
|
+
score: 5,
|
|
21
|
+
message: 'No tools or forms detected (rule not applicable)',
|
|
43
22
|
});
|
|
44
23
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Bonus for declarative tools
|
|
52
|
-
if (declarativeTools.length > 0) {
|
|
53
|
-
score += Math.min(5, declarativeTools.length);
|
|
24
|
+
if (opportunities.length === 0) {
|
|
25
|
+
return createRuleResult('COV-001', 5, {
|
|
26
|
+
passed: true,
|
|
27
|
+
score: 5,
|
|
28
|
+
message: 'All detected forms are covered by MCP tools',
|
|
29
|
+
});
|
|
54
30
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
31
|
+
const totalForms = tools.length + opportunities.length;
|
|
32
|
+
const coverageRatio = tools.length / totalForms;
|
|
33
|
+
const score = Math.round(coverageRatio * 5);
|
|
34
|
+
const passed = opportunities.length === 0;
|
|
35
|
+
const uncoveredNames = opportunities.map((o) => o.contextClues.submitText ||
|
|
36
|
+
o.contextClues.ariaLabel ||
|
|
37
|
+
o.contextClues.formId ||
|
|
38
|
+
o.contextClues.formAction ||
|
|
39
|
+
'unnamed form');
|
|
40
|
+
return createRuleResult('COV-001', 5, {
|
|
41
|
+
passed,
|
|
58
42
|
score,
|
|
59
|
-
message: `${
|
|
43
|
+
message: `${tools.length}/${totalForms} forms covered (${Math.round(coverageRatio * 100)}%)`,
|
|
44
|
+
details: uncoveredNames.map((n) => `Uncovered form: ${n}`),
|
|
45
|
+
suggestions: opportunities.length > 0
|
|
46
|
+
? ['Register uncovered forms as MCP tools to improve coverage']
|
|
47
|
+
: undefined,
|
|
60
48
|
});
|
|
61
49
|
},
|
|
62
50
|
};
|
|
63
|
-
export default COV_001;
|
|
64
51
|
//# sourceMappingURL=COV-001.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"COV-001.js","sourceRoot":"","sources":["../../../src/rules/coverage/COV-001.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,SAAS;IACb,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"COV-001.js","sourceRoot":"","sources":["../../../src/rules/coverage/COV-001.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,SAAS;IACb,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,CAAC;IAEX,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAEzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrD,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;gBACpC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,kDAAkD;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;gBACpC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,6CAA6C;aACvD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QACvD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;QAE1C,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CACtC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,YAAY,CAAC,UAAU;YACzB,CAAC,CAAC,YAAY,CAAC,SAAS;YACxB,CAAC,CAAC,YAAY,CAAC,MAAM;YACrB,CAAC,CAAC,YAAY,CAAC,UAAU;YACzB,cAAc,CACjB,CAAC;QAEF,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;YACpC,MAAM;YACN,KAAK;YACL,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,UAAU,mBAAmB,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,IAAI;YAC5F,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1D,WAAW,EACT,aAAa,CAAC,MAAM,GAAG,CAAC;gBACtB,CAAC,CAAC,CAAC,2DAA2D,CAAC;gBAC/D,CAAC,CAAC,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|