webmcp-cli 1.2.2 → 1.2.3
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/analysis/form-to-tool-mapper.d.ts +61 -0
- package/dist/analysis/form-to-tool-mapper.js +360 -0
- package/dist/analysis/form-to-tool-mapper.js.map +1 -0
- package/dist/analysis/index.d.ts +84 -0
- package/dist/analysis/index.js +81 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/missing-tool-analyzer.d.ts +35 -0
- package/dist/analysis/missing-tool-analyzer.js +617 -0
- package/dist/analysis/missing-tool-analyzer.js.map +1 -0
- package/dist/audit/run-multi-page-audit.d.ts +34 -0
- package/dist/audit/run-multi-page-audit.js +233 -0
- package/dist/audit/run-multi-page-audit.js.map +1 -0
- package/dist/cli/commands/potential.d.ts +8 -0
- package/dist/cli/commands/potential.js +323 -0
- package/dist/cli/commands/potential.js.map +1 -0
- package/dist/cli/commands/report.d.ts +12 -0
- package/dist/cli/commands/report.js +89 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.d.ts +36 -0
- package/dist/config/defaults.js +33 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +22 -0
- package/dist/config/loader.js +91 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +280 -0
- package/dist/config/schema.js +42 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/types/audit.d.ts +1 -1
- package/dist/core/types/index.d.ts +1 -0
- package/dist/core/types/index.js +1 -0
- package/dist/core/types/index.js.map +1 -1
- package/dist/core/types/recon.d.ts +265 -0
- package/dist/core/types/recon.js +5 -0
- package/dist/core/types/recon.js.map +1 -0
- package/dist/core/types/rule.d.ts +1 -1
- package/dist/core/types/rule.js +7 -5
- package/dist/core/types/rule.js.map +1 -1
- package/dist/crawler/depth-crawler.d.ts +29 -0
- package/dist/crawler/depth-crawler.js +212 -0
- package/dist/crawler/depth-crawler.js.map +1 -0
- package/dist/crawler/index.d.ts +2 -0
- package/dist/crawler/index.js +3 -0
- package/dist/crawler/index.js.map +1 -0
- package/dist/crawler/link-extractor.d.ts +1 -0
- package/dist/crawler/link-extractor.js +49 -0
- package/dist/crawler/link-extractor.js.map +1 -0
- package/dist/generators/index.d.ts +10 -0
- package/dist/generators/index.js +8 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/report-html.d.ts +12 -0
- package/dist/generators/report-html.js +470 -0
- package/dist/generators/report-html.js.map +1 -0
- package/dist/generators/report-json.d.ts +95 -0
- package/dist/generators/report-json.js +144 -0
- package/dist/generators/report-json.js.map +1 -0
- package/dist/generators/report-manager.d.ts +31 -0
- package/dist/generators/report-manager.js +208 -0
- package/dist/generators/report-manager.js.map +1 -0
- package/dist/generators/tool-code-generator.d.ts +31 -0
- package/dist/generators/tool-code-generator.js +201 -0
- package/dist/generators/tool-code-generator.js.map +1 -0
- package/dist/potential/ai-recommender.d.ts +33 -0
- package/dist/potential/ai-recommender.js +414 -0
- package/dist/potential/ai-recommender.js.map +1 -0
- package/dist/potential/analyzer.d.ts +32 -0
- package/dist/potential/analyzer.js +383 -0
- package/dist/potential/analyzer.js.map +1 -0
- package/dist/potential/index.d.ts +3 -0
- package/dist/potential/index.js +4 -0
- package/dist/potential/index.js.map +1 -0
- package/dist/potential/prompts.d.ts +20 -0
- package/dist/potential/prompts.js +42 -0
- package/dist/potential/prompts.js.map +1 -0
- package/dist/potential/types.d.ts +40 -0
- package/dist/potential/types.js +2 -0
- package/dist/potential/types.js.map +1 -0
- package/dist/recon/index.d.ts +20 -0
- package/dist/recon/index.js +143 -0
- package/dist/recon/index.js.map +1 -0
- package/dist/recon/manifest.d.ts +16 -0
- package/dist/recon/manifest.js +108 -0
- package/dist/recon/manifest.js.map +1 -0
- package/dist/recon/meta-extractor.d.ts +11 -0
- package/dist/recon/meta-extractor.js +276 -0
- package/dist/recon/meta-extractor.js.map +1 -0
- package/dist/recon/robots.d.ts +16 -0
- package/dist/recon/robots.js +158 -0
- package/dist/recon/robots.js.map +1 -0
- package/dist/recon/route-discovery.d.ts +25 -0
- package/dist/recon/route-discovery.js +303 -0
- package/dist/recon/route-discovery.js.map +1 -0
- package/dist/recon/sitemap.d.ts +12 -0
- package/dist/recon/sitemap.js +177 -0
- package/dist/recon/sitemap.js.map +1 -0
- package/dist/rules/accessibility/AXE-001.d.ts +9 -0
- package/dist/rules/accessibility/AXE-001.js +109 -0
- package/dist/rules/accessibility/AXE-001.js.map +1 -0
- package/dist/rules/accessibility/AXE-002.d.ts +8 -0
- package/dist/rules/accessibility/AXE-002.js +85 -0
- package/dist/rules/accessibility/AXE-002.js.map +1 -0
- package/dist/rules/accessibility/AXE-003.d.ts +8 -0
- package/dist/rules/accessibility/AXE-003.js +94 -0
- package/dist/rules/accessibility/AXE-003.js.map +1 -0
- package/dist/rules/accessibility/AXE-004.d.ts +8 -0
- package/dist/rules/accessibility/AXE-004.js +101 -0
- package/dist/rules/accessibility/AXE-004.js.map +1 -0
- package/dist/rules/accessibility/AXE-005.d.ts +9 -0
- package/dist/rules/accessibility/AXE-005.js +89 -0
- package/dist/rules/accessibility/AXE-005.js.map +1 -0
- package/dist/rules/best-practices/BP-004.d.ts +9 -0
- package/dist/rules/best-practices/BP-004.js +96 -0
- package/dist/rules/best-practices/BP-004.js.map +1 -0
- package/dist/rules/best-practices/BP-005.d.ts +8 -0
- package/dist/rules/best-practices/BP-005.js +94 -0
- package/dist/rules/best-practices/BP-005.js.map +1 -0
- package/dist/rules/best-practices/BP-006.d.ts +8 -0
- package/dist/rules/best-practices/BP-006.js +80 -0
- package/dist/rules/best-practices/BP-006.js.map +1 -0
- package/dist/rules/best-practices/BP-007.d.ts +8 -0
- package/dist/rules/best-practices/BP-007.js +92 -0
- package/dist/rules/best-practices/BP-007.js.map +1 -0
- package/dist/rules/best-practices/BP-008.d.ts +12 -0
- package/dist/rules/best-practices/BP-008.js +86 -0
- package/dist/rules/best-practices/BP-008.js.map +1 -0
- package/dist/rules/best-practices/BP-009.d.ts +9 -0
- package/dist/rules/best-practices/BP-009.js +77 -0
- package/dist/rules/best-practices/BP-009.js.map +1 -0
- package/dist/rules/best-practices/BP-010.d.ts +8 -0
- package/dist/rules/best-practices/BP-010.js +85 -0
- package/dist/rules/best-practices/BP-010.js.map +1 -0
- package/dist/rules/coverage/COV-002.d.ts +8 -0
- package/dist/rules/coverage/COV-002.js +68 -0
- package/dist/rules/coverage/COV-002.js.map +1 -0
- package/dist/rules/coverage/COV-003.d.ts +8 -0
- package/dist/rules/coverage/COV-003.js +68 -0
- package/dist/rules/coverage/COV-003.js.map +1 -0
- package/dist/rules/coverage/COV-004.d.ts +8 -0
- package/dist/rules/coverage/COV-004.js +89 -0
- package/dist/rules/coverage/COV-004.js.map +1 -0
- package/dist/rules/coverage/COV-005.d.ts +8 -0
- package/dist/rules/coverage/COV-005.js +67 -0
- package/dist/rules/coverage/COV-005.js.map +1 -0
- package/dist/rules/coverage/COV-006.d.ts +9 -0
- package/dist/rules/coverage/COV-006.js +76 -0
- package/dist/rules/coverage/COV-006.js.map +1 -0
- package/dist/rules/coverage/COV-007.d.ts +8 -0
- package/dist/rules/coverage/COV-007.js +67 -0
- package/dist/rules/coverage/COV-007.js.map +1 -0
- package/dist/rules/coverage/COV-008.d.ts +9 -0
- package/dist/rules/coverage/COV-008.js +87 -0
- package/dist/rules/coverage/COV-008.js.map +1 -0
- package/dist/rules/coverage/COV-009.d.ts +8 -0
- package/dist/rules/coverage/COV-009.js +73 -0
- package/dist/rules/coverage/COV-009.js.map +1 -0
- package/dist/rules/coverage/COV-010.d.ts +9 -0
- package/dist/rules/coverage/COV-010.js +82 -0
- package/dist/rules/coverage/COV-010.js.map +1 -0
- package/dist/rules/description/DESC-001.d.ts +9 -0
- package/dist/rules/description/DESC-001.js +88 -0
- package/dist/rules/description/DESC-001.js.map +1 -0
- package/dist/rules/description/DESC-002.d.ts +10 -0
- package/dist/rules/description/DESC-002.js +99 -0
- package/dist/rules/description/DESC-002.js.map +1 -0
- package/dist/rules/description/DESC-006.d.ts +9 -0
- package/dist/rules/description/DESC-006.js +78 -0
- package/dist/rules/description/DESC-006.js.map +1 -0
- package/dist/rules/description/DESC-007.d.ts +9 -0
- package/dist/rules/description/DESC-007.js +70 -0
- package/dist/rules/description/DESC-007.js.map +1 -0
- package/dist/rules/description/DESC-008.d.ts +9 -0
- package/dist/rules/description/DESC-008.js +70 -0
- package/dist/rules/description/DESC-008.js.map +1 -0
- package/dist/rules/description/DESC-009.d.ts +8 -0
- package/dist/rules/description/DESC-009.js +55 -0
- package/dist/rules/description/DESC-009.js.map +1 -0
- package/dist/rules/description/DESC-010.d.ts +9 -0
- package/dist/rules/description/DESC-010.js +92 -0
- package/dist/rules/description/DESC-010.js.map +1 -0
- package/dist/rules/description/DESC-011.d.ts +9 -0
- package/dist/rules/description/DESC-011.js +81 -0
- package/dist/rules/description/DESC-011.js.map +1 -0
- package/dist/rules/description/DESC-012.d.ts +9 -0
- package/dist/rules/description/DESC-012.js +98 -0
- package/dist/rules/description/DESC-012.js.map +1 -0
- package/dist/rules/implementation/IMP-002.d.ts +9 -0
- package/dist/rules/implementation/IMP-002.js +59 -0
- package/dist/rules/implementation/IMP-002.js.map +1 -0
- package/dist/rules/implementation/IMP-006.d.ts +9 -0
- package/dist/rules/implementation/IMP-006.js +48 -0
- package/dist/rules/implementation/IMP-006.js.map +1 -0
- package/dist/rules/implementation/IMP-008.d.ts +9 -0
- package/dist/rules/implementation/IMP-008.js +46 -0
- package/dist/rules/implementation/IMP-008.js.map +1 -0
- package/dist/rules/implementation/IMP-009.d.ts +9 -0
- package/dist/rules/implementation/IMP-009.js +48 -0
- package/dist/rules/implementation/IMP-009.js.map +1 -0
- package/dist/rules/implementation/IMP-010.d.ts +9 -0
- package/dist/rules/implementation/IMP-010.js +66 -0
- package/dist/rules/implementation/IMP-010.js.map +1 -0
- package/dist/rules/implementation/IMP-011.d.ts +9 -0
- package/dist/rules/implementation/IMP-011.js +82 -0
- package/dist/rules/implementation/IMP-011.js.map +1 -0
- package/dist/rules/implementation/IMP-012.d.ts +9 -0
- package/dist/rules/implementation/IMP-012.js +88 -0
- package/dist/rules/implementation/IMP-012.js.map +1 -0
- package/dist/rules/implementation/IMP-014.d.ts +9 -0
- package/dist/rules/implementation/IMP-014.js +58 -0
- package/dist/rules/implementation/IMP-014.js.map +1 -0
- package/dist/rules/implementation/IMP-015.d.ts +9 -0
- package/dist/rules/implementation/IMP-015.js +64 -0
- package/dist/rules/implementation/IMP-015.js.map +1 -0
- package/dist/rules/implementation/IMP-016.d.ts +9 -0
- package/dist/rules/implementation/IMP-016.js +52 -0
- package/dist/rules/implementation/IMP-016.js.map +1 -0
- package/dist/rules/implementation/IMP-017.d.ts +8 -0
- package/dist/rules/implementation/IMP-017.js +51 -0
- package/dist/rules/implementation/IMP-017.js.map +1 -0
- package/dist/rules/implementation/IMP-018.d.ts +8 -0
- package/dist/rules/implementation/IMP-018.js +52 -0
- package/dist/rules/implementation/IMP-018.js.map +1 -0
- package/dist/rules/implementation/IMP-019.d.ts +8 -0
- package/dist/rules/implementation/IMP-019.js +53 -0
- package/dist/rules/implementation/IMP-019.js.map +1 -0
- package/dist/rules/implementation/IMP-020.d.ts +9 -0
- package/dist/rules/implementation/IMP-020.js +62 -0
- package/dist/rules/implementation/IMP-020.js.map +1 -0
- package/dist/rules/implementation/IMP-021.d.ts +8 -0
- package/dist/rules/implementation/IMP-021.js +64 -0
- package/dist/rules/implementation/IMP-021.js.map +1 -0
- package/dist/rules/implementation/IMP-022.d.ts +8 -0
- package/dist/rules/implementation/IMP-022.js +70 -0
- package/dist/rules/implementation/IMP-022.js.map +1 -0
- package/dist/rules/index.d.ts +73 -6
- package/dist/rules/index.js +141 -6
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/schema/SCHEMA-004.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-004.js +57 -0
- package/dist/rules/schema/SCHEMA-004.js.map +1 -0
- package/dist/rules/schema/SCHEMA-005.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-005.js +61 -0
- package/dist/rules/schema/SCHEMA-005.js.map +1 -0
- package/dist/rules/schema/SCHEMA-006.d.ts +10 -0
- package/dist/rules/schema/SCHEMA-006.js +85 -0
- package/dist/rules/schema/SCHEMA-006.js.map +1 -0
- package/dist/rules/schema/SCHEMA-007.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-007.js +73 -0
- package/dist/rules/schema/SCHEMA-007.js.map +1 -0
- package/dist/rules/schema/SCHEMA-008.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-008.js +70 -0
- package/dist/rules/schema/SCHEMA-008.js.map +1 -0
- package/dist/rules/schema/SCHEMA-009.d.ts +10 -0
- package/dist/rules/schema/SCHEMA-009.js +80 -0
- package/dist/rules/schema/SCHEMA-009.js.map +1 -0
- package/dist/rules/schema/SCHEMA-010.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-010.js +96 -0
- package/dist/rules/schema/SCHEMA-010.js.map +1 -0
- package/dist/rules/schema/SCHEMA-012.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-012.js +65 -0
- package/dist/rules/schema/SCHEMA-012.js.map +1 -0
- package/dist/rules/security/SEC-002.d.ts +8 -0
- package/dist/rules/security/SEC-002.js +81 -0
- package/dist/rules/security/SEC-002.js.map +1 -0
- package/dist/rules/security/SEC-003.d.ts +8 -0
- package/dist/rules/security/SEC-003.js +85 -0
- package/dist/rules/security/SEC-003.js.map +1 -0
- package/dist/rules/security/SEC-004.d.ts +9 -0
- package/dist/rules/security/SEC-004.js +87 -0
- package/dist/rules/security/SEC-004.js.map +1 -0
- package/dist/rules/security/SEC-005.d.ts +8 -0
- package/dist/rules/security/SEC-005.js +87 -0
- package/dist/rules/security/SEC-005.js.map +1 -0
- package/dist/rules/security/SEC-006.d.ts +10 -0
- package/dist/rules/security/SEC-006.js +108 -0
- package/dist/rules/security/SEC-006.js.map +1 -0
- package/dist/rules/security/SEC-007.d.ts +9 -0
- package/dist/rules/security/SEC-007.js +108 -0
- package/dist/rules/security/SEC-007.js.map +1 -0
- package/dist/rules/security/SEC-008.d.ts +8 -0
- package/dist/rules/security/SEC-008.js +109 -0
- package/dist/rules/security/SEC-008.js.map +1 -0
- package/dist/rules/security/SEC-009.d.ts +9 -0
- package/dist/rules/security/SEC-009.js +93 -0
- package/dist/rules/security/SEC-009.js.map +1 -0
- package/dist/rules/security/SEC-010.d.ts +8 -0
- package/dist/rules/security/SEC-010.js +78 -0
- package/dist/rules/security/SEC-010.js.map +1 -0
- package/dist/rules/security/SEC-011.d.ts +8 -0
- package/dist/rules/security/SEC-011.js +93 -0
- package/dist/rules/security/SEC-011.js.map +1 -0
- package/dist/rules/security/SEC-012.d.ts +8 -0
- package/dist/rules/security/SEC-012.js +79 -0
- package/dist/rules/security/SEC-012.js.map +1 -0
- package/dist/rules/security/SEC-013.d.ts +9 -0
- package/dist/rules/security/SEC-013.js +107 -0
- package/dist/rules/security/SEC-013.js.map +1 -0
- package/dist/scoring/calculator.js +1 -0
- package/dist/scoring/calculator.js.map +1 -1
- package/dist/ui/ink/components/AIRecommendationCard.d.ts +11 -0
- package/dist/ui/ink/components/AIRecommendationCard.js +23 -0
- package/dist/ui/ink/components/AIRecommendationCard.js.map +1 -0
- package/dist/ui/ink/components/OpportunityList.d.ts +10 -0
- package/dist/ui/ink/components/OpportunityList.js +48 -0
- package/dist/ui/ink/components/OpportunityList.js.map +1 -0
- package/dist/ui/ink/components/PotentialPageCard.d.ts +13 -0
- package/dist/ui/ink/components/PotentialPageCard.js +43 -0
- package/dist/ui/ink/components/PotentialPageCard.js.map +1 -0
- package/dist/ui/ink/components/PotentialProgress.d.ts +16 -0
- package/dist/ui/ink/components/PotentialProgress.js +44 -0
- package/dist/ui/ink/components/PotentialProgress.js.map +1 -0
- package/dist/ui/ink/components/PotentialSummary.d.ts +10 -0
- package/dist/ui/ink/components/PotentialSummary.js +86 -0
- package/dist/ui/ink/components/PotentialSummary.js.map +1 -0
- package/dist/ui/ink/components/SuggestionCard.d.ts +34 -0
- package/dist/ui/ink/components/SuggestionCard.js +36 -0
- package/dist/ui/ink/components/SuggestionCard.js.map +1 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.d.ts +21 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.js +55 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.js.map +1 -0
- package/dist/ui/ink/components/views/PotentialView.d.ts +18 -0
- package/dist/ui/ink/components/views/PotentialView.js +74 -0
- package/dist/ui/ink/components/views/PotentialView.js.map +1 -0
- package/dist/ui/ink/components/views/ReconView.d.ts +22 -0
- package/dist/ui/ink/components/views/ReconView.js +30 -0
- package/dist/ui/ink/components/views/ReconView.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form-to-Tool Mapper
|
|
3
|
+
*
|
|
4
|
+
* Takes unregistered HTML forms and generates complete WebMCP tool definitions
|
|
5
|
+
* by mapping form fields to JSON Schema properties.
|
|
6
|
+
*/
|
|
7
|
+
import type { UnregisteredForm } from '../core/types/tool.js';
|
|
8
|
+
import type { ToolInputSchema } from '../core/types/tool.js';
|
|
9
|
+
/**
|
|
10
|
+
* A suggested WebMCP tool definition generated from an unregistered form
|
|
11
|
+
*/
|
|
12
|
+
export interface SuggestedTool {
|
|
13
|
+
/** Kebab-case tool name */
|
|
14
|
+
suggestedName: string;
|
|
15
|
+
/** Human-readable description */
|
|
16
|
+
suggestedDescription: string;
|
|
17
|
+
/** JSON Schema for inputs */
|
|
18
|
+
suggestedSchema: ToolInputSchema;
|
|
19
|
+
/** How valuable this tool is for AI agents */
|
|
20
|
+
agenticValue: 'critical' | 'high' | 'medium' | 'low';
|
|
21
|
+
/** Estimated score improvement if implemented */
|
|
22
|
+
estimatedScoreImpact: number;
|
|
23
|
+
/** Source form metadata */
|
|
24
|
+
sourceForm: {
|
|
25
|
+
index: number;
|
|
26
|
+
action: string | null;
|
|
27
|
+
method: string;
|
|
28
|
+
fieldCount: number;
|
|
29
|
+
pageUrl: string;
|
|
30
|
+
};
|
|
31
|
+
/** Annotations hint for the tool */
|
|
32
|
+
annotations: {
|
|
33
|
+
readOnlyHint: boolean;
|
|
34
|
+
destructiveHint: boolean;
|
|
35
|
+
requiresConfirmation: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** Hidden fields present in the form */
|
|
38
|
+
hiddenFields: HiddenFieldInfo[];
|
|
39
|
+
}
|
|
40
|
+
export interface HiddenFieldInfo {
|
|
41
|
+
name: string;
|
|
42
|
+
value: string | null;
|
|
43
|
+
metadata: 'hidden-field';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate a tool name from form context clues.
|
|
47
|
+
* Uses form action URL, id, submit text, or field analysis to produce a kebab-case name.
|
|
48
|
+
*/
|
|
49
|
+
export declare function generateToolName(form: UnregisteredForm): string;
|
|
50
|
+
/**
|
|
51
|
+
* Generate a tool description from form context
|
|
52
|
+
*/
|
|
53
|
+
export declare function generateToolDescription(form: UnregisteredForm): string;
|
|
54
|
+
/**
|
|
55
|
+
* Map a single unregistered form to a SuggestedTool definition
|
|
56
|
+
*/
|
|
57
|
+
export declare function mapFormToTool(form: UnregisteredForm, html?: string): SuggestedTool;
|
|
58
|
+
/**
|
|
59
|
+
* Map all unregistered forms to suggested tools
|
|
60
|
+
*/
|
|
61
|
+
export declare function mapFormsToTools(forms: UnregisteredForm[], html?: string): SuggestedTool[];
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form-to-Tool Mapper
|
|
3
|
+
*
|
|
4
|
+
* Takes unregistered HTML forms and generates complete WebMCP tool definitions
|
|
5
|
+
* by mapping form fields to JSON Schema properties.
|
|
6
|
+
*/
|
|
7
|
+
import * as cheerio from 'cheerio';
|
|
8
|
+
import { INPUT_TYPE_MAP } from '../core/constants.js';
|
|
9
|
+
/**
|
|
10
|
+
* Map an HTML input type to a JSON Schema type
|
|
11
|
+
*/
|
|
12
|
+
function mapInputTypeToSchema(inputType) {
|
|
13
|
+
const mapped = INPUT_TYPE_MAP[inputType.toLowerCase()];
|
|
14
|
+
if (mapped === 'number')
|
|
15
|
+
return 'number';
|
|
16
|
+
if (mapped === 'boolean')
|
|
17
|
+
return 'boolean';
|
|
18
|
+
return 'string';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Map an HTML input type to a JSON Schema format string, if applicable
|
|
22
|
+
*/
|
|
23
|
+
function mapInputTypeToFormat(inputType) {
|
|
24
|
+
const formatMap = {
|
|
25
|
+
email: 'email',
|
|
26
|
+
url: 'uri',
|
|
27
|
+
date: 'date',
|
|
28
|
+
'datetime-local': 'date-time',
|
|
29
|
+
time: 'time',
|
|
30
|
+
};
|
|
31
|
+
return formatMap[inputType.toLowerCase()];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generate a tool name from form context clues.
|
|
35
|
+
* Uses form action URL, id, submit text, or field analysis to produce a kebab-case name.
|
|
36
|
+
*/
|
|
37
|
+
export function generateToolName(form) {
|
|
38
|
+
const clues = form.contextClues;
|
|
39
|
+
// Try form id first
|
|
40
|
+
if (clues.formId) {
|
|
41
|
+
return toKebabCase(clues.formId);
|
|
42
|
+
}
|
|
43
|
+
// Try form action URL path
|
|
44
|
+
if (clues.formAction && clues.formAction !== '#' && clues.formAction !== '') {
|
|
45
|
+
const actionName = extractNameFromAction(clues.formAction);
|
|
46
|
+
if (actionName)
|
|
47
|
+
return actionName;
|
|
48
|
+
}
|
|
49
|
+
// Try submit button text
|
|
50
|
+
if (clues.submitText) {
|
|
51
|
+
const cleaned = clues.submitText.replace(/[^a-zA-Z0-9\s]/g, '').trim();
|
|
52
|
+
if (cleaned.length > 0 && cleaned.length < 40) {
|
|
53
|
+
return toKebabCase(cleaned);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Try nearest heading
|
|
57
|
+
if (clues.nearestHeading) {
|
|
58
|
+
const cleaned = clues.nearestHeading.replace(/[^a-zA-Z0-9\s]/g, '').trim();
|
|
59
|
+
if (cleaned.length > 0 && cleaned.length < 40) {
|
|
60
|
+
return toKebabCase(cleaned);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Try aria-label
|
|
64
|
+
if (clues.ariaLabel) {
|
|
65
|
+
return toKebabCase(clues.ariaLabel);
|
|
66
|
+
}
|
|
67
|
+
// Fallback: infer from field names
|
|
68
|
+
const fieldBased = inferNameFromFields(clues.fieldNames);
|
|
69
|
+
if (fieldBased)
|
|
70
|
+
return fieldBased;
|
|
71
|
+
// Last resort
|
|
72
|
+
return `form-${form.index}`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract a meaningful name from a form action URL
|
|
76
|
+
*/
|
|
77
|
+
function extractNameFromAction(action) {
|
|
78
|
+
try {
|
|
79
|
+
// Handle relative and absolute URLs
|
|
80
|
+
const path = action.startsWith('http')
|
|
81
|
+
? new URL(action).pathname
|
|
82
|
+
: action.split('?')[0] ?? action;
|
|
83
|
+
// Get the last meaningful segment
|
|
84
|
+
const segments = path
|
|
85
|
+
.split('/')
|
|
86
|
+
.filter((s) => s.length > 0 && !s.startsWith(':') && !s.startsWith('{'));
|
|
87
|
+
if (segments.length === 0)
|
|
88
|
+
return null;
|
|
89
|
+
// Use the last 1-2 segments
|
|
90
|
+
const relevant = segments.slice(-2).join('-');
|
|
91
|
+
const cleaned = relevant.replace(/[^a-zA-Z0-9-]/g, '');
|
|
92
|
+
return cleaned.length > 0 ? toKebabCase(cleaned) : null;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Infer a tool name from field names
|
|
100
|
+
*/
|
|
101
|
+
function inferNameFromFields(fieldNames) {
|
|
102
|
+
const meaningful = fieldNames.filter((n) => n.length > 0 && !['csrf', 'token', '_method', 'utf8'].includes(n.toLowerCase()));
|
|
103
|
+
if (meaningful.length === 0)
|
|
104
|
+
return null;
|
|
105
|
+
// Check for common patterns
|
|
106
|
+
const joined = meaningful.join(' ').toLowerCase();
|
|
107
|
+
if (/search|query|q\b/.test(joined))
|
|
108
|
+
return 'search';
|
|
109
|
+
if (/login|signin|username.*password/.test(joined))
|
|
110
|
+
return 'login';
|
|
111
|
+
if (/register|signup/.test(joined))
|
|
112
|
+
return 'register';
|
|
113
|
+
if (/subscribe|newsletter|email/.test(joined))
|
|
114
|
+
return 'subscribe';
|
|
115
|
+
if (/contact|message|subject.*body/.test(joined))
|
|
116
|
+
return 'send-message';
|
|
117
|
+
if (/comment|reply/.test(joined))
|
|
118
|
+
return 'post-comment';
|
|
119
|
+
if (/filter|sort/.test(joined))
|
|
120
|
+
return 'filter';
|
|
121
|
+
if (/checkout|payment|card/.test(joined))
|
|
122
|
+
return 'checkout';
|
|
123
|
+
if (/address|shipping/.test(joined))
|
|
124
|
+
return 'submit-address';
|
|
125
|
+
if (/review|rating/.test(joined))
|
|
126
|
+
return 'submit-review';
|
|
127
|
+
// Use first 2-3 field names
|
|
128
|
+
const nameFields = meaningful.slice(0, 3);
|
|
129
|
+
return toKebabCase(nameFields.join('-'));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Convert a string to kebab-case
|
|
133
|
+
*/
|
|
134
|
+
function toKebabCase(str) {
|
|
135
|
+
return str
|
|
136
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
137
|
+
.replace(/[\s_]+/g, '-')
|
|
138
|
+
.replace(/[^a-zA-Z0-9-]/g, '')
|
|
139
|
+
.replace(/-+/g, '-')
|
|
140
|
+
.replace(/^-|-$/g, '')
|
|
141
|
+
.toLowerCase()
|
|
142
|
+
.substring(0, 50);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Generate a tool description from form context
|
|
146
|
+
*/
|
|
147
|
+
export function generateToolDescription(form) {
|
|
148
|
+
const clues = form.contextClues;
|
|
149
|
+
const parts = [];
|
|
150
|
+
// Start with heading context
|
|
151
|
+
if (clues.nearestHeading) {
|
|
152
|
+
parts.push(clues.nearestHeading);
|
|
153
|
+
}
|
|
154
|
+
// Add submit text context
|
|
155
|
+
if (clues.submitText) {
|
|
156
|
+
const verb = clues.submitText.toLowerCase();
|
|
157
|
+
if (!parts.some((p) => p.toLowerCase().includes(verb))) {
|
|
158
|
+
parts.push(clues.submitText);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Add field description context
|
|
162
|
+
const fieldDesc = describeFields(form);
|
|
163
|
+
if (fieldDesc) {
|
|
164
|
+
parts.push(fieldDesc);
|
|
165
|
+
}
|
|
166
|
+
if (parts.length === 0) {
|
|
167
|
+
// Fallback based on method
|
|
168
|
+
const method = clues.formMethod.toUpperCase();
|
|
169
|
+
if (method === 'GET') {
|
|
170
|
+
return `Query data using ${form.fieldCount} parameter(s)`;
|
|
171
|
+
}
|
|
172
|
+
return `Submit form data with ${form.fieldCount} field(s)`;
|
|
173
|
+
}
|
|
174
|
+
// Construct a coherent sentence
|
|
175
|
+
const context = parts.join(' - ');
|
|
176
|
+
return context.charAt(0).toUpperCase() + context.slice(1);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Describe fields in a human-readable way
|
|
180
|
+
*/
|
|
181
|
+
function describeFields(form) {
|
|
182
|
+
const labels = form.fields
|
|
183
|
+
.map((f) => f.label ?? f.placeholder ?? f.name)
|
|
184
|
+
.filter((l) => l.length > 0)
|
|
185
|
+
.slice(0, 4);
|
|
186
|
+
if (labels.length === 0)
|
|
187
|
+
return null;
|
|
188
|
+
if (labels.length <= 3) {
|
|
189
|
+
return `Accepts ${labels.join(', ')}`;
|
|
190
|
+
}
|
|
191
|
+
return `Accepts ${labels.slice(0, 3).join(', ')}, and more`;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Map a single form field to a JSON Schema property
|
|
195
|
+
*/
|
|
196
|
+
function mapFieldToProperty(field) {
|
|
197
|
+
const prop = {
|
|
198
|
+
type: mapInputTypeToSchema(field.type),
|
|
199
|
+
};
|
|
200
|
+
// Description from label or placeholder
|
|
201
|
+
const desc = field.label ?? field.placeholder;
|
|
202
|
+
if (desc) {
|
|
203
|
+
prop.description = desc;
|
|
204
|
+
}
|
|
205
|
+
// Format from input type
|
|
206
|
+
const format = mapInputTypeToFormat(field.type);
|
|
207
|
+
if (format) {
|
|
208
|
+
prop.format = format;
|
|
209
|
+
}
|
|
210
|
+
// Enum for select options
|
|
211
|
+
if (field.options && field.options.length > 0) {
|
|
212
|
+
prop.enum = field.options
|
|
213
|
+
.filter((o) => o.value !== '')
|
|
214
|
+
.map((o) => o.value);
|
|
215
|
+
}
|
|
216
|
+
// Checkbox -> boolean
|
|
217
|
+
if (field.type === 'checkbox') {
|
|
218
|
+
prop.type = 'boolean';
|
|
219
|
+
}
|
|
220
|
+
return prop;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Build a complete JSON Schema from form fields, handling radio groups
|
|
224
|
+
*/
|
|
225
|
+
function buildSchemaFromFields(form, html) {
|
|
226
|
+
const properties = {};
|
|
227
|
+
const required = [];
|
|
228
|
+
const hiddenFields = [];
|
|
229
|
+
const seenRadioGroups = new Set();
|
|
230
|
+
// Process visible fields
|
|
231
|
+
for (const field of form.fields) {
|
|
232
|
+
if (!field.name)
|
|
233
|
+
continue;
|
|
234
|
+
// Radio groups: only process once per name
|
|
235
|
+
if (field.type === 'radio') {
|
|
236
|
+
if (seenRadioGroups.has(field.name))
|
|
237
|
+
continue;
|
|
238
|
+
seenRadioGroups.add(field.name);
|
|
239
|
+
// Collect all radio options from the form HTML if available
|
|
240
|
+
if (html && form.formOuterHTML) {
|
|
241
|
+
const radioOptions = extractRadioOptions(form.formOuterHTML, field.name);
|
|
242
|
+
if (radioOptions.length > 0) {
|
|
243
|
+
properties[field.name] = {
|
|
244
|
+
type: 'string',
|
|
245
|
+
enum: radioOptions.map((o) => o.value),
|
|
246
|
+
description: field.label ?? undefined,
|
|
247
|
+
};
|
|
248
|
+
if (field.required)
|
|
249
|
+
required.push(field.name);
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
properties[field.name] = mapFieldToProperty(field);
|
|
255
|
+
if (field.required) {
|
|
256
|
+
required.push(field.name);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Extract hidden fields from form HTML
|
|
260
|
+
if (form.formOuterHTML) {
|
|
261
|
+
const $ = cheerio.load(form.formOuterHTML);
|
|
262
|
+
$('input[type=hidden]').each((_i, el) => {
|
|
263
|
+
const name = $(el).attr('name');
|
|
264
|
+
if (name) {
|
|
265
|
+
hiddenFields.push({
|
|
266
|
+
name,
|
|
267
|
+
value: $(el).attr('value') ?? null,
|
|
268
|
+
metadata: 'hidden-field',
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
schema: {
|
|
275
|
+
type: 'object',
|
|
276
|
+
properties,
|
|
277
|
+
required: required.length > 0 ? required : undefined,
|
|
278
|
+
},
|
|
279
|
+
hiddenFields,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Extract radio button options from HTML snippet
|
|
284
|
+
*/
|
|
285
|
+
function extractRadioOptions(html, name) {
|
|
286
|
+
const $ = cheerio.load(html);
|
|
287
|
+
const options = [];
|
|
288
|
+
$(`input[type=radio][name="${name}"]`).each((_i, el) => {
|
|
289
|
+
const $el = $(el);
|
|
290
|
+
const value = $el.attr('value') ?? '';
|
|
291
|
+
const text = $el.closest('label').text().trim() ||
|
|
292
|
+
$el.next('label').text().trim() ||
|
|
293
|
+
value;
|
|
294
|
+
options.push({ value, text });
|
|
295
|
+
});
|
|
296
|
+
return options;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Estimate the agentic value score impact of implementing a tool
|
|
300
|
+
*/
|
|
301
|
+
function estimateScoreImpact(agenticValue, fieldCount) {
|
|
302
|
+
const baseImpact = {
|
|
303
|
+
critical: 8,
|
|
304
|
+
high: 5,
|
|
305
|
+
medium: 3,
|
|
306
|
+
low: 1,
|
|
307
|
+
};
|
|
308
|
+
const base = baseImpact[agenticValue] ?? 2;
|
|
309
|
+
// Larger forms have more impact
|
|
310
|
+
const complexity = Math.min(fieldCount / 5, 1.5);
|
|
311
|
+
return Math.round(base * (1 + complexity * 0.3));
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Determine annotation hints from form context
|
|
315
|
+
*/
|
|
316
|
+
function inferAnnotations(form) {
|
|
317
|
+
const method = form.contextClues.formMethod.toUpperCase();
|
|
318
|
+
const isReadOnly = method === 'GET';
|
|
319
|
+
const isDestructive = form.contextClues.hasPaymentFields ||
|
|
320
|
+
/delete|remove|cancel/i.test([form.contextClues.submitText ?? '', form.contextClues.formAction ?? ''].join(' '));
|
|
321
|
+
const requiresConfirmation = form.sensitivity === 'critical' ||
|
|
322
|
+
form.sensitivity === 'high' ||
|
|
323
|
+
isDestructive;
|
|
324
|
+
return {
|
|
325
|
+
readOnlyHint: isReadOnly,
|
|
326
|
+
destructiveHint: isDestructive,
|
|
327
|
+
requiresConfirmation,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Map a single unregistered form to a SuggestedTool definition
|
|
332
|
+
*/
|
|
333
|
+
export function mapFormToTool(form, html) {
|
|
334
|
+
const suggestedName = generateToolName(form);
|
|
335
|
+
const suggestedDescription = generateToolDescription(form);
|
|
336
|
+
const { schema, hiddenFields } = buildSchemaFromFields(form, html);
|
|
337
|
+
return {
|
|
338
|
+
suggestedName,
|
|
339
|
+
suggestedDescription,
|
|
340
|
+
suggestedSchema: schema,
|
|
341
|
+
agenticValue: form.agenticValue,
|
|
342
|
+
estimatedScoreImpact: estimateScoreImpact(form.agenticValue, form.fieldCount),
|
|
343
|
+
sourceForm: {
|
|
344
|
+
index: form.index,
|
|
345
|
+
action: form.contextClues.formAction,
|
|
346
|
+
method: form.contextClues.formMethod,
|
|
347
|
+
fieldCount: form.fieldCount,
|
|
348
|
+
pageUrl: form.pageUrl ?? '',
|
|
349
|
+
},
|
|
350
|
+
annotations: inferAnnotations(form),
|
|
351
|
+
hiddenFields,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Map all unregistered forms to suggested tools
|
|
356
|
+
*/
|
|
357
|
+
export function mapFormsToTools(forms, html) {
|
|
358
|
+
return forms.map((form) => mapFormToTool(form, html));
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=form-to-tool-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-to-tool-mapper.js","sourceRoot":"","sources":["../../src/analysis/form-to-tool-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Module
|
|
3
|
+
*
|
|
4
|
+
* Integrates form-to-tool mapping, missing tool analysis, and code generation
|
|
5
|
+
* into a single suggestion pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import type { DetectedTool, UnregisteredForm } from '../core/types/tool.js';
|
|
8
|
+
import type { SuggestedTool } from './form-to-tool-mapper.js';
|
|
9
|
+
import type { InteractiveOpportunity } from './missing-tool-analyzer.js';
|
|
10
|
+
export { mapFormToTool, mapFormsToTools, generateToolName, generateToolDescription } from './form-to-tool-mapper.js';
|
|
11
|
+
export type { SuggestedTool, HiddenFieldInfo } from './form-to-tool-mapper.js';
|
|
12
|
+
export { analyzeForMissingTools } from './missing-tool-analyzer.js';
|
|
13
|
+
export type { InteractiveOpportunity } from './missing-tool-analyzer.js';
|
|
14
|
+
/**
|
|
15
|
+
* Input data for the analysis pipeline
|
|
16
|
+
*/
|
|
17
|
+
export interface PageAnalysisData {
|
|
18
|
+
/** Raw HTML content of the page */
|
|
19
|
+
html: string;
|
|
20
|
+
/** Page URL */
|
|
21
|
+
pageUrl: string;
|
|
22
|
+
/** Already detected WebMCP tools */
|
|
23
|
+
existingTools: DetectedTool[];
|
|
24
|
+
/** Unregistered forms found by declarative scanner */
|
|
25
|
+
unregisteredForms: UnregisteredForm[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gap analysis summary
|
|
29
|
+
*/
|
|
30
|
+
export interface GapAnalysis {
|
|
31
|
+
/** Total interactive elements found */
|
|
32
|
+
totalInteractiveElements: number;
|
|
33
|
+
/** Elements already covered by WebMCP tools */
|
|
34
|
+
coveredElements: number;
|
|
35
|
+
/** Elements that should have WebMCP tools */
|
|
36
|
+
uncoveredElements: number;
|
|
37
|
+
/** Coverage ratio (0-1) */
|
|
38
|
+
coverageRatio: number;
|
|
39
|
+
/** Breakdown by element type */
|
|
40
|
+
breakdown: {
|
|
41
|
+
forms: {
|
|
42
|
+
total: number;
|
|
43
|
+
covered: number;
|
|
44
|
+
};
|
|
45
|
+
search: {
|
|
46
|
+
total: number;
|
|
47
|
+
covered: number;
|
|
48
|
+
};
|
|
49
|
+
filters: {
|
|
50
|
+
total: number;
|
|
51
|
+
covered: number;
|
|
52
|
+
};
|
|
53
|
+
actions: {
|
|
54
|
+
total: number;
|
|
55
|
+
covered: number;
|
|
56
|
+
};
|
|
57
|
+
navigation: {
|
|
58
|
+
total: number;
|
|
59
|
+
covered: number;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Complete result from the suggestion engine
|
|
65
|
+
*/
|
|
66
|
+
export interface SuggestionResult {
|
|
67
|
+
/** Tools suggested from unregistered forms */
|
|
68
|
+
suggestedTools: SuggestedTool[];
|
|
69
|
+
/** Interactive elements detected as opportunities */
|
|
70
|
+
interactiveOpportunities: InteractiveOpportunity[];
|
|
71
|
+
/** Combined generated code (JS + HTML) */
|
|
72
|
+
codeOutput: {
|
|
73
|
+
combinedJS: string;
|
|
74
|
+
combinedHTML: string;
|
|
75
|
+
};
|
|
76
|
+
/** Gap analysis summary */
|
|
77
|
+
gapAnalysis: GapAnalysis;
|
|
78
|
+
/** Projected score improvement if all suggestions are implemented */
|
|
79
|
+
projectedScoreImprovement: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Main entry point: analyze a page and produce tool suggestions
|
|
83
|
+
*/
|
|
84
|
+
export declare function analyzeAndSuggest(data: PageAnalysisData): SuggestionResult;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Module
|
|
3
|
+
*
|
|
4
|
+
* Integrates form-to-tool mapping, missing tool analysis, and code generation
|
|
5
|
+
* into a single suggestion pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import { mapFormsToTools } from './form-to-tool-mapper.js';
|
|
8
|
+
import { analyzeForMissingTools } from './missing-tool-analyzer.js';
|
|
9
|
+
import { generateCombinedCode } from '../generators/tool-code-generator.js';
|
|
10
|
+
export { mapFormToTool, mapFormsToTools, generateToolName, generateToolDescription } from './form-to-tool-mapper.js';
|
|
11
|
+
export { analyzeForMissingTools } from './missing-tool-analyzer.js';
|
|
12
|
+
/**
|
|
13
|
+
* Main entry point: analyze a page and produce tool suggestions
|
|
14
|
+
*/
|
|
15
|
+
export function analyzeAndSuggest(data) {
|
|
16
|
+
// 1. Map unregistered forms to suggested tools
|
|
17
|
+
const suggestedTools = mapFormsToTools(data.unregisteredForms, data.html);
|
|
18
|
+
// 2. Analyze for missing interactive tool opportunities
|
|
19
|
+
const interactiveOpportunities = analyzeForMissingTools(data.html, data.existingTools, data.pageUrl);
|
|
20
|
+
// 3. Generate code for form-based suggestions
|
|
21
|
+
const codeOutput = generateCombinedCode(suggestedTools);
|
|
22
|
+
// 4. Compute gap analysis
|
|
23
|
+
const gapAnalysis = computeGapAnalysis(data, suggestedTools, interactiveOpportunities);
|
|
24
|
+
// 5. Estimate projected score improvement
|
|
25
|
+
const projectedScoreImprovement = estimateProjectedImprovement(suggestedTools, interactiveOpportunities);
|
|
26
|
+
return {
|
|
27
|
+
suggestedTools,
|
|
28
|
+
interactiveOpportunities,
|
|
29
|
+
codeOutput,
|
|
30
|
+
gapAnalysis,
|
|
31
|
+
projectedScoreImprovement,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Compute the gap analysis for a page
|
|
36
|
+
*/
|
|
37
|
+
function computeGapAnalysis(data, suggestedTools, opportunities) {
|
|
38
|
+
const formsCovered = data.existingTools.filter((t) => t.source === 'declarative').length;
|
|
39
|
+
const formsTotal = formsCovered + data.unregisteredForms.length;
|
|
40
|
+
const searchOpps = opportunities.filter((o) => o.elementType === 'search');
|
|
41
|
+
const filterOpps = opportunities.filter((o) => o.elementType === 'filter');
|
|
42
|
+
const actionOpps = opportunities.filter((o) => o.elementType === 'action-button');
|
|
43
|
+
const navOpps = opportunities.filter((o) => o.elementType === 'navigation');
|
|
44
|
+
// Count existing tools that cover each category
|
|
45
|
+
const existingNames = data.existingTools.map((t) => t.name.toLowerCase());
|
|
46
|
+
const searchCovered = existingNames.some((n) => /search|find|query/.test(n)) ? 1 : 0;
|
|
47
|
+
const filterCovered = existingNames.some((n) => /filter|sort|refine/.test(n)) ? 1 : 0;
|
|
48
|
+
const totalInteractive = formsTotal +
|
|
49
|
+
searchOpps.length + searchCovered +
|
|
50
|
+
filterOpps.length + filterCovered +
|
|
51
|
+
actionOpps.length +
|
|
52
|
+
navOpps.length;
|
|
53
|
+
const covered = formsCovered +
|
|
54
|
+
searchCovered +
|
|
55
|
+
filterCovered;
|
|
56
|
+
const uncovered = totalInteractive - covered;
|
|
57
|
+
const coverageRatio = totalInteractive > 0 ? covered / totalInteractive : 1;
|
|
58
|
+
return {
|
|
59
|
+
totalInteractiveElements: totalInteractive,
|
|
60
|
+
coveredElements: covered,
|
|
61
|
+
uncoveredElements: uncovered,
|
|
62
|
+
coverageRatio,
|
|
63
|
+
breakdown: {
|
|
64
|
+
forms: { total: formsTotal, covered: formsCovered },
|
|
65
|
+
search: { total: searchOpps.length + searchCovered, covered: searchCovered },
|
|
66
|
+
filters: { total: filterOpps.length + filterCovered, covered: filterCovered },
|
|
67
|
+
actions: { total: actionOpps.length, covered: 0 },
|
|
68
|
+
navigation: { total: navOpps.length, covered: 0 },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Estimate projected score improvement from implementing all suggestions
|
|
74
|
+
*/
|
|
75
|
+
function estimateProjectedImprovement(suggestedTools, opportunities) {
|
|
76
|
+
const formImpact = suggestedTools.reduce((sum, t) => sum + t.estimatedScoreImpact, 0);
|
|
77
|
+
const interactiveImpact = opportunities.reduce((sum, o) => sum + o.estimatedScoreImpact, 0);
|
|
78
|
+
// Cap at reasonable maximum (coverage category is only 5% weight)
|
|
79
|
+
return Math.min(formImpact + interactiveImpact, 25);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Missing Tool Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects interactive elements that SHOULD be WebMCP tools but aren't:
|
|
5
|
+
* search inputs, filter controls, action buttons, navigation patterns,
|
|
6
|
+
* and JS-only functionality.
|
|
7
|
+
*/
|
|
8
|
+
import type { DetectedTool, ToolInputSchema } from '../core/types/tool.js';
|
|
9
|
+
/**
|
|
10
|
+
* An interactive element detected as a potential tool opportunity
|
|
11
|
+
*/
|
|
12
|
+
export interface InteractiveOpportunity {
|
|
13
|
+
/** Type of interactive element detected */
|
|
14
|
+
elementType: 'search' | 'filter' | 'action-button' | 'navigation' | 'js-interactive';
|
|
15
|
+
/** Suggested tool name in kebab-case */
|
|
16
|
+
suggestedName: string;
|
|
17
|
+
/** Suggested tool description */
|
|
18
|
+
suggestedDescription: string;
|
|
19
|
+
/** Suggested input schema */
|
|
20
|
+
suggestedSchema: ToolInputSchema;
|
|
21
|
+
/** How valuable this tool is for AI agents */
|
|
22
|
+
agenticValue: 'critical' | 'high' | 'medium' | 'low';
|
|
23
|
+
/** Estimated score improvement if implemented */
|
|
24
|
+
estimatedScoreImpact: number;
|
|
25
|
+
/** HTML snippet of the detected element */
|
|
26
|
+
elementHTML: string;
|
|
27
|
+
/** Selector that identifies the element */
|
|
28
|
+
selector: string;
|
|
29
|
+
/** Confidence level (0-1) */
|
|
30
|
+
confidence: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Analyze HTML for interactive elements that should be WebMCP tools
|
|
34
|
+
*/
|
|
35
|
+
export declare function analyzeForMissingTools(html: string, existingTools: DetectedTool[], pageUrl: string): InteractiveOpportunity[];
|