@ai-lighthouse/cli 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2573 -12
- package/package.json +10 -4
- package/.ai-lighthouse/audit_example.com_2025-12-15T12-10-43.json +0 -183
- package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-32-28.html +0 -743
- package/.ai-lighthouse/audit_fayeed.dev_2026-01-07T19-33-02.html +0 -757
- package/.ai-lighthouse/audit_github.com_2025-12-15T11-53-21.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-04-06.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-05-10.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-09-45.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-11-07.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-13-28.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-14-59.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-07.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-18-44.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-21-38.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-21.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-22-46.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-23-18.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-15T12-24-43.json +0 -205
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-08.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-15-57.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-17-11.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-17.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-22-42.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-23-56.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-24.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-25-40.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-02.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-27-20.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-29-56.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-32-27.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-33-00.json +0 -168
- package/.ai-lighthouse/audit_github.com_2025-12-17T12-34-49.json +0 -168
- package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-31.json +0 -168
- package/.ai-lighthouse/audit_stripe.com_2025-12-15T12-11-45.json +0 -168
- package/.ai-lighthouse/audit_tailwindcss.com_2025-12-15T12-12-01.json +0 -169
- package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-08.json +0 -24
- package/.ai-lighthouse/crawl_example.com_2025-12-15T12-03-23.json +0 -24
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-41-34.json +0 -21
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-09.json +0 -21
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-42-45.json +0 -21
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-02.json +0 -21
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-43-26.json +0 -21
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-47-46.json +0 -906
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-50-27.json +0 -906
- package/.ai-lighthouse/crawl_github.com_2025-12-15T11-52-59.json +0 -906
- package/.ai-lighthouse/crawl_github.com_2025-12-15T12-03-33.json +0 -28
- package/CLI_UI_README.md +0 -211
- package/EXAMPLES.md +0 -87
- package/IMPLEMENTATION.md +0 -215
- package/USAGE.md +0 -264
- package/WIZARD_GUIDE.md +0 -340
- package/bin/cli.js +0 -2
- package/dist/commands/audit-interactive.d.ts +0 -2
- package/dist/commands/audit-interactive.js +0 -106
- package/dist/commands/audit-wizard.d.ts +0 -2
- package/dist/commands/audit-wizard.js +0 -110
- package/dist/commands/audit.d.ts +0 -2
- package/dist/commands/audit.js +0 -940
- package/dist/commands/crawl.d.ts +0 -2
- package/dist/commands/crawl.js +0 -267
- package/dist/commands/report.d.ts +0 -2
- package/dist/commands/report.js +0 -304
- package/dist/index.d.ts +0 -1
- package/dist/ui/AuditReportUI.d.ts +0 -10
- package/dist/ui/AuditReportUI.js +0 -76
- package/dist/ui/SetupWizard.d.ts +0 -18
- package/dist/ui/SetupWizard.js +0 -179
- package/dist/ui/components/AIUnderstandingSection.d.ts +0 -6
- package/dist/ui/components/AIUnderstandingSection.js +0 -87
- package/dist/ui/components/HallucinationSection.d.ts +0 -6
- package/dist/ui/components/HallucinationSection.js +0 -84
- package/dist/ui/components/IssuesSection.d.ts +0 -6
- package/dist/ui/components/IssuesSection.js +0 -84
- package/dist/ui/components/MessageAlignmentSection.d.ts +0 -6
- package/dist/ui/components/MessageAlignmentSection.js +0 -108
- package/dist/ui/components/OverviewSection.d.ts +0 -6
- package/dist/ui/components/OverviewSection.js +0 -107
- package/dist/ui/components/ScoreDisplay.d.ts +0 -8
- package/dist/ui/components/ScoreDisplay.js +0 -41
- package/dist/ui/components/TechnicalSection.d.ts +0 -7
- package/dist/ui/components/TechnicalSection.js +0 -110
- package/dist/utils/comprehensive-formatter.d.ts +0 -5
- package/dist/utils/comprehensive-formatter.js +0 -370
- package/src/commands/audit-interactive.ts +0 -149
- package/src/commands/audit-wizard.ts +0 -137
- package/src/commands/audit.ts +0 -1012
- package/src/commands/crawl.ts +0 -307
- package/src/commands/report.ts +0 -321
- package/src/index.ts +0 -22
- package/src/ui/AuditReportUI.tsx +0 -151
- package/src/ui/SetupWizard.tsx +0 -294
- package/src/ui/components/AIUnderstandingSection.tsx +0 -183
- package/src/ui/components/HallucinationSection.tsx +0 -172
- package/src/ui/components/IssuesSection.tsx +0 -140
- package/src/ui/components/MessageAlignmentSection.tsx +0 -203
- package/src/ui/components/OverviewSection.tsx +0 -157
- package/src/ui/components/ScoreDisplay.tsx +0 -58
- package/src/ui/components/TechnicalSection.tsx +0 -200
- package/src/utils/comprehensive-formatter.ts +0 -455
- package/test.sh +0 -31
- package/tsconfig.json +0 -25
|
@@ -1,172 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,140 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,203 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,157 +0,0 @@
|
|
|
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
|
-
}
|