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,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-009: Cross-Origin Awareness
|
|
3
|
+
*
|
|
4
|
+
* Flags tools that send data to cross-origin destinations.
|
|
5
|
+
* This is informational — not necessarily bad, but agents should
|
|
6
|
+
* be aware of cross-origin data flow.
|
|
7
|
+
*/
|
|
8
|
+
import { createRuleResult } from '../runner.js';
|
|
9
|
+
function extractDomain(url) {
|
|
10
|
+
try {
|
|
11
|
+
return new URL(url).hostname;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export const SEC_009 = {
|
|
18
|
+
id: 'SEC-009',
|
|
19
|
+
category: 'security',
|
|
20
|
+
name: 'Cross-Origin Awareness',
|
|
21
|
+
description: 'Tools that send data cross-origin should be flagged for awareness',
|
|
22
|
+
severity: 'info',
|
|
23
|
+
maxScore: 5,
|
|
24
|
+
async check(context) {
|
|
25
|
+
const tools = context.tools;
|
|
26
|
+
if (tools.length === 0) {
|
|
27
|
+
return createRuleResult('SEC-009', 5, {
|
|
28
|
+
passed: true,
|
|
29
|
+
score: 5,
|
|
30
|
+
message: 'No tools detected (rule not applicable)',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const pageDomain = extractDomain(context.url);
|
|
34
|
+
const crossOriginTools = [];
|
|
35
|
+
for (const tool of tools) {
|
|
36
|
+
// Check declarative form actions
|
|
37
|
+
if (tool.formData?.formAction) {
|
|
38
|
+
const actionDomain = extractDomain(tool.formData.formAction);
|
|
39
|
+
if (actionDomain &&
|
|
40
|
+
pageDomain &&
|
|
41
|
+
actionDomain !== pageDomain &&
|
|
42
|
+
!actionDomain.endsWith(`.${pageDomain}`)) {
|
|
43
|
+
crossOriginTools.push({
|
|
44
|
+
name: tool.name,
|
|
45
|
+
target: actionDomain,
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Check execute source for cross-origin fetches
|
|
51
|
+
const src = tool.executeSource ?? '';
|
|
52
|
+
const urlRegex = /fetch\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = urlRegex.exec(src)) !== null) {
|
|
55
|
+
const url = match[1];
|
|
56
|
+
if (!url)
|
|
57
|
+
continue;
|
|
58
|
+
const domain = extractDomain(url);
|
|
59
|
+
if (domain &&
|
|
60
|
+
pageDomain &&
|
|
61
|
+
domain !== pageDomain &&
|
|
62
|
+
!domain.endsWith(`.${pageDomain}`) &&
|
|
63
|
+
!url.startsWith('/')) {
|
|
64
|
+
crossOriginTools.push({ name: tool.name, target: domain });
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (crossOriginTools.length === 0) {
|
|
70
|
+
return createRuleResult('SEC-009', 5, {
|
|
71
|
+
passed: true,
|
|
72
|
+
score: 5,
|
|
73
|
+
message: 'No cross-origin data flows detected',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Informational — partial deduction only
|
|
77
|
+
const penalty = Math.min(crossOriginTools.length, 3);
|
|
78
|
+
const score = Math.max(0, 5 - penalty);
|
|
79
|
+
return createRuleResult('SEC-009', 5, {
|
|
80
|
+
passed: false,
|
|
81
|
+
score,
|
|
82
|
+
message: `${crossOriginTools.length} tool(s) send data cross-origin`,
|
|
83
|
+
details: crossOriginTools.map((t) => `Tool "${t.name}" sends data to cross-origin domain: ${t.target}`),
|
|
84
|
+
suggestions: [
|
|
85
|
+
'Document cross-origin data flows in the tool description',
|
|
86
|
+
'Consider whether cross-origin requests are necessary',
|
|
87
|
+
'Ensure user consent for data sent to third-party domains',
|
|
88
|
+
],
|
|
89
|
+
affectedTools: crossOriginTools.map((t) => t.name),
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=SEC-009.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-009.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-009.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-010: Service Worker Isolation
|
|
3
|
+
*
|
|
4
|
+
* Checks that tools registered in a service worker context
|
|
5
|
+
* use clientInfo.sessionId for proper session isolation.
|
|
6
|
+
*/
|
|
7
|
+
import { createRuleResult } from '../runner.js';
|
|
8
|
+
const SERVICE_WORKER_PATTERNS = [
|
|
9
|
+
/serviceWorker/,
|
|
10
|
+
/self\.addEventListener\s*\(\s*['"](?:fetch|install|activate)/,
|
|
11
|
+
/ServiceWorkerGlobalScope/,
|
|
12
|
+
/importScripts\s*\(/,
|
|
13
|
+
];
|
|
14
|
+
const SESSION_ISOLATION_PATTERNS = [
|
|
15
|
+
/clientInfo\.sessionId/,
|
|
16
|
+
/sessionId/,
|
|
17
|
+
/client\.id/,
|
|
18
|
+
/clientId/,
|
|
19
|
+
];
|
|
20
|
+
export const SEC_010 = {
|
|
21
|
+
id: 'SEC-010',
|
|
22
|
+
category: 'security',
|
|
23
|
+
name: 'Service Worker Isolation',
|
|
24
|
+
description: 'Service worker tools should use clientInfo.sessionId for session isolation',
|
|
25
|
+
severity: 'warning',
|
|
26
|
+
maxScore: 5,
|
|
27
|
+
async check(context) {
|
|
28
|
+
const tools = context.tools;
|
|
29
|
+
if (tools.length === 0) {
|
|
30
|
+
return createRuleResult('SEC-010', 5, {
|
|
31
|
+
passed: true,
|
|
32
|
+
score: 5,
|
|
33
|
+
message: 'No tools detected (rule not applicable)',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Check scripts for service worker context
|
|
37
|
+
const hasServiceWorkerContext = (context.scripts ?? []).some((script) => SERVICE_WORKER_PATTERNS.some((p) => p.test(script.content)));
|
|
38
|
+
if (!hasServiceWorkerContext) {
|
|
39
|
+
return createRuleResult('SEC-010', 5, {
|
|
40
|
+
passed: true,
|
|
41
|
+
score: 5,
|
|
42
|
+
message: 'No service worker context detected (rule not applicable)',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const violations = [];
|
|
46
|
+
for (const tool of tools) {
|
|
47
|
+
const src = tool.executeSource ?? '';
|
|
48
|
+
if (src.length === 0)
|
|
49
|
+
continue;
|
|
50
|
+
const hasIsolation = SESSION_ISOLATION_PATTERNS.some((p) => p.test(src));
|
|
51
|
+
if (!hasIsolation) {
|
|
52
|
+
violations.push(tool.name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (violations.length === 0) {
|
|
56
|
+
return createRuleResult('SEC-010', 5, {
|
|
57
|
+
passed: true,
|
|
58
|
+
score: 5,
|
|
59
|
+
message: 'Service worker tools properly use session isolation',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const penalty = violations.length * 2;
|
|
63
|
+
const score = Math.max(0, 5 - penalty);
|
|
64
|
+
return createRuleResult('SEC-010', 5, {
|
|
65
|
+
passed: false,
|
|
66
|
+
score,
|
|
67
|
+
message: `${violations.length} service worker tool(s) lack session isolation`,
|
|
68
|
+
details: violations.map((name) => `Tool "${name}" in service worker context does not reference clientInfo.sessionId`),
|
|
69
|
+
suggestions: [
|
|
70
|
+
'Use clientInfo.sessionId to scope tool state per session',
|
|
71
|
+
'Service workers are shared across tabs — tools must isolate state',
|
|
72
|
+
'Example: const state = sessions.get(clientInfo.sessionId)',
|
|
73
|
+
],
|
|
74
|
+
affectedTools: violations,
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=SEC-010.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-010.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-010.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-011: Rate Limit Consideration
|
|
3
|
+
*
|
|
4
|
+
* Checks that repeatable tools (those that can be called many times)
|
|
5
|
+
* have some form of rate limiting or throttling to prevent abuse.
|
|
6
|
+
*/
|
|
7
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
8
|
+
export declare const SEC_011: Rule;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-011: Rate Limit Consideration
|
|
3
|
+
*
|
|
4
|
+
* Checks that repeatable tools (those that can be called many times)
|
|
5
|
+
* have some form of rate limiting or throttling to prevent abuse.
|
|
6
|
+
*/
|
|
7
|
+
import { createRuleResult } from '../runner.js';
|
|
8
|
+
const RATE_LIMIT_PATTERNS = [
|
|
9
|
+
/rateLimit/i,
|
|
10
|
+
/throttle/i,
|
|
11
|
+
/debounce/i,
|
|
12
|
+
/cooldown/i,
|
|
13
|
+
/lastCall/i,
|
|
14
|
+
/callCount/i,
|
|
15
|
+
/Date\.now\s*\(\s*\)\s*-/,
|
|
16
|
+
/setTimeout/,
|
|
17
|
+
/setInterval/,
|
|
18
|
+
/maxCalls/i,
|
|
19
|
+
/requestsPerMinute/i,
|
|
20
|
+
/rateLimited/i,
|
|
21
|
+
];
|
|
22
|
+
const REPEATABLE_KEYWORDS = [
|
|
23
|
+
'search',
|
|
24
|
+
'query',
|
|
25
|
+
'find',
|
|
26
|
+
'list',
|
|
27
|
+
'fetch',
|
|
28
|
+
'get',
|
|
29
|
+
'load',
|
|
30
|
+
'filter',
|
|
31
|
+
'browse',
|
|
32
|
+
'lookup',
|
|
33
|
+
'check',
|
|
34
|
+
'send',
|
|
35
|
+
'submit',
|
|
36
|
+
'post',
|
|
37
|
+
'create',
|
|
38
|
+
'add',
|
|
39
|
+
];
|
|
40
|
+
export const SEC_011 = {
|
|
41
|
+
id: 'SEC-011',
|
|
42
|
+
category: 'security',
|
|
43
|
+
name: 'Rate Limit Consideration',
|
|
44
|
+
description: 'Repeatable tools should have rate limiting or throttling',
|
|
45
|
+
severity: 'info',
|
|
46
|
+
maxScore: 5,
|
|
47
|
+
async check(context) {
|
|
48
|
+
const tools = context.tools;
|
|
49
|
+
if (tools.length === 0) {
|
|
50
|
+
return createRuleResult('SEC-011', 5, {
|
|
51
|
+
passed: true,
|
|
52
|
+
score: 5,
|
|
53
|
+
message: 'No tools detected (rule not applicable)',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const violations = [];
|
|
57
|
+
for (const tool of tools) {
|
|
58
|
+
const nameAndDesc = `${tool.name} ${tool.description}`.toLowerCase();
|
|
59
|
+
const isRepeatable = REPEATABLE_KEYWORDS.some((kw) => new RegExp(`\\b${kw}\\b`).test(nameAndDesc));
|
|
60
|
+
if (!isRepeatable)
|
|
61
|
+
continue;
|
|
62
|
+
const src = tool.executeSource ?? '';
|
|
63
|
+
if (src.length === 0)
|
|
64
|
+
continue;
|
|
65
|
+
const hasRateLimit = RATE_LIMIT_PATTERNS.some((p) => p.test(src));
|
|
66
|
+
if (!hasRateLimit) {
|
|
67
|
+
violations.push(tool.name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (violations.length === 0) {
|
|
71
|
+
return createRuleResult('SEC-011', 5, {
|
|
72
|
+
passed: true,
|
|
73
|
+
score: 5,
|
|
74
|
+
message: 'Repeatable tools have rate limiting considerations',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const penalty = Math.min(violations.length, 5);
|
|
78
|
+
const score = Math.max(0, 5 - penalty);
|
|
79
|
+
return createRuleResult('SEC-011', 5, {
|
|
80
|
+
passed: false,
|
|
81
|
+
score,
|
|
82
|
+
message: `${violations.length} repeatable tool(s) lack rate limiting`,
|
|
83
|
+
details: violations.map((name) => `Tool "${name}" is repeatable but has no visible rate limiting`),
|
|
84
|
+
suggestions: [
|
|
85
|
+
'Add rate limiting or throttling to tools that can be called repeatedly',
|
|
86
|
+
'Consider using debounce/throttle for search and query tools',
|
|
87
|
+
'Track call frequency and reject excessive requests',
|
|
88
|
+
],
|
|
89
|
+
affectedTools: violations,
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=SEC-011.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-011.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-011.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-012: Autosubmit Safety
|
|
3
|
+
*
|
|
4
|
+
* Checks that forms with toolautosubmit don't perform sensitive actions
|
|
5
|
+
* like payments, account deletion, or other critical operations.
|
|
6
|
+
*/
|
|
7
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
8
|
+
export declare const SEC_012: Rule;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-012: Autosubmit Safety
|
|
3
|
+
*
|
|
4
|
+
* Checks that forms with toolautosubmit don't perform sensitive actions
|
|
5
|
+
* like payments, account deletion, or other critical operations.
|
|
6
|
+
*/
|
|
7
|
+
import { createRuleResult } from '../runner.js';
|
|
8
|
+
const SENSITIVE_ACTION_PATTERNS = [
|
|
9
|
+
/\bpay\b/i,
|
|
10
|
+
/\bpurchase\b/i,
|
|
11
|
+
/\bcheckout\b/i,
|
|
12
|
+
/\bbuy\b/i,
|
|
13
|
+
/\bdelete\b/i,
|
|
14
|
+
/\bremove\b/i,
|
|
15
|
+
/\bdestroy\b/i,
|
|
16
|
+
/\btransfer\b/i,
|
|
17
|
+
/\bcancel\b/i,
|
|
18
|
+
/\bterminate\b/i,
|
|
19
|
+
/\bsubscribe\b/i,
|
|
20
|
+
/\bunsubscribe\b/i,
|
|
21
|
+
/\bpassword\b/i,
|
|
22
|
+
/\baccount\b.*\b(?:close|deactivate)\b/i,
|
|
23
|
+
];
|
|
24
|
+
export const SEC_012 = {
|
|
25
|
+
id: 'SEC-012',
|
|
26
|
+
category: 'security',
|
|
27
|
+
name: 'Autosubmit Safety',
|
|
28
|
+
description: 'Forms with toolautosubmit should not perform sensitive actions without confirmation',
|
|
29
|
+
severity: 'critical',
|
|
30
|
+
maxScore: 10,
|
|
31
|
+
async check(context) {
|
|
32
|
+
const tools = context.tools;
|
|
33
|
+
if (tools.length === 0) {
|
|
34
|
+
return createRuleResult('SEC-012', 10, {
|
|
35
|
+
passed: true,
|
|
36
|
+
score: 10,
|
|
37
|
+
message: 'No tools detected (rule not applicable)',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const autosubmitTools = tools.filter((t) => t.source === 'declarative' && t.formData?.autosubmit === true);
|
|
41
|
+
if (autosubmitTools.length === 0) {
|
|
42
|
+
return createRuleResult('SEC-012', 10, {
|
|
43
|
+
passed: true,
|
|
44
|
+
score: 10,
|
|
45
|
+
message: 'No autosubmit forms detected',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const violations = [];
|
|
49
|
+
for (const tool of autosubmitTools) {
|
|
50
|
+
const textToCheck = `${tool.name} ${tool.description} ${tool.formData?.formAction ?? ''}`;
|
|
51
|
+
const isSensitive = SENSITIVE_ACTION_PATTERNS.some((p) => p.test(textToCheck));
|
|
52
|
+
if (isSensitive) {
|
|
53
|
+
violations.push(tool.name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (violations.length === 0) {
|
|
57
|
+
return createRuleResult('SEC-012', 10, {
|
|
58
|
+
passed: true,
|
|
59
|
+
score: 10,
|
|
60
|
+
message: 'Autosubmit forms do not perform sensitive actions',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const penalty = violations.length * 5;
|
|
64
|
+
const score = Math.max(0, 10 - penalty);
|
|
65
|
+
return createRuleResult('SEC-012', 10, {
|
|
66
|
+
passed: false,
|
|
67
|
+
score,
|
|
68
|
+
message: `${violations.length} autosubmit form(s) perform sensitive actions`,
|
|
69
|
+
details: violations.map((name) => `Form tool "${name}" has toolautosubmit but performs a sensitive action`),
|
|
70
|
+
suggestions: [
|
|
71
|
+
'Remove toolautosubmit from forms that perform destructive or financial actions',
|
|
72
|
+
'Use a confirmation step before sensitive operations',
|
|
73
|
+
'Autosubmit is designed for safe, repeatable operations like search or filter',
|
|
74
|
+
],
|
|
75
|
+
affectedTools: violations,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=SEC-012.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-012.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-012.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,yBAAyB,GAAG;IAChC,UAAU;IACV,eAAe;IACf,eAAe;IACf,UAAU;IACV,aAAa;IACb,aAAa;IACb,cAAc;IACd,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,wCAAwC;CACzC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,SAAS;IACb,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,qFAAqF;IACvF,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,EAAE;IAEZ,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;gBACrC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CACrE,CAAC;QAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;gBACrC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,8BAA8B;aACxC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,EAAE,UAAU,IAAI,EAAE,EAAE,CAAC;YAE1F,MAAM,WAAW,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACvD,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CACpB,CAAC;YAEF,IAAI,WAAW,EAAE,CAAC;gBAChB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;gBACrC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,mDAAmD;aAC7D,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;QAExC,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;YACrC,MAAM,EAAE,KAAK;YACb,KAAK;YACL,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,+CAA+C;YAC5E,OAAO,EAAE,UAAU,CAAC,GAAG,CACrB,CAAC,IAAI,EAAE,EAAE,CACP,cAAc,IAAI,sDAAsD,CAC3E;YACD,WAAW,EAAE;gBACX,gFAAgF;gBAChF,qDAAqD;gBACrD,8EAA8E;aAC/E;YACD,aAAa,EAAE,UAAU;SAC1B,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-013: Hidden Field Exposure
|
|
3
|
+
*
|
|
4
|
+
* Checks that hidden form fields are not exposed as tool parameters.
|
|
5
|
+
* Hidden fields often contain CSRF tokens, session IDs, or internal state
|
|
6
|
+
* that should not be manipulated by AI agents.
|
|
7
|
+
*/
|
|
8
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
9
|
+
export declare const SEC_013: Rule;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-013: Hidden Field Exposure
|
|
3
|
+
*
|
|
4
|
+
* Checks that hidden form fields are not exposed as tool parameters.
|
|
5
|
+
* Hidden fields often contain CSRF tokens, session IDs, or internal state
|
|
6
|
+
* that should not be manipulated by AI agents.
|
|
7
|
+
*/
|
|
8
|
+
import { createRuleResult } from '../runner.js';
|
|
9
|
+
const SENSITIVE_HIDDEN_FIELDS = [
|
|
10
|
+
/csrf/i,
|
|
11
|
+
/token/i,
|
|
12
|
+
/session/i,
|
|
13
|
+
/nonce/i,
|
|
14
|
+
/secret/i,
|
|
15
|
+
/auth/i,
|
|
16
|
+
/key/i,
|
|
17
|
+
/signature/i,
|
|
18
|
+
/hmac/i,
|
|
19
|
+
/hash/i,
|
|
20
|
+
/_method/i,
|
|
21
|
+
/honeypot/i,
|
|
22
|
+
];
|
|
23
|
+
export const SEC_013 = {
|
|
24
|
+
id: 'SEC-013',
|
|
25
|
+
category: 'security',
|
|
26
|
+
name: 'Hidden Field Exposure',
|
|
27
|
+
description: 'Hidden form fields should not be exposed as tool parameters',
|
|
28
|
+
severity: 'warning',
|
|
29
|
+
maxScore: 8,
|
|
30
|
+
async check(context) {
|
|
31
|
+
const tools = context.tools;
|
|
32
|
+
if (tools.length === 0) {
|
|
33
|
+
return createRuleResult('SEC-013', 8, {
|
|
34
|
+
passed: true,
|
|
35
|
+
score: 8,
|
|
36
|
+
message: 'No tools detected (rule not applicable)',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const declarativeTools = tools.filter((t) => t.source === 'declarative');
|
|
40
|
+
if (declarativeTools.length === 0) {
|
|
41
|
+
return createRuleResult('SEC-013', 8, {
|
|
42
|
+
passed: true,
|
|
43
|
+
score: 8,
|
|
44
|
+
message: 'No declarative form tools detected (rule not applicable)',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const violations = [];
|
|
48
|
+
// Scan HTML for hidden fields in forms with toolname
|
|
49
|
+
const html = context.html ?? '';
|
|
50
|
+
const formRegex = /<form[^>]*toolname\s*=\s*["']([^"']+)["'][^>]*>([\s\S]*?)<\/form>/gi;
|
|
51
|
+
let formMatch;
|
|
52
|
+
while ((formMatch = formRegex.exec(html)) !== null) {
|
|
53
|
+
const toolname = formMatch[1];
|
|
54
|
+
const formBody = formMatch[2] ?? '';
|
|
55
|
+
const hiddenFieldRegex = /<input[^>]*type\s*=\s*["']hidden["'][^>]*name\s*=\s*["']([^"']+)["'][^>]*/gi;
|
|
56
|
+
const hiddenFields = [];
|
|
57
|
+
let fieldMatch;
|
|
58
|
+
while ((fieldMatch = hiddenFieldRegex.exec(formBody)) !== null) {
|
|
59
|
+
const fieldName = fieldMatch[1];
|
|
60
|
+
if (!fieldName)
|
|
61
|
+
continue;
|
|
62
|
+
const isSensitive = SENSITIVE_HIDDEN_FIELDS.some((p) => p.test(fieldName));
|
|
63
|
+
if (isSensitive) {
|
|
64
|
+
hiddenFields.push(fieldName);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Also check reverse order: name before type
|
|
68
|
+
const hiddenFieldRegex2 = /<input[^>]*name\s*=\s*["']([^"']+)["'][^>]*type\s*=\s*["']hidden["'][^>]*/gi;
|
|
69
|
+
while ((fieldMatch = hiddenFieldRegex2.exec(formBody)) !== null) {
|
|
70
|
+
const fieldName = fieldMatch[1];
|
|
71
|
+
if (!fieldName)
|
|
72
|
+
continue;
|
|
73
|
+
if (hiddenFields.includes(fieldName))
|
|
74
|
+
continue;
|
|
75
|
+
const isSensitive = SENSITIVE_HIDDEN_FIELDS.some((p) => p.test(fieldName));
|
|
76
|
+
if (isSensitive) {
|
|
77
|
+
hiddenFields.push(fieldName);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (hiddenFields.length > 0) {
|
|
81
|
+
violations.push({ tool: toolname ?? 'unknown', fields: hiddenFields });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (violations.length === 0) {
|
|
85
|
+
return createRuleResult('SEC-013', 8, {
|
|
86
|
+
passed: true,
|
|
87
|
+
score: 8,
|
|
88
|
+
message: 'No sensitive hidden fields exposed as tool parameters',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const penalty = violations.length * 4;
|
|
92
|
+
const score = Math.max(0, 8 - penalty);
|
|
93
|
+
return createRuleResult('SEC-013', 8, {
|
|
94
|
+
passed: false,
|
|
95
|
+
score,
|
|
96
|
+
message: `${violations.length} form(s) expose sensitive hidden fields`,
|
|
97
|
+
details: violations.map((v) => `Form tool "${v.tool}" exposes hidden fields: [${v.fields.join(', ')}]`),
|
|
98
|
+
suggestions: [
|
|
99
|
+
'Exclude hidden fields (CSRF tokens, session IDs) from tool parameters',
|
|
100
|
+
'Use toolparamexclude attribute to hide sensitive hidden fields',
|
|
101
|
+
'Hidden form fields should be handled automatically, not by AI agents',
|
|
102
|
+
],
|
|
103
|
+
affectedTools: violations.map((v) => v.tool),
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=SEC-013.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-013.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-013.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculator.js","sourceRoot":"","sources":["../../src/scoring/calculator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAoC,EACpC,cAAyC;IAEzC,4BAA4B;IAC5B,MAAM,eAAe,GAAuC;QAC1D,cAAc,EAAE,EAAE;QAClB,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,EAAE;QACpB,QAAQ,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"calculator.js","sourceRoot":"","sources":["../../src/scoring/calculator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAoC,EACpC,cAAyC;IAEzC,4BAA4B;IAC5B,MAAM,eAAe,GAAuC;QAC1D,cAAc,EAAE,EAAE;QAClB,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,EAAE;QACpB,QAAQ,EAAE,EAAE;QACZ,aAAa,EAAE,EAAE;KAClB,CAAC;IAEF,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAG/D,EAAE,CAAC;QACJ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAEvE,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC;YAChC,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,WAAW;YAClB,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;SACnC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC5C,kBAAkB,IAAI,UAAU,GAAG,MAAM,CAAC;QAC1C,WAAW,IAAI,MAAM,CAAC;IACxB,CAAC;IAED,gCAAgC;IAChC,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjF,kBAAkB;IAClB,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAEpC,2BAA2B;IAC3B,MAAM,UAAU,GAAG;QACjB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,CAAC;KACR,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,mCAAmC;YACnC,IAAI,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBACzC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACxB,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;gBAC/C,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK;QACL,KAAK;QACL,UAAU;QACV,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/C,IAAI,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/C,IAAI,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/C,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/C,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,WAAoC,EACpC,cAA4D;IAE5D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC3C,IAAI,MAAM,CAAC,MAAM;YAAE,SAAS;QAE5B,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;QACzD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;QAEnD,sCAAsC;QACtC,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM;YACN,QAAQ;YACR,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YAC/B,IAAI,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YAC/B,GAAG,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC5B,WAAW;SACZ,CAAC,CAAC;QAEH,oDAAoD;QACpD,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,QAAQ,CAAC,IAAI,CAAC;oBACZ,MAAM;oBACN,QAAQ;oBACR,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,IAAI;oBACJ,GAAG,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;oBAC5B,WAAW,EAAE,CAAC,EAAE,kBAAkB;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,MAAM,aAAa,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3D,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3E,IAAI,YAAY,KAAK,CAAC;YAAE,OAAO,YAAY,CAAC;QAC5C,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAmB;IACzD,MAAM,eAAe,GAAqB,EAAE,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,SAAS;QAC5C,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,SAAS;QAE3B,6CAA6C;QAC7C,IAAI,MAAM,GAA8B,QAAQ,CAAC;QACjD,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC;YAAE,MAAM,GAAG,KAAK,CAAC;QAC7C,IAAI,OAAO,CAAC,WAAW,IAAI,EAAE;YAAE,MAAM,GAAG,MAAM,CAAC;QAC/C,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,MAAM,GAAG,MAAM,CAAC;QACvD,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,MAAM,GAAG,KAAK,CAAC;QAEvD,yBAAyB;QACzB,MAAM,aAAa,GAAG,QAAQ;aAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;aACpD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC;QAEvB,eAAe,CAAC,IAAI,CAAC;YACnB,QAAQ,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC;YACpC,MAAM,EAAE,OAAO,CAAC,GAAG;YACnB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,MAAM;YACN,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,aAAa,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;SACpE,CAAC,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;IAE9D,oCAAoC;IACpC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACjC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAoB,EACpB,UAAsB,EACtB,cAAsB;IAEtB,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;IAC3D,MAAM,qBAAqB,GAAG,WAAW,CAAC,CAAC,4CAA4C;IACvF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,qBAAqB,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIRecommendationCard Component
|
|
3
|
+
*
|
|
4
|
+
* Displays an AI-generated recommendation for WebMCP potential.
|
|
5
|
+
*/
|
|
6
|
+
import type { AIRecommendation } from '../../../potential/types.js';
|
|
7
|
+
export interface AIRecommendationCardProps {
|
|
8
|
+
recommendation: AIRecommendation;
|
|
9
|
+
index: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const AIRecommendationCard: import("react").NamedExoticComponent<AIRecommendationCardProps>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* AIRecommendationCard Component
|
|
4
|
+
*
|
|
5
|
+
* Displays an AI-generated recommendation for WebMCP potential.
|
|
6
|
+
*/
|
|
7
|
+
import { memo } from 'react';
|
|
8
|
+
import { Box, Text } from 'ink';
|
|
9
|
+
import figures from 'figures';
|
|
10
|
+
import { Card } from './shared/Card.js';
|
|
11
|
+
import { Badge } from './shared/Badge.js';
|
|
12
|
+
const PRIORITY_COLORS = {
|
|
13
|
+
critical: 'red',
|
|
14
|
+
high: 'yellow',
|
|
15
|
+
medium: 'cyan',
|
|
16
|
+
low: 'gray',
|
|
17
|
+
};
|
|
18
|
+
export const AIRecommendationCard = memo(function AIRecommendationCard({ recommendation, index }) {
|
|
19
|
+
const color = PRIORITY_COLORS[recommendation.priority] ?? 'gray';
|
|
20
|
+
const schema = recommendation.toolDefinition?.inputSchema;
|
|
21
|
+
return (_jsx(Card, { borderColor: color, borderStyle: "round", marginBottom: 1, children: _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { justifyContent: "space-between", flexWrap: "wrap", children: [_jsxs(Text, { bold: true, children: ["#", index + 1, " ", recommendation.title] }), _jsx(Badge, { label: recommendation.priority.toUpperCase(), color: color })] }), _jsx(Text, { wrap: "wrap", children: recommendation.description }), recommendation.toolDefinition && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Tool:" }), _jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [_jsx(Text, { color: "cyan", children: recommendation.toolDefinition.name }), _jsx(Text, { wrap: "wrap", dimColor: true, children: recommendation.toolDefinition.description }), schema && (_jsxs(Text, { dimColor: true, children: ["Schema: ", JSON.stringify(schema)] }))] })] })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: [figures.arrowRight, " Impact: ", recommendation.estimatedImpact] }), _jsxs(Text, { dimColor: true, children: ["Hint: ", recommendation.implementationHint] })] })] }) }));
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=AIRecommendationCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIRecommendationCard.js","sourceRoot":"","sources":["../../../../src/ui/ink/components/AIRecommendationCard.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,MAAM,eAAe,GAA2B;IAC9C,QAAQ,EAAE,KAAK;IACf,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,MAAM;CACZ,CAAC;AAOF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,oBAAoB,CAAC,EAAE,cAAc,EAAE,KAAK,EAA6B;IACzH,MAAM,KAAK,GAAG,eAAe,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IACjE,MAAM,MAAM,GAAG,cAAc,CAAC,cAAc,EAAE,WAAkD,CAAC;IAEjG,OAAO,CACL,KAAC,IAAI,IAAC,WAAW,EAAE,KAAK,EAAE,WAAW,EAAC,OAAO,EAAC,YAAY,EAAE,CAAC,YAC3D,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,MAAC,GAAG,IAAC,cAAc,EAAC,eAAe,EAAC,QAAQ,EAAC,MAAM,aACjD,MAAC,IAAI,IAAC,IAAI,wBACN,KAAK,GAAG,CAAC,OAAG,cAAc,CAAC,KAAK,IAC7B,EACP,KAAC,KAAK,IAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,GAAI,IACjE,EAEN,KAAC,IAAI,IAAC,IAAI,EAAC,MAAM,YAAE,cAAc,CAAC,WAAW,GAAQ,EAEpD,cAAc,CAAC,cAAc,IAAI,CAChC,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACtC,KAAC,IAAI,IAAC,QAAQ,4BAAa,EAC3B,MAAC,GAAG,IAAC,UAAU,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACxC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,cAAc,CAAC,cAAc,CAAC,IAAI,GAAQ,EAC9D,KAAC,IAAI,IAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,kBACvB,cAAc,CAAC,cAAc,CAAC,WAAW,GACrC,EACN,MAAM,IAAI,CACT,MAAC,IAAI,IAAC,QAAQ,+BACH,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAC1B,CACR,IACG,IACF,CACP,EAED,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,MAAC,IAAI,eACF,OAAO,CAAC,UAAU,eAAW,cAAc,CAAC,eAAe,IACvD,EACP,MAAC,IAAI,IAAC,QAAQ,6BACL,cAAc,CAAC,kBAAkB,IACnC,IACH,IACF,GACD,CACR,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpportunityList Component
|
|
3
|
+
*
|
|
4
|
+
* Displays grouped opportunity lists color-coded by agentic value.
|
|
5
|
+
*/
|
|
6
|
+
import type { PotentialOpportunity } from '../../../potential/types.js';
|
|
7
|
+
export interface OpportunityListProps {
|
|
8
|
+
opportunities: PotentialOpportunity[];
|
|
9
|
+
}
|
|
10
|
+
export declare const OpportunityList: import("react").NamedExoticComponent<OpportunityListProps>;
|