@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.
Files changed (103) hide show
  1. package/.ai-lighthouse/audit_example.com_2025-12-15T12-10-43.json +183 -0
  2. package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-32-28.html +743 -0
  3. package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-33-02.html +757 -0
  4. package/.ai-lighthouse/audit_github.com_2025-12-15T11-53-21.json +168 -0
  5. package/.ai-lighthouse/audit_github.com_2025-12-15T12-04-06.json +168 -0
  6. package/.ai-lighthouse/audit_github.com_2025-12-15T12-05-10.json +168 -0
  7. package/.ai-lighthouse/audit_github.com_2025-12-15T12-09-45.json +168 -0
  8. package/.ai-lighthouse/audit_github.com_2025-12-15T12-11-07.json +168 -0
  9. package/.ai-lighthouse/audit_github.com_2025-12-15T12-13-28.json +168 -0
  10. package/.ai-lighthouse/audit_github.com_2025-12-15T12-14-59.json +205 -0
  11. package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-07.json +205 -0
  12. package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-44.json +205 -0
  13. package/.ai-lighthouse/audit_github.com_2025-12-15T12-21-38.json +205 -0
  14. package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-21.json +205 -0
  15. package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-46.json +205 -0
  16. package/.ai-lighthouse/audit_github.com_2025-12-15T12-23-18.json +205 -0
  17. package/.ai-lighthouse/audit_github.com_2025-12-15T12-24-43.json +205 -0
  18. package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-08.json +168 -0
  19. package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-57.json +168 -0
  20. package/.ai-lighthouse/audit_github.com_2025-12-17T12-17-11.json +168 -0
  21. package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-17.json +168 -0
  22. package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-42.json +168 -0
  23. package/.ai-lighthouse/audit_github.com_2025-12-17T12-23-56.json +168 -0
  24. package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-24.json +168 -0
  25. package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-40.json +168 -0
  26. package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-02.json +168 -0
  27. package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-20.json +168 -0
  28. package/.ai-lighthouse/audit_github.com_2025-12-17T12-29-56.json +168 -0
  29. package/.ai-lighthouse/audit_github.com_2025-12-17T12-32-27.json +168 -0
  30. package/.ai-lighthouse/audit_github.com_2025-12-17T12-33-00.json +168 -0
  31. package/.ai-lighthouse/audit_github.com_2025-12-17T12-34-49.json +168 -0
  32. package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-31.json +168 -0
  33. package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-45.json +168 -0
  34. package/.ai-lighthouse/audit_tailwindcss.com_2025-12-15T12-12-01.json +169 -0
  35. package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-08.json +24 -0
  36. package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-23.json +24 -0
  37. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-41-34.json +21 -0
  38. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-09.json +21 -0
  39. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-45.json +21 -0
  40. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-02.json +21 -0
  41. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-26.json +21 -0
  42. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-47-46.json +906 -0
  43. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-50-27.json +906 -0
  44. package/.ai-lighthouse/crawl_github.com_2025-12-15T11-52-59.json +906 -0
  45. package/.ai-lighthouse/crawl_github.com_2025-12-15T12-03-33.json +28 -0
  46. package/CLI_UI_README.md +211 -0
  47. package/EXAMPLES.md +87 -0
  48. package/IMPLEMENTATION.md +215 -0
  49. package/README.md +166 -0
  50. package/USAGE.md +264 -0
  51. package/WIZARD_GUIDE.md +340 -0
  52. package/bin/cli.js +2 -0
  53. package/dist/commands/audit-interactive.d.ts +2 -0
  54. package/dist/commands/audit-interactive.js +106 -0
  55. package/dist/commands/audit-wizard.d.ts +2 -0
  56. package/dist/commands/audit-wizard.js +110 -0
  57. package/dist/commands/audit.d.ts +2 -0
  58. package/dist/commands/audit.js +940 -0
  59. package/dist/commands/crawl.d.ts +2 -0
  60. package/dist/commands/crawl.js +267 -0
  61. package/dist/commands/report.d.ts +2 -0
  62. package/dist/commands/report.js +304 -0
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +16 -0
  65. package/dist/ui/AuditReportUI.d.ts +10 -0
  66. package/dist/ui/AuditReportUI.js +76 -0
  67. package/dist/ui/SetupWizard.d.ts +18 -0
  68. package/dist/ui/SetupWizard.js +179 -0
  69. package/dist/ui/components/AIUnderstandingSection.d.ts +6 -0
  70. package/dist/ui/components/AIUnderstandingSection.js +87 -0
  71. package/dist/ui/components/HallucinationSection.d.ts +6 -0
  72. package/dist/ui/components/HallucinationSection.js +84 -0
  73. package/dist/ui/components/IssuesSection.d.ts +6 -0
  74. package/dist/ui/components/IssuesSection.js +84 -0
  75. package/dist/ui/components/MessageAlignmentSection.d.ts +6 -0
  76. package/dist/ui/components/MessageAlignmentSection.js +108 -0
  77. package/dist/ui/components/OverviewSection.d.ts +6 -0
  78. package/dist/ui/components/OverviewSection.js +107 -0
  79. package/dist/ui/components/ScoreDisplay.d.ts +8 -0
  80. package/dist/ui/components/ScoreDisplay.js +41 -0
  81. package/dist/ui/components/TechnicalSection.d.ts +7 -0
  82. package/dist/ui/components/TechnicalSection.js +110 -0
  83. package/dist/utils/comprehensive-formatter.d.ts +5 -0
  84. package/dist/utils/comprehensive-formatter.js +370 -0
  85. package/package.json +49 -0
  86. package/src/commands/audit-interactive.ts +149 -0
  87. package/src/commands/audit-wizard.ts +137 -0
  88. package/src/commands/audit.ts +1012 -0
  89. package/src/commands/crawl.ts +307 -0
  90. package/src/commands/report.ts +321 -0
  91. package/src/index.ts +22 -0
  92. package/src/ui/AuditReportUI.tsx +151 -0
  93. package/src/ui/SetupWizard.tsx +294 -0
  94. package/src/ui/components/AIUnderstandingSection.tsx +183 -0
  95. package/src/ui/components/HallucinationSection.tsx +172 -0
  96. package/src/ui/components/IssuesSection.tsx +140 -0
  97. package/src/ui/components/MessageAlignmentSection.tsx +203 -0
  98. package/src/ui/components/OverviewSection.tsx +157 -0
  99. package/src/ui/components/ScoreDisplay.tsx +58 -0
  100. package/src/ui/components/TechnicalSection.tsx +200 -0
  101. package/src/utils/comprehensive-formatter.ts +455 -0
  102. package/test.sh +31 -0
  103. package/tsconfig.json +25 -0
@@ -0,0 +1,172 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+
4
+ interface HallucinationSectionProps {
5
+ hallucinationReport: any;
6
+ }
7
+
8
+ export const HallucinationSection: React.FC<HallucinationSectionProps> = ({ hallucinationReport }) => {
9
+ if (!hallucinationReport || Object.keys(hallucinationReport).length === 0) {
10
+ return (
11
+ <Box flexDirection="column" paddingY={1}>
12
+ <Box
13
+ flexDirection="column"
14
+ borderStyle="round"
15
+ borderColor="yellow"
16
+ paddingX={2}
17
+ paddingY={1}
18
+ >
19
+ <Text bold color="yellow">
20
+ 💡 Enable Hallucination Detection
21
+ </Text>
22
+ <Box marginTop={1} flexDirection="column">
23
+ <Text>Hallucination detection is not enabled. To see risk assessment, run:</Text>
24
+ <Box marginTop={1} borderStyle="single" paddingX={1}>
25
+ <Text color="cyan">
26
+ ai-lighthouse audit [URL] --enable-hallucination --enable-llm --llm-provider openai --llm-api-key YOUR_KEY
27
+ </Text>
28
+ </Box>
29
+ <Box marginTop={1}>
30
+ <Text dimColor>Note: Hallucination detection requires LLM analysis to be enabled</Text>
31
+ </Box>
32
+ </Box>
33
+ </Box>
34
+ </Box>
35
+ );
36
+ }
37
+
38
+ const riskScore = hallucinationReport.hallucinationRiskScore;
39
+ const getRiskColor = (score: number) => {
40
+ if (score >= 70) return 'red';
41
+ if (score >= 40) return 'yellow';
42
+ return 'green';
43
+ };
44
+
45
+ return (
46
+ <Box flexDirection="column" paddingY={1}>
47
+ {/* Risk Score */}
48
+ <Box
49
+ flexDirection="column"
50
+ borderStyle="round"
51
+ borderColor={getRiskColor(riskScore)}
52
+ paddingX={2}
53
+ paddingY={1}
54
+ marginBottom={1}
55
+ >
56
+ <Text bold color={getRiskColor(riskScore)}>
57
+ ⚠️ Hallucination Risk Assessment
58
+ </Text>
59
+ <Box marginTop={1}>
60
+ <Text>
61
+ <Text bold>Risk Score: </Text>
62
+ <Text bold color={getRiskColor(riskScore)}>
63
+ {riskScore}/100
64
+ </Text>
65
+ </Text>
66
+ </Box>
67
+ </Box>
68
+
69
+ {/* Fact Check Summary */}
70
+ {hallucinationReport.factCheckSummary && (
71
+ <Box
72
+ flexDirection="column"
73
+ borderStyle="round"
74
+ borderColor="blue"
75
+ paddingX={2}
76
+ paddingY={1}
77
+ marginBottom={1}
78
+ >
79
+ <Text bold color="blue">
80
+ 📊 Fact Check Summary
81
+ </Text>
82
+ <Box marginTop={1} flexDirection="column">
83
+ <Text>
84
+ <Text bold>Total Facts:</Text> {hallucinationReport.factCheckSummary.totalFacts}
85
+ </Text>
86
+ <Text>
87
+ <Text bold color="green">Verified:</Text> {hallucinationReport.factCheckSummary.verifiedFacts}
88
+ </Text>
89
+ <Text>
90
+ <Text bold color="yellow">Unverified:</Text> {hallucinationReport.factCheckSummary.unverifiedFacts}
91
+ </Text>
92
+ <Text>
93
+ <Text bold color="red">Contradictions:</Text> {hallucinationReport.factCheckSummary.contradictions}
94
+ </Text>
95
+ {hallucinationReport.factCheckSummary.ambiguities !== undefined && (
96
+ <Text>
97
+ <Text bold color="yellow">Ambiguities:</Text> {hallucinationReport.factCheckSummary.ambiguities}
98
+ </Text>
99
+ )}
100
+ </Box>
101
+ </Box>
102
+ )}
103
+
104
+ {/* Tip for unverified facts */}
105
+ {hallucinationReport.factCheckSummary?.unverifiedFacts > 0 && (
106
+ <Box
107
+ flexDirection="column"
108
+ borderStyle="round"
109
+ borderColor="yellow"
110
+ paddingX={2}
111
+ paddingY={1}
112
+ marginBottom={1}
113
+ >
114
+ <Text color="yellow">
115
+ 💡 Tip: Add citations and links to verify claims and reduce AI hallucination risk
116
+ </Text>
117
+ </Box>
118
+ )}
119
+
120
+ {/* High-Risk Triggers */}
121
+ {hallucinationReport.triggers && hallucinationReport.triggers.length > 0 && (
122
+ <>
123
+ {hallucinationReport.triggers.filter((t: any) => t.severity === 'high' || t.severity === 'critical').length > 0 && (
124
+ <Box flexDirection="column" marginBottom={1}>
125
+ <Text bold underline color="red">
126
+ 🚨 High-Risk Triggers
127
+ </Text>
128
+ {hallucinationReport.triggers
129
+ .filter((t: any) => t.severity === 'high' || t.severity === 'critical')
130
+ .slice(0, 5)
131
+ .map((trigger: any, idx: number) => (
132
+ <Box
133
+ key={idx}
134
+ flexDirection="column"
135
+ borderStyle="single"
136
+ borderColor="red"
137
+ paddingX={1}
138
+ paddingY={0.5}
139
+ marginTop={1}
140
+ >
141
+ <Text>
142
+ {idx + 1}. <Text bold color="red">[{trigger.severity.toUpperCase()}]</Text> {trigger.type}
143
+ </Text>
144
+ <Text dimColor>{trigger.description}</Text>
145
+ {trigger.confidence && (
146
+ <Text dimColor>Confidence: {Math.round(trigger.confidence * 100)}%</Text>
147
+ )}
148
+ </Box>
149
+ ))}
150
+ </Box>
151
+ )}
152
+ </>
153
+ )}
154
+
155
+ {/* Recommendations */}
156
+ {hallucinationReport.recommendations && hallucinationReport.recommendations.length > 0 && (
157
+ <Box flexDirection="column">
158
+ <Text bold underline color="cyan">
159
+ 💡 Recommendations
160
+ </Text>
161
+ {hallucinationReport.recommendations.slice(0, 3).map((rec: string, idx: number) => (
162
+ <Box key={idx} marginTop={0.5}>
163
+ <Text color="cyan">
164
+ {idx + 1}. {rec}
165
+ </Text>
166
+ </Box>
167
+ ))}
168
+ </Box>
169
+ )}
170
+ </Box>
171
+ );
172
+ };
@@ -0,0 +1,140 @@
1
+ import React, { useState } from 'react';
2
+ import { Box, Text } from 'ink';
3
+ import SelectInput from 'ink-select-input';
4
+
5
+ interface IssuesSectionProps {
6
+ issues: any[];
7
+ }
8
+
9
+ export const IssuesSection: React.FC<IssuesSectionProps> = ({ issues }) => {
10
+ const [selectedSeverity, setSelectedSeverity] = useState<string>('all');
11
+ const [expandedIssue, setExpandedIssue] = useState<number | null>(null);
12
+
13
+ const getSeverityColor = (severity: string) => {
14
+ if (severity === 'critical') return 'red';
15
+ if (severity === 'high') return 'magenta';
16
+ if (severity === 'medium') return 'yellow';
17
+ return 'blue';
18
+ };
19
+
20
+ const getSeverityIcon = (severity: string) => {
21
+ if (severity === 'critical') return '🔴';
22
+ if (severity === 'high') return '🟠';
23
+ if (severity === 'medium') return '🟡';
24
+ return '🔵';
25
+ };
26
+
27
+ // Group issues by severity
28
+ const grouped = {
29
+ critical: issues.filter(i => i.severity === 'critical'),
30
+ high: issues.filter(i => i.severity === 'high'),
31
+ medium: issues.filter(i => i.severity === 'medium'),
32
+ low: issues.filter(i => i.severity === 'low'),
33
+ };
34
+
35
+ const filteredIssues = selectedSeverity === 'all' ? issues : grouped[selectedSeverity as keyof typeof grouped] || [];
36
+
37
+ return (
38
+ <Box flexDirection="column" paddingY={1}>
39
+ {/* Summary Stats */}
40
+ <Box
41
+ flexDirection="column"
42
+ borderStyle="round"
43
+ borderColor="blue"
44
+ paddingX={2}
45
+ paddingY={1}
46
+ marginBottom={1}
47
+ >
48
+ <Text bold color="blue">
49
+ ⚠️ Issues Summary
50
+ </Text>
51
+ <Box marginTop={1}>
52
+ <Box flexDirection="column" width="50%">
53
+ <Text>
54
+ <Text color="red" bold>
55
+ Critical:
56
+ </Text>{' '}
57
+ {grouped.critical.length}
58
+ </Text>
59
+ <Text>
60
+ <Text color="magenta" bold>
61
+ High:
62
+ </Text>{' '}
63
+ {grouped.high.length}
64
+ </Text>
65
+ </Box>
66
+ <Box flexDirection="column" width="50%">
67
+ <Text>
68
+ <Text color="yellow" bold>
69
+ Medium:
70
+ </Text>{' '}
71
+ {grouped.medium.length}
72
+ </Text>
73
+ <Text>
74
+ <Text color="blue" bold>
75
+ Low:
76
+ </Text>{' '}
77
+ {grouped.low.length}
78
+ </Text>
79
+ </Box>
80
+ </Box>
81
+ </Box>
82
+
83
+ {/* Issue List */}
84
+ <Box flexDirection="column">
85
+ <Text bold underline>
86
+ {selectedSeverity === 'all' ? 'All Issues' : `${selectedSeverity.toUpperCase()} Issues`} ({filteredIssues.length})
87
+ </Text>
88
+ {filteredIssues.map((issue: any, idx: number) => (
89
+ <Box
90
+ key={idx}
91
+ flexDirection="column"
92
+ borderStyle="round"
93
+ borderColor={getSeverityColor(issue.severity)}
94
+ paddingX={2}
95
+ paddingY={1}
96
+ marginTop={1}
97
+ >
98
+ <Box>
99
+ <Text>
100
+ {getSeverityIcon(issue.severity)}{' '}
101
+ <Text bold color={getSeverityColor(issue.severity)}>
102
+ {issue.message || issue.title}
103
+ </Text>
104
+ </Text>
105
+ </Box>
106
+
107
+ <Box marginTop={0.5}>
108
+ <Text dimColor>
109
+ Category: {issue.category} • Impact: {issue.impact}
110
+ </Text>
111
+ </Box>
112
+
113
+ {issue.evidence && (
114
+ <Box marginTop={0.5}>
115
+ <Text dimColor>
116
+ {typeof issue.evidence === 'string'
117
+ ? issue.evidence.substring(0, 100)
118
+ : Array.isArray(issue.evidence)
119
+ ? issue.evidence.join(', ').substring(0, 100)
120
+ : ''}
121
+ {(typeof issue.evidence === 'string' ? issue.evidence : issue.evidence?.join(', ') || '').length > 100 ? '...' : ''}
122
+ </Text>
123
+ </Box>
124
+ )}
125
+
126
+ <Box
127
+ marginTop={1}
128
+ borderStyle="single"
129
+ borderColor="cyan"
130
+ paddingX={1}
131
+ paddingY={0.5}
132
+ >
133
+ <Text color="cyan">💡 Fix: {issue.suggested_fix || issue.remediation}</Text>
134
+ </Box>
135
+ </Box>
136
+ ))}
137
+ </Box>
138
+ </Box>
139
+ );
140
+ };
@@ -0,0 +1,203 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+
4
+ interface MessageAlignmentSectionProps {
5
+ mirrorReport: any;
6
+ }
7
+
8
+ export const MessageAlignmentSection: React.FC<MessageAlignmentSectionProps> = ({ mirrorReport }) => {
9
+ if (!mirrorReport || Object.keys(mirrorReport).length === 0) {
10
+ return (
11
+ <Box flexDirection="column" paddingY={1}>
12
+ <Box
13
+ flexDirection="column"
14
+ borderStyle="round"
15
+ borderColor="yellow"
16
+ paddingX={2}
17
+ paddingY={1}
18
+ >
19
+ <Text bold color="yellow">
20
+ 💡 Enable Message Alignment Analysis
21
+ </Text>
22
+ <Box marginTop={1} flexDirection="column">
23
+ <Text>Message alignment analysis is not available. To see what AI understands, run:</Text>
24
+ <Box marginTop={1} borderStyle="single" paddingX={1}>
25
+ <Text color="cyan">
26
+ ai-lighthouse audit [URL] --enable-llm --llm-provider openai --llm-api-key YOUR_KEY
27
+ </Text>
28
+ </Box>
29
+ <Box marginTop={1}>
30
+ <Text dimColor>This requires LLM analysis to compare AI understanding with your intended message</Text>
31
+ </Box>
32
+ </Box>
33
+ </Box>
34
+ </Box>
35
+ );
36
+ }
37
+
38
+ const getScoreColor = (score: number) => {
39
+ if (score >= 80) return 'green';
40
+ if (score >= 60) return 'yellow';
41
+ return 'red';
42
+ };
43
+
44
+ return (
45
+ <Box flexDirection="column" paddingY={1}>
46
+ {/* Summary Stats */}
47
+ <Box
48
+ flexDirection="column"
49
+ borderStyle="round"
50
+ borderColor="magenta"
51
+ paddingX={2}
52
+ paddingY={1}
53
+ marginBottom={1}
54
+ >
55
+ <Text bold color="magenta">
56
+ 🔍 AI Misunderstanding Check
57
+ </Text>
58
+ <Box marginTop={1} flexDirection="column">
59
+ <Box>
60
+ <Text>
61
+ <Text bold>Alignment Score:</Text>{' '}
62
+ <Text bold color={getScoreColor(mirrorReport.summary.alignmentScore)}>
63
+ {mirrorReport.summary.alignmentScore}/100
64
+ </Text>
65
+ </Text>
66
+ </Box>
67
+ <Box>
68
+ <Text>
69
+ <Text bold>Clarity Score:</Text>{' '}
70
+ <Text bold color={getScoreColor(mirrorReport.summary.clarityScore)}>
71
+ {mirrorReport.summary.clarityScore}/100
72
+ </Text>
73
+ </Text>
74
+ </Box>
75
+ <Box>
76
+ <Text>
77
+ <Text bold>Critical Issues:</Text>{' '}
78
+ <Text color="red">{mirrorReport.summary.critical}</Text>
79
+ </Text>
80
+ </Box>
81
+ <Box>
82
+ <Text>
83
+ <Text bold>Major Issues:</Text>{' '}
84
+ <Text color="yellow">{mirrorReport.summary.major}</Text>
85
+ </Text>
86
+ </Box>
87
+ </Box>
88
+ </Box>
89
+
90
+ {/* What AI Actually Understood */}
91
+ {mirrorReport.llmInterpretation && (
92
+ <Box
93
+ flexDirection="column"
94
+ borderStyle="round"
95
+ borderColor="blue"
96
+ paddingX={2}
97
+ paddingY={1}
98
+ marginBottom={1}
99
+ >
100
+ <Text bold color="blue">
101
+ 🤖 What AI Actually Understood
102
+ </Text>
103
+ <Text dimColor>({Math.round(mirrorReport.llmInterpretation.confidence * 100)}% confident)</Text>
104
+
105
+ <Box marginTop={1} flexDirection="column">
106
+ {mirrorReport.llmInterpretation.productName && (
107
+ <Text>
108
+ <Text bold>Product:</Text> {mirrorReport.llmInterpretation.productName}
109
+ </Text>
110
+ )}
111
+ {mirrorReport.llmInterpretation.purpose && (
112
+ <Text>
113
+ <Text bold>Purpose:</Text> {mirrorReport.llmInterpretation.purpose}
114
+ </Text>
115
+ )}
116
+ {mirrorReport.llmInterpretation.valueProposition && (
117
+ <Text>
118
+ <Text bold color="magenta">💎 Value:</Text> {mirrorReport.llmInterpretation.valueProposition}
119
+ </Text>
120
+ )}
121
+ </Box>
122
+
123
+ {mirrorReport.llmInterpretation.keyBenefits && mirrorReport.llmInterpretation.keyBenefits.length > 0 && (
124
+ <Box marginTop={1} flexDirection="column">
125
+ <Text bold>Benefits:</Text>
126
+ {mirrorReport.llmInterpretation.keyBenefits.map((benefit: string, idx: number) => (
127
+ <Text key={idx}>• {benefit}</Text>
128
+ ))}
129
+ </Box>
130
+ )}
131
+
132
+ {mirrorReport.llmInterpretation.keyFeatures && mirrorReport.llmInterpretation.keyFeatures.length > 0 && (
133
+ <Box marginTop={1} flexDirection="column">
134
+ <Text bold>Features:</Text>
135
+ {mirrorReport.llmInterpretation.keyFeatures.slice(0, 3).map((feature: string, idx: number) => (
136
+ <Text key={idx}>• {feature}</Text>
137
+ ))}
138
+ </Box>
139
+ )}
140
+
141
+ {mirrorReport.llmInterpretation.targetAudience && (
142
+ <Box marginTop={1}>
143
+ <Text>
144
+ <Text bold>Audience:</Text> {mirrorReport.llmInterpretation.targetAudience}
145
+ </Text>
146
+ </Box>
147
+ )}
148
+ </Box>
149
+ )}
150
+
151
+ {/* Priority Mismatches */}
152
+ {mirrorReport.mismatches && mirrorReport.mismatches.length > 0 && (
153
+ <>
154
+ {mirrorReport.mismatches.filter((m: any) => m.severity === 'critical' || m.severity === 'major').length > 0 && (
155
+ <Box flexDirection="column" marginBottom={1}>
156
+ <Text bold underline>
157
+ Priority Mismatches
158
+ </Text>
159
+ {mirrorReport.mismatches
160
+ .filter((m: any) => m.severity === 'critical' || m.severity === 'major')
161
+ .slice(0, 5)
162
+ .map((mismatch: any, idx: number) => (
163
+ <Box
164
+ key={idx}
165
+ flexDirection="column"
166
+ borderStyle="single"
167
+ borderColor={mismatch.severity === 'critical' ? 'red' : 'yellow'}
168
+ paddingX={1}
169
+ paddingY={0.5}
170
+ marginTop={1}
171
+ >
172
+ <Text>
173
+ {mismatch.severity === 'critical' ? '🔴' : '🟡'} {idx + 1}. <Text bold>{mismatch.field}</Text>
174
+ </Text>
175
+ <Text dimColor>{mismatch.description}</Text>
176
+ <Box marginTop={0.5}>
177
+ <Text color="cyan">→ {mismatch.recommendation}</Text>
178
+ </Box>
179
+ </Box>
180
+ ))}
181
+ </Box>
182
+ )}
183
+ </>
184
+ )}
185
+
186
+ {/* Recommendations */}
187
+ {mirrorReport.recommendations && mirrorReport.recommendations.length > 0 && (
188
+ <Box flexDirection="column">
189
+ <Text bold underline color="cyan">
190
+ 💡 Top Recommendations
191
+ </Text>
192
+ {mirrorReport.recommendations.slice(0, 3).map((rec: string, idx: number) => (
193
+ <Box key={idx} marginTop={0.5}>
194
+ <Text color="cyan">
195
+ {idx + 1}. {rec}
196
+ </Text>
197
+ </Box>
198
+ ))}
199
+ </Box>
200
+ )}
201
+ </Box>
202
+ );
203
+ };
@@ -0,0 +1,157 @@
1
+ import React from 'react';
2
+ import { Box, Text } from 'ink';
3
+
4
+ interface OverviewSectionProps {
5
+ aiReadiness: any;
6
+ }
7
+
8
+ export const OverviewSection: React.FC<OverviewSectionProps> = ({ aiReadiness }) => {
9
+ const getStatusColor = (status: string) => {
10
+ if (status === 'excellent') return 'green';
11
+ if (status === 'good') return 'blue';
12
+ if (status === 'needs-work') return 'yellow';
13
+ return 'red';
14
+ };
15
+
16
+ const renderProgressBar = (score: number, width: number = 20) => {
17
+ const filled = Math.round((score / 100) * width);
18
+ const empty = width - filled;
19
+ const color = score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red';
20
+
21
+ return (
22
+ <Text color={color}>
23
+ {'█'.repeat(filled)}
24
+ <Text dimColor>{'░'.repeat(empty)}</Text>
25
+ {` ${Math.round(score)}%`}
26
+ </Text>
27
+ );
28
+ };
29
+
30
+ return (
31
+ <Box flexDirection="column" paddingY={1}>
32
+ {/* AI Agent Perspective */}
33
+ <Box
34
+ flexDirection="column"
35
+ borderStyle="round"
36
+ borderColor="cyan"
37
+ paddingX={2}
38
+ paddingY={1}
39
+ marginBottom={1}
40
+ >
41
+ <Text bold color="cyan">
42
+ 🤖 AI Agent Perspective
43
+ </Text>
44
+ <Box marginTop={1} flexDirection="column">
45
+ <Box>
46
+ <Text>
47
+ {aiReadiness.aiPerspective?.canUnderstand ? '✅' : '❌'} Can Understand
48
+ {aiReadiness.aiPerspective?.canExtract ? '✅' : '❌'} Can Extract
49
+ </Text>
50
+ </Box>
51
+ <Box>
52
+ <Text>
53
+ {aiReadiness.aiPerspective?.canIndex ? '✅' : '❌'} Can Index
54
+ {aiReadiness.aiPerspective?.canAnswer ? '✅' : '❌'} Can Answer
55
+ </Text>
56
+ </Box>
57
+ <Box marginTop={1}>
58
+ <Text dimColor>
59
+ Confidence: {Math.round((aiReadiness.aiPerspective?.confidence || 0) * 100)}%
60
+ </Text>
61
+ </Box>
62
+ </Box>
63
+
64
+ {aiReadiness.aiPerspective?.mainBlockers && aiReadiness.aiPerspective.mainBlockers.length > 0 && (
65
+ <Box marginTop={1} flexDirection="column">
66
+ <Text bold color="red">
67
+ Main Blockers:
68
+ </Text>
69
+ {aiReadiness.aiPerspective.mainBlockers.map((blocker: string, idx: number) => (
70
+ <Text key={idx} color="red">
71
+ • {blocker}
72
+ </Text>
73
+ ))}
74
+ </Box>
75
+ )}
76
+ </Box>
77
+
78
+ {/* Dimension Scores */}
79
+ <Box flexDirection="column" marginTop={1}>
80
+ <Text bold underline>
81
+ 🎯 Dimension Scores
82
+ </Text>
83
+ {Object.entries(aiReadiness.dimensions || {}).map(([key, dim]: [string, any]) => (
84
+ <Box key={key} flexDirection="column" marginTop={1}>
85
+ <Box justifyContent="space-between">
86
+ <Text bold color={getStatusColor(dim.status)}>
87
+ {getDimensionIcon(key)} {formatDimensionName(key)}
88
+ </Text>
89
+ <Text color={getStatusColor(dim.status)}>{Math.round(dim.score)}/100</Text>
90
+ </Box>
91
+ <Box marginTop={0.5}>{renderProgressBar(dim.score)}</Box>
92
+ {dim.recommendation && (
93
+ <Box marginTop={0.5}>
94
+ <Text dimColor>→ {dim.recommendation}</Text>
95
+ </Box>
96
+ )}
97
+ </Box>
98
+ ))}
99
+ </Box>
100
+
101
+ {/* Quick Wins */}
102
+ {aiReadiness.quickWins && aiReadiness.quickWins.length > 0 && (
103
+ <Box
104
+ flexDirection="column"
105
+ borderStyle="round"
106
+ borderColor="yellow"
107
+ paddingX={2}
108
+ paddingY={1}
109
+ marginTop={1}
110
+ >
111
+ <Text bold color="yellow">
112
+ ⚡ Quick Wins (High Impact, Low Effort)
113
+ </Text>
114
+ {aiReadiness.quickWins.slice(0, 5).map((win: any, idx: number) => (
115
+ <Box key={idx} flexDirection="column" marginTop={1}>
116
+ <Text bold>
117
+ {idx + 1}. {win.issue}
118
+ </Text>
119
+ <Text dimColor>Impact: {win.impact} • Effort: {win.effort}</Text>
120
+ <Text color="cyan">→ {win.fix}</Text>
121
+ </Box>
122
+ ))}
123
+ </Box>
124
+ )}
125
+ </Box>
126
+ );
127
+ };
128
+
129
+ function getDimensionIcon(key: string): string {
130
+ const icons: Record<string, string> = {
131
+ technical: '⚙️',
132
+ contentQuality: '📝',
133
+ crawlability: '🕷️',
134
+ discoverability: '🔍',
135
+ knowledge: '🧠',
136
+ extractability: '🔄',
137
+ comprehensibility: '💡',
138
+ trustworthiness: '✅',
139
+ accessibility: '♿',
140
+ };
141
+ return icons[key] || '📌';
142
+ }
143
+
144
+ function formatDimensionName(key: string): string {
145
+ const names: Record<string, string> = {
146
+ technical: 'Technical',
147
+ contentQuality: 'Content Quality',
148
+ crawlability: 'Crawlability',
149
+ discoverability: 'Discoverability',
150
+ knowledge: 'Knowledge',
151
+ extractability: 'Extractability',
152
+ comprehensibility: 'Comprehensibility',
153
+ trustworthiness: 'Trustworthiness',
154
+ accessibility: 'Accessibility',
155
+ };
156
+ return names[key] || key;
157
+ }