@ai-lighthouse/cli 1.0.0
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/.ai-lighthouse/audit_example.com_2025-12-15T12-10-43.json +183 -0
- package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-32-28.html +743 -0
- package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-33-02.html +757 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T11-53-21.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-04-06.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-05-10.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-09-45.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-11-07.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-13-28.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-14-59.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-07.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-44.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-21-38.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-21.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-46.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-23-18.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-24-43.json +205 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-08.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-57.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-17-11.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-17.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-42.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-23-56.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-24.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-40.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-02.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-20.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-29-56.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-32-27.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-33-00.json +168 -0
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-34-49.json +168 -0
- package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-31.json +168 -0
- package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-45.json +168 -0
- package/.ai-lighthouse/audit_tailwindcss.com_2025-12-15T12-12-01.json +169 -0
- package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-08.json +24 -0
- package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-23.json +24 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-41-34.json +21 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-09.json +21 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-45.json +21 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-02.json +21 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-26.json +21 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-47-46.json +906 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-50-27.json +906 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-52-59.json +906 -0
- package/.ai-lighthouse/crawl_github.com_2025-12-15T12-03-33.json +28 -0
- package/CLI_UI_README.md +211 -0
- package/EXAMPLES.md +87 -0
- package/IMPLEMENTATION.md +215 -0
- package/README.md +166 -0
- package/USAGE.md +264 -0
- package/WIZARD_GUIDE.md +340 -0
- package/bin/cli.js +2 -0
- package/dist/commands/audit-interactive.d.ts +2 -0
- package/dist/commands/audit-interactive.js +106 -0
- package/dist/commands/audit-wizard.d.ts +2 -0
- package/dist/commands/audit-wizard.js +110 -0
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.js +940 -0
- package/dist/commands/crawl.d.ts +2 -0
- package/dist/commands/crawl.js +267 -0
- package/dist/commands/report.d.ts +2 -0
- package/dist/commands/report.js +304 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +16 -0
- package/dist/ui/AuditReportUI.d.ts +10 -0
- package/dist/ui/AuditReportUI.js +76 -0
- package/dist/ui/SetupWizard.d.ts +18 -0
- package/dist/ui/SetupWizard.js +179 -0
- package/dist/ui/components/AIUnderstandingSection.d.ts +6 -0
- package/dist/ui/components/AIUnderstandingSection.js +87 -0
- package/dist/ui/components/HallucinationSection.d.ts +6 -0
- package/dist/ui/components/HallucinationSection.js +84 -0
- package/dist/ui/components/IssuesSection.d.ts +6 -0
- package/dist/ui/components/IssuesSection.js +84 -0
- package/dist/ui/components/MessageAlignmentSection.d.ts +6 -0
- package/dist/ui/components/MessageAlignmentSection.js +108 -0
- package/dist/ui/components/OverviewSection.d.ts +6 -0
- package/dist/ui/components/OverviewSection.js +107 -0
- package/dist/ui/components/ScoreDisplay.d.ts +8 -0
- package/dist/ui/components/ScoreDisplay.js +41 -0
- package/dist/ui/components/TechnicalSection.d.ts +7 -0
- package/dist/ui/components/TechnicalSection.js +110 -0
- package/dist/utils/comprehensive-formatter.d.ts +5 -0
- package/dist/utils/comprehensive-formatter.js +370 -0
- package/package.json +49 -0
- package/src/commands/audit-interactive.ts +149 -0
- package/src/commands/audit-wizard.ts +137 -0
- package/src/commands/audit.ts +1012 -0
- package/src/commands/crawl.ts +307 -0
- package/src/commands/report.ts +321 -0
- package/src/index.ts +22 -0
- package/src/ui/AuditReportUI.tsx +151 -0
- package/src/ui/SetupWizard.tsx +294 -0
- package/src/ui/components/AIUnderstandingSection.tsx +183 -0
- package/src/ui/components/HallucinationSection.tsx +172 -0
- package/src/ui/components/IssuesSection.tsx +140 -0
- package/src/ui/components/MessageAlignmentSection.tsx +203 -0
- package/src/ui/components/OverviewSection.tsx +157 -0
- package/src/ui/components/ScoreDisplay.tsx +58 -0
- package/src/ui/components/TechnicalSection.tsx +200 -0
- package/src/utils/comprehensive-formatter.ts +455 -0
- package/test.sh +31 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
export const MessageAlignmentSection = ({ mirrorReport }) => {
|
|
4
|
+
if (!mirrorReport || Object.keys(mirrorReport).length === 0) {
|
|
5
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
6
|
+
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1 },
|
|
7
|
+
React.createElement(Text, { bold: true, color: "yellow" }, "\uD83D\uDCA1 Enable Message Alignment Analysis"),
|
|
8
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
9
|
+
React.createElement(Text, null, "Message alignment analysis is not available. To see what AI understands, run:"),
|
|
10
|
+
React.createElement(Box, { marginTop: 1, borderStyle: "single", paddingX: 1 },
|
|
11
|
+
React.createElement(Text, { color: "cyan" }, "ai-lighthouse audit [URL] --enable-llm --llm-provider openai --llm-api-key YOUR_KEY")),
|
|
12
|
+
React.createElement(Box, { marginTop: 1 },
|
|
13
|
+
React.createElement(Text, { dimColor: true }, "This requires LLM analysis to compare AI understanding with your intended message"))))));
|
|
14
|
+
}
|
|
15
|
+
const getScoreColor = (score) => {
|
|
16
|
+
if (score >= 80)
|
|
17
|
+
return 'green';
|
|
18
|
+
if (score >= 60)
|
|
19
|
+
return 'yellow';
|
|
20
|
+
return 'red';
|
|
21
|
+
};
|
|
22
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
23
|
+
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
24
|
+
React.createElement(Text, { bold: true, color: "magenta" }, "\uD83D\uDD0D AI Misunderstanding Check"),
|
|
25
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
26
|
+
React.createElement(Box, null,
|
|
27
|
+
React.createElement(Text, null,
|
|
28
|
+
React.createElement(Text, { bold: true }, "Alignment Score:"),
|
|
29
|
+
' ',
|
|
30
|
+
React.createElement(Text, { bold: true, color: getScoreColor(mirrorReport.summary.alignmentScore) },
|
|
31
|
+
mirrorReport.summary.alignmentScore,
|
|
32
|
+
"/100"))),
|
|
33
|
+
React.createElement(Box, null,
|
|
34
|
+
React.createElement(Text, null,
|
|
35
|
+
React.createElement(Text, { bold: true }, "Clarity Score:"),
|
|
36
|
+
' ',
|
|
37
|
+
React.createElement(Text, { bold: true, color: getScoreColor(mirrorReport.summary.clarityScore) },
|
|
38
|
+
mirrorReport.summary.clarityScore,
|
|
39
|
+
"/100"))),
|
|
40
|
+
React.createElement(Box, null,
|
|
41
|
+
React.createElement(Text, null,
|
|
42
|
+
React.createElement(Text, { bold: true }, "Critical Issues:"),
|
|
43
|
+
' ',
|
|
44
|
+
React.createElement(Text, { color: "red" }, mirrorReport.summary.critical))),
|
|
45
|
+
React.createElement(Box, null,
|
|
46
|
+
React.createElement(Text, null,
|
|
47
|
+
React.createElement(Text, { bold: true }, "Major Issues:"),
|
|
48
|
+
' ',
|
|
49
|
+
React.createElement(Text, { color: "yellow" }, mirrorReport.summary.major))))),
|
|
50
|
+
mirrorReport.llmInterpretation && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
51
|
+
React.createElement(Text, { bold: true, color: "blue" }, "\uD83E\uDD16 What AI Actually Understood"),
|
|
52
|
+
React.createElement(Text, { dimColor: true },
|
|
53
|
+
"(",
|
|
54
|
+
Math.round(mirrorReport.llmInterpretation.confidence * 100),
|
|
55
|
+
"% confident)"),
|
|
56
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
57
|
+
mirrorReport.llmInterpretation.productName && (React.createElement(Text, null,
|
|
58
|
+
React.createElement(Text, { bold: true }, "Product:"),
|
|
59
|
+
" ",
|
|
60
|
+
mirrorReport.llmInterpretation.productName)),
|
|
61
|
+
mirrorReport.llmInterpretation.purpose && (React.createElement(Text, null,
|
|
62
|
+
React.createElement(Text, { bold: true }, "Purpose:"),
|
|
63
|
+
" ",
|
|
64
|
+
mirrorReport.llmInterpretation.purpose)),
|
|
65
|
+
mirrorReport.llmInterpretation.valueProposition && (React.createElement(Text, null,
|
|
66
|
+
React.createElement(Text, { bold: true, color: "magenta" }, "\uD83D\uDC8E Value:"),
|
|
67
|
+
" ",
|
|
68
|
+
mirrorReport.llmInterpretation.valueProposition))),
|
|
69
|
+
mirrorReport.llmInterpretation.keyBenefits && mirrorReport.llmInterpretation.keyBenefits.length > 0 && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
70
|
+
React.createElement(Text, { bold: true }, "Benefits:"),
|
|
71
|
+
mirrorReport.llmInterpretation.keyBenefits.map((benefit, idx) => (React.createElement(Text, { key: idx },
|
|
72
|
+
"\u2022 ",
|
|
73
|
+
benefit))))),
|
|
74
|
+
mirrorReport.llmInterpretation.keyFeatures && mirrorReport.llmInterpretation.keyFeatures.length > 0 && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
75
|
+
React.createElement(Text, { bold: true }, "Features:"),
|
|
76
|
+
mirrorReport.llmInterpretation.keyFeatures.slice(0, 3).map((feature, idx) => (React.createElement(Text, { key: idx },
|
|
77
|
+
"\u2022 ",
|
|
78
|
+
feature))))),
|
|
79
|
+
mirrorReport.llmInterpretation.targetAudience && (React.createElement(Box, { marginTop: 1 },
|
|
80
|
+
React.createElement(Text, null,
|
|
81
|
+
React.createElement(Text, { bold: true }, "Audience:"),
|
|
82
|
+
" ",
|
|
83
|
+
mirrorReport.llmInterpretation.targetAudience))))),
|
|
84
|
+
mirrorReport.mismatches && mirrorReport.mismatches.length > 0 && (React.createElement(React.Fragment, null, mirrorReport.mismatches.filter((m) => m.severity === 'critical' || m.severity === 'major').length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
85
|
+
React.createElement(Text, { bold: true, underline: true }, "Priority Mismatches"),
|
|
86
|
+
mirrorReport.mismatches
|
|
87
|
+
.filter((m) => m.severity === 'critical' || m.severity === 'major')
|
|
88
|
+
.slice(0, 5)
|
|
89
|
+
.map((mismatch, idx) => (React.createElement(Box, { key: idx, flexDirection: "column", borderStyle: "single", borderColor: mismatch.severity === 'critical' ? 'red' : 'yellow', paddingX: 1, paddingY: 0.5, marginTop: 1 },
|
|
90
|
+
React.createElement(Text, null,
|
|
91
|
+
mismatch.severity === 'critical' ? '🔴' : '🟡',
|
|
92
|
+
" ",
|
|
93
|
+
idx + 1,
|
|
94
|
+
". ",
|
|
95
|
+
React.createElement(Text, { bold: true }, mismatch.field)),
|
|
96
|
+
React.createElement(Text, { dimColor: true }, mismatch.description),
|
|
97
|
+
React.createElement(Box, { marginTop: 0.5 },
|
|
98
|
+
React.createElement(Text, { color: "cyan" },
|
|
99
|
+
"\u2192 ",
|
|
100
|
+
mismatch.recommendation))))))))),
|
|
101
|
+
mirrorReport.recommendations && mirrorReport.recommendations.length > 0 && (React.createElement(Box, { flexDirection: "column" },
|
|
102
|
+
React.createElement(Text, { bold: true, underline: true, color: "cyan" }, "\uD83D\uDCA1 Top Recommendations"),
|
|
103
|
+
mirrorReport.recommendations.slice(0, 3).map((rec, idx) => (React.createElement(Box, { key: idx, marginTop: 0.5 },
|
|
104
|
+
React.createElement(Text, { color: "cyan" },
|
|
105
|
+
idx + 1,
|
|
106
|
+
". ",
|
|
107
|
+
rec))))))));
|
|
108
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
export const OverviewSection = ({ aiReadiness }) => {
|
|
4
|
+
const getStatusColor = (status) => {
|
|
5
|
+
if (status === 'excellent')
|
|
6
|
+
return 'green';
|
|
7
|
+
if (status === 'good')
|
|
8
|
+
return 'blue';
|
|
9
|
+
if (status === 'needs-work')
|
|
10
|
+
return 'yellow';
|
|
11
|
+
return 'red';
|
|
12
|
+
};
|
|
13
|
+
const renderProgressBar = (score, width = 20) => {
|
|
14
|
+
const filled = Math.round((score / 100) * width);
|
|
15
|
+
const empty = width - filled;
|
|
16
|
+
const color = score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red';
|
|
17
|
+
return (React.createElement(Text, { color: color },
|
|
18
|
+
'█'.repeat(filled),
|
|
19
|
+
React.createElement(Text, { dimColor: true }, '░'.repeat(empty)),
|
|
20
|
+
` ${Math.round(score)}%`));
|
|
21
|
+
};
|
|
22
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
23
|
+
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
24
|
+
React.createElement(Text, { bold: true, color: "cyan" }, "\uD83E\uDD16 AI Agent Perspective"),
|
|
25
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
26
|
+
React.createElement(Box, null,
|
|
27
|
+
React.createElement(Text, null,
|
|
28
|
+
aiReadiness.aiPerspective?.canUnderstand ? '✅' : '❌',
|
|
29
|
+
" Can Understand",
|
|
30
|
+
aiReadiness.aiPerspective?.canExtract ? '✅' : '❌',
|
|
31
|
+
" Can Extract")),
|
|
32
|
+
React.createElement(Box, null,
|
|
33
|
+
React.createElement(Text, null,
|
|
34
|
+
aiReadiness.aiPerspective?.canIndex ? '✅' : '❌',
|
|
35
|
+
" Can Index",
|
|
36
|
+
aiReadiness.aiPerspective?.canAnswer ? '✅' : '❌',
|
|
37
|
+
" Can Answer")),
|
|
38
|
+
React.createElement(Box, { marginTop: 1 },
|
|
39
|
+
React.createElement(Text, { dimColor: true },
|
|
40
|
+
"Confidence: ",
|
|
41
|
+
Math.round((aiReadiness.aiPerspective?.confidence || 0) * 100),
|
|
42
|
+
"%"))),
|
|
43
|
+
aiReadiness.aiPerspective?.mainBlockers && aiReadiness.aiPerspective.mainBlockers.length > 0 && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
44
|
+
React.createElement(Text, { bold: true, color: "red" }, "Main Blockers:"),
|
|
45
|
+
aiReadiness.aiPerspective.mainBlockers.map((blocker, idx) => (React.createElement(Text, { key: idx, color: "red" },
|
|
46
|
+
"\u2022 ",
|
|
47
|
+
blocker)))))),
|
|
48
|
+
React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
49
|
+
React.createElement(Text, { bold: true, underline: true }, "\uD83C\uDFAF Dimension Scores"),
|
|
50
|
+
Object.entries(aiReadiness.dimensions || {}).map(([key, dim]) => (React.createElement(Box, { key: key, flexDirection: "column", marginTop: 1 },
|
|
51
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
52
|
+
React.createElement(Text, { bold: true, color: getStatusColor(dim.status) },
|
|
53
|
+
getDimensionIcon(key),
|
|
54
|
+
" ",
|
|
55
|
+
formatDimensionName(key)),
|
|
56
|
+
React.createElement(Text, { color: getStatusColor(dim.status) },
|
|
57
|
+
Math.round(dim.score),
|
|
58
|
+
"/100")),
|
|
59
|
+
React.createElement(Box, { marginTop: 0.5 }, renderProgressBar(dim.score)),
|
|
60
|
+
dim.recommendation && (React.createElement(Box, { marginTop: 0.5 },
|
|
61
|
+
React.createElement(Text, { dimColor: true },
|
|
62
|
+
"\u2192 ",
|
|
63
|
+
dim.recommendation))))))),
|
|
64
|
+
aiReadiness.quickWins && aiReadiness.quickWins.length > 0 && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, marginTop: 1 },
|
|
65
|
+
React.createElement(Text, { bold: true, color: "yellow" }, "\u26A1 Quick Wins (High Impact, Low Effort)"),
|
|
66
|
+
aiReadiness.quickWins.slice(0, 5).map((win, idx) => (React.createElement(Box, { key: idx, flexDirection: "column", marginTop: 1 },
|
|
67
|
+
React.createElement(Text, { bold: true },
|
|
68
|
+
idx + 1,
|
|
69
|
+
". ",
|
|
70
|
+
win.issue),
|
|
71
|
+
React.createElement(Text, { dimColor: true },
|
|
72
|
+
"Impact: ",
|
|
73
|
+
win.impact,
|
|
74
|
+
" \u2022 Effort: ",
|
|
75
|
+
win.effort),
|
|
76
|
+
React.createElement(Text, { color: "cyan" },
|
|
77
|
+
"\u2192 ",
|
|
78
|
+
win.fix))))))));
|
|
79
|
+
};
|
|
80
|
+
function getDimensionIcon(key) {
|
|
81
|
+
const icons = {
|
|
82
|
+
technical: '⚙️',
|
|
83
|
+
contentQuality: '📝',
|
|
84
|
+
crawlability: '🕷️',
|
|
85
|
+
discoverability: '🔍',
|
|
86
|
+
knowledge: '🧠',
|
|
87
|
+
extractability: '🔄',
|
|
88
|
+
comprehensibility: '💡',
|
|
89
|
+
trustworthiness: '✅',
|
|
90
|
+
accessibility: '♿',
|
|
91
|
+
};
|
|
92
|
+
return icons[key] || '📌';
|
|
93
|
+
}
|
|
94
|
+
function formatDimensionName(key) {
|
|
95
|
+
const names = {
|
|
96
|
+
technical: 'Technical',
|
|
97
|
+
contentQuality: 'Content Quality',
|
|
98
|
+
crawlability: 'Crawlability',
|
|
99
|
+
discoverability: 'Discoverability',
|
|
100
|
+
knowledge: 'Knowledge',
|
|
101
|
+
extractability: 'Extractability',
|
|
102
|
+
comprehensibility: 'Comprehensibility',
|
|
103
|
+
trustworthiness: 'Trustworthiness',
|
|
104
|
+
accessibility: 'Accessibility',
|
|
105
|
+
};
|
|
106
|
+
return names[key] || key;
|
|
107
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import Gradient from 'ink-gradient';
|
|
4
|
+
import BigText from 'ink-big-text';
|
|
5
|
+
export const ScoreDisplay = ({ score, grade, url }) => {
|
|
6
|
+
const getGradeColor = (grade) => {
|
|
7
|
+
if (grade.startsWith('A'))
|
|
8
|
+
return 'green';
|
|
9
|
+
if (grade.startsWith('B'))
|
|
10
|
+
return 'blue';
|
|
11
|
+
if (grade.startsWith('C'))
|
|
12
|
+
return 'yellow';
|
|
13
|
+
return 'red';
|
|
14
|
+
};
|
|
15
|
+
const getScoreMessage = (score) => {
|
|
16
|
+
if (score >= 90)
|
|
17
|
+
return { status: 'Excellent', message: 'Your site is AI-ready!', color: 'green' };
|
|
18
|
+
if (score >= 80)
|
|
19
|
+
return { status: 'Good', message: 'Your site works well with AI', color: 'blue' };
|
|
20
|
+
if (score >= 70)
|
|
21
|
+
return { status: 'Fair', message: 'Room for improvement', color: 'yellow' };
|
|
22
|
+
if (score >= 60)
|
|
23
|
+
return { status: 'Poor', message: 'Needs significant work', color: 'yellow' };
|
|
24
|
+
return { status: 'Critical', message: 'Major issues detected', color: 'red' };
|
|
25
|
+
};
|
|
26
|
+
const { status, message, color } = getScoreMessage(score);
|
|
27
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
28
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
29
|
+
React.createElement(Gradient, { name: "rainbow" },
|
|
30
|
+
React.createElement(BigText, { text: `${score}`, font: "block" }))),
|
|
31
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
32
|
+
React.createElement(Text, { bold: true, color: getGradeColor(grade) },
|
|
33
|
+
"Grade: ",
|
|
34
|
+
grade,
|
|
35
|
+
" \u2022 ",
|
|
36
|
+
status)),
|
|
37
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
38
|
+
React.createElement(Text, { dimColor: true }, url)),
|
|
39
|
+
React.createElement(Box, { borderStyle: "round", borderColor: color, paddingX: 2, paddingY: 1 },
|
|
40
|
+
React.createElement(Text, { color: color }, message))));
|
|
41
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
export const TechnicalSection = ({ result, scoring }) => {
|
|
4
|
+
const renderProgressBar = (score, width = 20) => {
|
|
5
|
+
const filled = Math.round((score / 100) * width);
|
|
6
|
+
const empty = width - filled;
|
|
7
|
+
const color = score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red';
|
|
8
|
+
return (React.createElement(Text, { color: color },
|
|
9
|
+
'█'.repeat(filled),
|
|
10
|
+
React.createElement(Text, { dimColor: true }, '░'.repeat(empty)),
|
|
11
|
+
` ${Math.round(score)}%`));
|
|
12
|
+
};
|
|
13
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
14
|
+
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
15
|
+
React.createElement(Text, { bold: true, color: "blue" }, "\uD83D\uDCCA Category Scores"),
|
|
16
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
17
|
+
scoring?.crawlability !== undefined && (React.createElement(Box, { flexDirection: "column", marginTop: 0.5 },
|
|
18
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
19
|
+
React.createElement(Text, { bold: true }, "\uD83D\uDD77\uFE0F Crawlability"),
|
|
20
|
+
React.createElement(Text, null,
|
|
21
|
+
Math.round(scoring.crawlability),
|
|
22
|
+
"/100")),
|
|
23
|
+
React.createElement(Box, { marginTop: 0.5 }, renderProgressBar(scoring.crawlability)))),
|
|
24
|
+
scoring?.structure !== undefined && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
25
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
26
|
+
React.createElement(Text, { bold: true }, "\uD83D\uDCD0 Structure"),
|
|
27
|
+
React.createElement(Text, null,
|
|
28
|
+
Math.round(scoring.structure),
|
|
29
|
+
"/100")),
|
|
30
|
+
React.createElement(Box, { marginTop: 0.5 }, renderProgressBar(scoring.structure)))),
|
|
31
|
+
scoring?.schema_coverage !== undefined && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
32
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
33
|
+
React.createElement(Text, { bold: true }, "\uD83C\uDFF7\uFE0F Schema Coverage"),
|
|
34
|
+
React.createElement(Text, null,
|
|
35
|
+
Math.round(scoring.schema_coverage),
|
|
36
|
+
"/100")),
|
|
37
|
+
React.createElement(Box, { marginTop: 0.5 }, renderProgressBar(scoring.schema_coverage)))),
|
|
38
|
+
scoring?.content_clarity !== undefined && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
39
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
40
|
+
React.createElement(Text, { bold: true }, "\uD83D\uDCDD Content Clarity"),
|
|
41
|
+
React.createElement(Text, null,
|
|
42
|
+
Math.round(scoring.content_clarity),
|
|
43
|
+
"/100")),
|
|
44
|
+
React.createElement(Box, { marginTop: 0.5 }, renderProgressBar(scoring.content_clarity)))))),
|
|
45
|
+
result.chunking && Object.keys(result.chunking).length > 0 ? (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
46
|
+
React.createElement(Text, { bold: true, color: "green" }, "\uD83D\uDCC4 Content Chunking Analysis"),
|
|
47
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
48
|
+
React.createElement(Text, null,
|
|
49
|
+
React.createElement(Text, { bold: true }, "Strategy:"),
|
|
50
|
+
" ",
|
|
51
|
+
result.chunking.chunkingStrategy),
|
|
52
|
+
React.createElement(Text, null,
|
|
53
|
+
React.createElement(Text, { bold: true }, "Total Chunks:"),
|
|
54
|
+
" ",
|
|
55
|
+
result.chunking.totalChunks),
|
|
56
|
+
React.createElement(Text, null,
|
|
57
|
+
React.createElement(Text, { bold: true }, "Avg Tokens/Chunk:"),
|
|
58
|
+
" ",
|
|
59
|
+
result.chunking.averageTokensPerChunk),
|
|
60
|
+
React.createElement(Text, null,
|
|
61
|
+
React.createElement(Text, { bold: true }, "Avg Noise Ratio:"),
|
|
62
|
+
" ",
|
|
63
|
+
(result.chunking.averageNoiseRatio * 100).toFixed(1),
|
|
64
|
+
"%")),
|
|
65
|
+
result.chunking.chunkingStrategy === 'heading-based' && (React.createElement(Box, { marginTop: 1 },
|
|
66
|
+
React.createElement(Text, { color: "green" }, "\u2713 Heading-based chunking is ideal for AI comprehension"))),
|
|
67
|
+
result.chunking.chunkingStrategy === 'paragraph-based' && (React.createElement(Box, { marginTop: 1 },
|
|
68
|
+
React.createElement(Text, { color: "yellow" }, "\u26A0 Consider adding headings for better semantic structure"))))) : (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
69
|
+
React.createElement(Text, { dimColor: true }, "\uD83D\uDCA1 Enable chunking analysis with --enable-chunking to see how your content is divided for AI processing"))),
|
|
70
|
+
result.extractability && Object.keys(result.extractability).length > 0 ? (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
71
|
+
React.createElement(Text, { bold: true, color: "yellow" }, "\uD83D\uDD04 Extractability Analysis"),
|
|
72
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
73
|
+
React.createElement(Text, null,
|
|
74
|
+
React.createElement(Text, { bold: true }, "Overall Score:"),
|
|
75
|
+
" ",
|
|
76
|
+
result.extractability.score.extractabilityScore,
|
|
77
|
+
"/100"),
|
|
78
|
+
React.createElement(Text, null,
|
|
79
|
+
React.createElement(Text, { bold: true }, "Server-Rendered:"),
|
|
80
|
+
" ",
|
|
81
|
+
result.extractability.score.serverRenderedPercent,
|
|
82
|
+
"%")),
|
|
83
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
84
|
+
React.createElement(Text, { bold: true, underline: true }, "Content Type Extractability:"),
|
|
85
|
+
Object.entries(result.extractability.contentTypes).map(([type, data]) => {
|
|
86
|
+
const percentage = data.percentage;
|
|
87
|
+
const color = percentage >= 80 ? 'green' : percentage >= 50 ? 'yellow' : 'red';
|
|
88
|
+
return (React.createElement(Box, { key: type, marginTop: 0.5 },
|
|
89
|
+
React.createElement(Text, null,
|
|
90
|
+
React.createElement(Text, { bold: true },
|
|
91
|
+
type.charAt(0).toUpperCase() + type.slice(1),
|
|
92
|
+
":"),
|
|
93
|
+
' ',
|
|
94
|
+
React.createElement(Text, { color: color },
|
|
95
|
+
percentage,
|
|
96
|
+
"%"),
|
|
97
|
+
' ',
|
|
98
|
+
React.createElement(Text, { dimColor: true },
|
|
99
|
+
"(",
|
|
100
|
+
data.extractable,
|
|
101
|
+
"/",
|
|
102
|
+
data.total,
|
|
103
|
+
")"))));
|
|
104
|
+
})),
|
|
105
|
+
result.extractability.score.extractabilityScore >= 80 && (React.createElement(Box, { marginTop: 1 },
|
|
106
|
+
React.createElement(Text, { color: "green" }, "\u2713 Good extractability - AI can easily read your content"))),
|
|
107
|
+
result.extractability.score.extractabilityScore < 50 && (React.createElement(Box, { marginTop: 1 },
|
|
108
|
+
React.createElement(Text, { color: "red" }, "\u26A0 Low extractability - Consider server-side rendering"))))) : (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
109
|
+
React.createElement(Text, { dimColor: true }, "\uD83D\uDCA1 Enable extractability analysis with --enable-extractability to see how well AI can extract your content")))));
|
|
110
|
+
};
|