@ai-lighthouse/cli 1.0.1 → 1.0.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/README.md +126 -53
- package/dist/index.js +2788 -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
package/dist/ui/SetupWizard.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
interface SetupWizardProps {
|
|
3
|
-
onComplete: (config: AuditConfig) => void;
|
|
4
|
-
initialUrl?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface AuditConfig {
|
|
7
|
-
url: string;
|
|
8
|
-
enableLlm: boolean;
|
|
9
|
-
enableChunking: boolean;
|
|
10
|
-
enableExtractability: boolean;
|
|
11
|
-
enableHallucination: boolean;
|
|
12
|
-
llmProvider?: string;
|
|
13
|
-
llmModel?: string;
|
|
14
|
-
llmApiKey?: string;
|
|
15
|
-
llmBaseUrl?: string;
|
|
16
|
-
}
|
|
17
|
-
export declare const SetupWizard: React.FC<SetupWizardProps>;
|
|
18
|
-
export {};
|
package/dist/ui/SetupWizard.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Box, Text, useApp } from 'ink';
|
|
3
|
-
import TextInput from 'ink-text-input';
|
|
4
|
-
import SelectInput from 'ink-select-input';
|
|
5
|
-
export const SetupWizard = ({ onComplete, initialUrl }) => {
|
|
6
|
-
const { exit } = useApp();
|
|
7
|
-
const [step, setStep] = useState(initialUrl ? 'features' : 'url');
|
|
8
|
-
const [url, setUrl] = useState(initialUrl || '');
|
|
9
|
-
const [selectedFeatures, setSelectedFeatures] = useState([]);
|
|
10
|
-
const [llmProvider, setLlmProvider] = useState('');
|
|
11
|
-
const [llmModel, setLlmModel] = useState('');
|
|
12
|
-
const [llmApiKey, setLlmApiKey] = useState('');
|
|
13
|
-
const [llmBaseUrl, setLlmBaseUrl] = useState('');
|
|
14
|
-
const featureOptions = [
|
|
15
|
-
{ label: '🧠 AI Understanding (LLM Analysis)', value: 'llm' },
|
|
16
|
-
{ label: '📄 Content Chunking Analysis', value: 'chunking' },
|
|
17
|
-
{ label: '🔄 Extractability Analysis', value: 'extractability' },
|
|
18
|
-
{ label: '⚠️ Hallucination Detection', value: 'hallucination' },
|
|
19
|
-
{ label: '✅ Continue with selected features', value: 'done' },
|
|
20
|
-
];
|
|
21
|
-
const llmProviderOptions = [
|
|
22
|
-
{ label: 'OpenAI (GPT-4, GPT-3.5)', value: 'openai' },
|
|
23
|
-
{ label: 'Anthropic (Claude)', value: 'anthropic' },
|
|
24
|
-
{ label: 'Ollama (Local)', value: 'ollama' },
|
|
25
|
-
{ label: 'Custom/Local Provider', value: 'local' },
|
|
26
|
-
];
|
|
27
|
-
const handleUrlSubmit = (value) => {
|
|
28
|
-
setUrl(value);
|
|
29
|
-
setStep('features');
|
|
30
|
-
};
|
|
31
|
-
const handleFeatureSelect = (item) => {
|
|
32
|
-
if (item.value === 'done') {
|
|
33
|
-
// Check if LLM is needed
|
|
34
|
-
if (selectedFeatures.includes('llm') || selectedFeatures.includes('hallucination')) {
|
|
35
|
-
setStep('llm-provider');
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
completeSetup();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
// Toggle feature selection
|
|
43
|
-
if (selectedFeatures.includes(item.value)) {
|
|
44
|
-
setSelectedFeatures(selectedFeatures.filter(f => f !== item.value));
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
setSelectedFeatures([...selectedFeatures, item.value]);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const handleLlmProviderSelect = (item) => {
|
|
52
|
-
setLlmProvider(item.value);
|
|
53
|
-
// Set default base URL for ollama
|
|
54
|
-
if (item.value === 'ollama') {
|
|
55
|
-
setLlmBaseUrl('http://localhost:11434');
|
|
56
|
-
}
|
|
57
|
-
setStep('llm-model');
|
|
58
|
-
};
|
|
59
|
-
const handleLlmModelSubmit = (value) => {
|
|
60
|
-
setLlmModel(value);
|
|
61
|
-
// If ollama, skip API key and go to base URL
|
|
62
|
-
if (llmProvider === 'ollama') {
|
|
63
|
-
setStep('llm-base-url');
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
setStep('llm-api-key');
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
const handleLlmApiKeySubmit = (value) => {
|
|
70
|
-
setLlmApiKey(value);
|
|
71
|
-
// If provider needs base URL, go there, otherwise complete
|
|
72
|
-
if (llmProvider === 'local' || llmProvider === 'anthropic') {
|
|
73
|
-
setStep('llm-base-url');
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
completeSetup();
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
const handleLlmBaseUrlSubmit = (value) => {
|
|
80
|
-
setLlmBaseUrl(value);
|
|
81
|
-
completeSetup();
|
|
82
|
-
};
|
|
83
|
-
const completeSetup = () => {
|
|
84
|
-
const config = {
|
|
85
|
-
url,
|
|
86
|
-
enableLlm: selectedFeatures.includes('llm') || selectedFeatures.includes('hallucination'),
|
|
87
|
-
enableChunking: selectedFeatures.includes('chunking'),
|
|
88
|
-
enableExtractability: selectedFeatures.includes('extractability'),
|
|
89
|
-
enableHallucination: selectedFeatures.includes('hallucination'),
|
|
90
|
-
};
|
|
91
|
-
if (config.enableLlm) {
|
|
92
|
-
config.llmProvider = llmProvider;
|
|
93
|
-
config.llmModel = llmModel;
|
|
94
|
-
config.llmApiKey = llmApiKey || undefined;
|
|
95
|
-
config.llmBaseUrl = llmBaseUrl || undefined;
|
|
96
|
-
}
|
|
97
|
-
onComplete(config);
|
|
98
|
-
// Exit the wizard app
|
|
99
|
-
exit();
|
|
100
|
-
};
|
|
101
|
-
const getModelPlaceholder = () => {
|
|
102
|
-
switch (llmProvider) {
|
|
103
|
-
case 'openai':
|
|
104
|
-
return 'gpt-4o-mini (default)';
|
|
105
|
-
case 'anthropic':
|
|
106
|
-
return 'claude-3-5-sonnet-20241022 (default)';
|
|
107
|
-
case 'ollama':
|
|
108
|
-
return 'qwen2.5:0.5b';
|
|
109
|
-
default:
|
|
110
|
-
return 'model-name';
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
const getApiKeyPlaceholder = () => {
|
|
114
|
-
switch (llmProvider) {
|
|
115
|
-
case 'openai':
|
|
116
|
-
return 'sk-...';
|
|
117
|
-
case 'anthropic':
|
|
118
|
-
return 'sk-ant-...';
|
|
119
|
-
default:
|
|
120
|
-
return 'your-api-key';
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
124
|
-
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
125
|
-
React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDEA8 AI Lighthouse Setup Wizard"),
|
|
126
|
-
React.createElement(Text, { dimColor: true }, "Configure your audit settings")),
|
|
127
|
-
step === 'url' && (React.createElement(Box, { flexDirection: "column" },
|
|
128
|
-
React.createElement(Text, { bold: true }, "Enter the URL to audit:"),
|
|
129
|
-
React.createElement(Box, { marginTop: 1 },
|
|
130
|
-
React.createElement(Text, { color: "cyan" }, "URL: "),
|
|
131
|
-
React.createElement(TextInput, { value: url, onChange: setUrl, onSubmit: handleUrlSubmit, placeholder: "https://example.com" })),
|
|
132
|
-
React.createElement(Box, { marginTop: 1 },
|
|
133
|
-
React.createElement(Text, { dimColor: true }, "Press Enter to continue")))),
|
|
134
|
-
step === 'features' && (React.createElement(Box, { flexDirection: "column" },
|
|
135
|
-
React.createElement(Text, { bold: true }, "Select features to enable:"),
|
|
136
|
-
React.createElement(Box, { marginTop: 1 },
|
|
137
|
-
React.createElement(Text, { dimColor: true },
|
|
138
|
-
"Selected: ",
|
|
139
|
-
selectedFeatures.length === 0 ? 'None (basic audit only)' : selectedFeatures.map(f => {
|
|
140
|
-
const feature = featureOptions.find(opt => opt.value === f);
|
|
141
|
-
return feature?.label.split(' ')[0];
|
|
142
|
-
}).join(', '))),
|
|
143
|
-
React.createElement(Box, { marginTop: 1 },
|
|
144
|
-
React.createElement(SelectInput, { items: featureOptions.map(opt => ({
|
|
145
|
-
...opt,
|
|
146
|
-
label: selectedFeatures.includes(opt.value) && opt.value !== 'done'
|
|
147
|
-
? `✓ ${opt.label}`
|
|
148
|
-
: opt.label,
|
|
149
|
-
})), onSelect: handleFeatureSelect })),
|
|
150
|
-
React.createElement(Box, { marginTop: 1 },
|
|
151
|
-
React.createElement(Text, { dimColor: true }, "Use \u2191\u2193 to navigate, Enter to toggle/continue")))),
|
|
152
|
-
step === 'llm-provider' && (React.createElement(Box, { flexDirection: "column" },
|
|
153
|
-
React.createElement(Text, { bold: true }, "Select LLM provider:"),
|
|
154
|
-
React.createElement(Box, { marginTop: 1 },
|
|
155
|
-
React.createElement(SelectInput, { items: llmProviderOptions, onSelect: handleLlmProviderSelect })),
|
|
156
|
-
React.createElement(Box, { marginTop: 1 },
|
|
157
|
-
React.createElement(Text, { dimColor: true }, "Use \u2191\u2193 to navigate, Enter to select")))),
|
|
158
|
-
step === 'llm-model' && (React.createElement(Box, { flexDirection: "column" },
|
|
159
|
-
React.createElement(Text, { bold: true }, "Enter LLM model name:"),
|
|
160
|
-
React.createElement(Box, { marginTop: 1 },
|
|
161
|
-
React.createElement(Text, { color: "cyan" }, "Model: "),
|
|
162
|
-
React.createElement(TextInput, { value: llmModel, onChange: setLlmModel, onSubmit: handleLlmModelSubmit, placeholder: getModelPlaceholder() })),
|
|
163
|
-
React.createElement(Box, { marginTop: 1 },
|
|
164
|
-
React.createElement(Text, { dimColor: true }, "Leave empty for default, or press Enter to continue")))),
|
|
165
|
-
step === 'llm-api-key' && (React.createElement(Box, { flexDirection: "column" },
|
|
166
|
-
React.createElement(Text, { bold: true }, "Enter API key:"),
|
|
167
|
-
React.createElement(Box, { marginTop: 1 },
|
|
168
|
-
React.createElement(Text, { color: "cyan" }, "API Key: "),
|
|
169
|
-
React.createElement(TextInput, { value: llmApiKey, onChange: setLlmApiKey, onSubmit: handleLlmApiKeySubmit, placeholder: getApiKeyPlaceholder(), mask: "*" })),
|
|
170
|
-
React.createElement(Box, { marginTop: 1 },
|
|
171
|
-
React.createElement(Text, { dimColor: true }, "Your API key will not be stored")))),
|
|
172
|
-
step === 'llm-base-url' && (React.createElement(Box, { flexDirection: "column" },
|
|
173
|
-
React.createElement(Text, { bold: true }, "Enter API base URL (optional):"),
|
|
174
|
-
React.createElement(Box, { marginTop: 1 },
|
|
175
|
-
React.createElement(Text, { color: "cyan" }, "Base URL: "),
|
|
176
|
-
React.createElement(TextInput, { value: llmBaseUrl, onChange: setLlmBaseUrl, onSubmit: handleLlmBaseUrlSubmit, placeholder: llmProvider === 'ollama' ? 'http://localhost:11434' : 'https://api.example.com' })),
|
|
177
|
-
React.createElement(Box, { marginTop: 1 },
|
|
178
|
-
React.createElement(Text, { dimColor: true }, "Press Enter to continue (leave empty for default)"))))));
|
|
179
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
export const AIUnderstandingSection = ({ llm }) => {
|
|
4
|
-
if (!llm || Object.keys(llm).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 AI Understanding Analysis"),
|
|
8
|
-
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
9
|
-
React.createElement(Text, null, "LLM analysis is not enabled. To see AI understanding insights, 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 }, "Supported providers: openai, anthropic, ollama, local"))))));
|
|
14
|
-
}
|
|
15
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
16
|
-
llm.pageType && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
17
|
-
React.createElement(Text, { bold: true, color: "magenta" }, "\uD83D\uDCC4 Inferred Page Type"),
|
|
18
|
-
React.createElement(Text, { color: "cyan" }, llm.pageType))),
|
|
19
|
-
llm.pageTypeInsights && llm.pageTypeInsights.length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
20
|
-
React.createElement(Text, { bold: true, underline: true, color: "blue" }, "\uD83D\uDCA1 AI-Generated Insights"),
|
|
21
|
-
llm.pageTypeInsights.map((insight, idx) => (React.createElement(Box, { key: idx, marginTop: 0.5 },
|
|
22
|
-
React.createElement(Text, { color: "cyan" },
|
|
23
|
-
"\u2022 ",
|
|
24
|
-
insight)))))),
|
|
25
|
-
llm.summary && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
26
|
-
React.createElement(Text, { bold: true, underline: true }, "Summary"),
|
|
27
|
-
React.createElement(Box, { marginTop: 0.5 },
|
|
28
|
-
React.createElement(Text, null, llm.summary)))),
|
|
29
|
-
llm.keyTopics && llm.keyTopics.length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
30
|
-
React.createElement(Text, { bold: true, underline: true }, "\uD83C\uDFF7\uFE0F Key Topics"),
|
|
31
|
-
React.createElement(Box, { marginTop: 0.5 },
|
|
32
|
-
React.createElement(Text, null, llm.keyTopics.map((t) => `[${t}]`).join(' '))))),
|
|
33
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
34
|
-
React.createElement(Text, { bold: true, underline: true }, "Metadata"),
|
|
35
|
-
React.createElement(Box, { marginTop: 0.5, flexDirection: "column" },
|
|
36
|
-
llm.readingLevel && (React.createElement(Text, null,
|
|
37
|
-
React.createElement(Text, { bold: true }, "Reading Level:"),
|
|
38
|
-
" ",
|
|
39
|
-
llm.readingLevel.description)),
|
|
40
|
-
llm.sentiment && (React.createElement(Text, null,
|
|
41
|
-
React.createElement(Text, { bold: true }, "Sentiment:"),
|
|
42
|
-
" ",
|
|
43
|
-
llm.sentiment)),
|
|
44
|
-
llm.technicalDepth && (React.createElement(Text, null,
|
|
45
|
-
React.createElement(Text, { bold: true }, "Technical Depth:"),
|
|
46
|
-
" ",
|
|
47
|
-
llm.technicalDepth)))),
|
|
48
|
-
llm.topEntities && llm.topEntities.length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
49
|
-
React.createElement(Text, { bold: true, underline: true }, "\uD83D\uDD0D Key Entities"),
|
|
50
|
-
llm.topEntities.slice(0, 5).map((entity, idx) => (React.createElement(Box, { key: idx, marginTop: 0.5 },
|
|
51
|
-
React.createElement(Text, null,
|
|
52
|
-
"\u2022 ",
|
|
53
|
-
React.createElement(Text, { bold: true }, entity.name),
|
|
54
|
-
' ',
|
|
55
|
-
React.createElement(Text, { dimColor: true },
|
|
56
|
-
"(",
|
|
57
|
-
entity.type,
|
|
58
|
-
") - ",
|
|
59
|
-
Math.round((entity.relevance || 0) * 100),
|
|
60
|
-
"% relevance"))))))),
|
|
61
|
-
llm.questions && llm.questions.length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
62
|
-
React.createElement(Text, { bold: true, underline: true }, "\u2753 Questions AI Can Answer"),
|
|
63
|
-
llm.questions.slice(0, 5).map((q, idx) => (React.createElement(Box, { key: idx, marginTop: 0.5 },
|
|
64
|
-
React.createElement(Text, null,
|
|
65
|
-
idx + 1,
|
|
66
|
-
". ",
|
|
67
|
-
React.createElement(Text, { dimColor: true },
|
|
68
|
-
"[",
|
|
69
|
-
q.difficulty.toUpperCase(),
|
|
70
|
-
"]"),
|
|
71
|
-
" ",
|
|
72
|
-
q.question)))))),
|
|
73
|
-
llm.suggestedFAQ && llm.suggestedFAQ.length > 0 && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1 },
|
|
74
|
-
React.createElement(Text, { bold: true, color: "yellow" }, "\uD83D\uDCA1 Suggested FAQs"),
|
|
75
|
-
llm.suggestedFAQ
|
|
76
|
-
.filter((f) => f.importance === 'high')
|
|
77
|
-
.slice(0, 3)
|
|
78
|
-
.map((faq, idx) => (React.createElement(Box, { key: idx, flexDirection: "column", marginTop: 1 },
|
|
79
|
-
React.createElement(Text, null,
|
|
80
|
-
React.createElement(Text, { bold: true }, "Q:"),
|
|
81
|
-
" ",
|
|
82
|
-
faq.question),
|
|
83
|
-
React.createElement(Text, { dimColor: true },
|
|
84
|
-
React.createElement(Text, { bold: true }, "A:"),
|
|
85
|
-
" ",
|
|
86
|
-
faq.suggestedAnswer))))))));
|
|
87
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
export const HallucinationSection = ({ hallucinationReport }) => {
|
|
4
|
-
if (!hallucinationReport || Object.keys(hallucinationReport).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 Hallucination Detection"),
|
|
8
|
-
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
9
|
-
React.createElement(Text, null, "Hallucination detection is not enabled. To see risk assessment, run:"),
|
|
10
|
-
React.createElement(Box, { marginTop: 1, borderStyle: "single", paddingX: 1 },
|
|
11
|
-
React.createElement(Text, { color: "cyan" }, "ai-lighthouse audit [URL] --enable-hallucination --enable-llm --llm-provider openai --llm-api-key YOUR_KEY")),
|
|
12
|
-
React.createElement(Box, { marginTop: 1 },
|
|
13
|
-
React.createElement(Text, { dimColor: true }, "Note: Hallucination detection requires LLM analysis to be enabled"))))));
|
|
14
|
-
}
|
|
15
|
-
const riskScore = hallucinationReport.hallucinationRiskScore;
|
|
16
|
-
const getRiskColor = (score) => {
|
|
17
|
-
if (score >= 70)
|
|
18
|
-
return 'red';
|
|
19
|
-
if (score >= 40)
|
|
20
|
-
return 'yellow';
|
|
21
|
-
return 'green';
|
|
22
|
-
};
|
|
23
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
24
|
-
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: getRiskColor(riskScore), paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
25
|
-
React.createElement(Text, { bold: true, color: getRiskColor(riskScore) }, "\u26A0\uFE0F Hallucination Risk Assessment"),
|
|
26
|
-
React.createElement(Box, { marginTop: 1 },
|
|
27
|
-
React.createElement(Text, null,
|
|
28
|
-
React.createElement(Text, { bold: true }, "Risk Score: "),
|
|
29
|
-
React.createElement(Text, { bold: true, color: getRiskColor(riskScore) },
|
|
30
|
-
riskScore,
|
|
31
|
-
"/100")))),
|
|
32
|
-
hallucinationReport.factCheckSummary && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
33
|
-
React.createElement(Text, { bold: true, color: "blue" }, "\uD83D\uDCCA Fact Check Summary"),
|
|
34
|
-
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
35
|
-
React.createElement(Text, null,
|
|
36
|
-
React.createElement(Text, { bold: true }, "Total Facts:"),
|
|
37
|
-
" ",
|
|
38
|
-
hallucinationReport.factCheckSummary.totalFacts),
|
|
39
|
-
React.createElement(Text, null,
|
|
40
|
-
React.createElement(Text, { bold: true, color: "green" }, "Verified:"),
|
|
41
|
-
" ",
|
|
42
|
-
hallucinationReport.factCheckSummary.verifiedFacts),
|
|
43
|
-
React.createElement(Text, null,
|
|
44
|
-
React.createElement(Text, { bold: true, color: "yellow" }, "Unverified:"),
|
|
45
|
-
" ",
|
|
46
|
-
hallucinationReport.factCheckSummary.unverifiedFacts),
|
|
47
|
-
React.createElement(Text, null,
|
|
48
|
-
React.createElement(Text, { bold: true, color: "red" }, "Contradictions:"),
|
|
49
|
-
" ",
|
|
50
|
-
hallucinationReport.factCheckSummary.contradictions),
|
|
51
|
-
hallucinationReport.factCheckSummary.ambiguities !== undefined && (React.createElement(Text, null,
|
|
52
|
-
React.createElement(Text, { bold: true, color: "yellow" }, "Ambiguities:"),
|
|
53
|
-
" ",
|
|
54
|
-
hallucinationReport.factCheckSummary.ambiguities))))),
|
|
55
|
-
hallucinationReport.factCheckSummary?.unverifiedFacts > 0 && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
56
|
-
React.createElement(Text, { color: "yellow" }, "\uD83D\uDCA1 Tip: Add citations and links to verify claims and reduce AI hallucination risk"))),
|
|
57
|
-
hallucinationReport.triggers && hallucinationReport.triggers.length > 0 && (React.createElement(React.Fragment, null, hallucinationReport.triggers.filter((t) => t.severity === 'high' || t.severity === 'critical').length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
58
|
-
React.createElement(Text, { bold: true, underline: true, color: "red" }, "\uD83D\uDEA8 High-Risk Triggers"),
|
|
59
|
-
hallucinationReport.triggers
|
|
60
|
-
.filter((t) => t.severity === 'high' || t.severity === 'critical')
|
|
61
|
-
.slice(0, 5)
|
|
62
|
-
.map((trigger, idx) => (React.createElement(Box, { key: idx, flexDirection: "column", borderStyle: "single", borderColor: "red", paddingX: 1, paddingY: 0.5, marginTop: 1 },
|
|
63
|
-
React.createElement(Text, null,
|
|
64
|
-
idx + 1,
|
|
65
|
-
". ",
|
|
66
|
-
React.createElement(Text, { bold: true, color: "red" },
|
|
67
|
-
"[",
|
|
68
|
-
trigger.severity.toUpperCase(),
|
|
69
|
-
"]"),
|
|
70
|
-
" ",
|
|
71
|
-
trigger.type),
|
|
72
|
-
React.createElement(Text, { dimColor: true }, trigger.description),
|
|
73
|
-
trigger.confidence && (React.createElement(Text, { dimColor: true },
|
|
74
|
-
"Confidence: ",
|
|
75
|
-
Math.round(trigger.confidence * 100),
|
|
76
|
-
"%"))))))))),
|
|
77
|
-
hallucinationReport.recommendations && hallucinationReport.recommendations.length > 0 && (React.createElement(Box, { flexDirection: "column" },
|
|
78
|
-
React.createElement(Text, { bold: true, underline: true, color: "cyan" }, "\uD83D\uDCA1 Recommendations"),
|
|
79
|
-
hallucinationReport.recommendations.slice(0, 3).map((rec, idx) => (React.createElement(Box, { key: idx, marginTop: 0.5 },
|
|
80
|
-
React.createElement(Text, { color: "cyan" },
|
|
81
|
-
idx + 1,
|
|
82
|
-
". ",
|
|
83
|
-
rec))))))));
|
|
84
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
export const IssuesSection = ({ issues }) => {
|
|
4
|
-
const [selectedSeverity, setSelectedSeverity] = useState('all');
|
|
5
|
-
const [expandedIssue, setExpandedIssue] = useState(null);
|
|
6
|
-
const getSeverityColor = (severity) => {
|
|
7
|
-
if (severity === 'critical')
|
|
8
|
-
return 'red';
|
|
9
|
-
if (severity === 'high')
|
|
10
|
-
return 'magenta';
|
|
11
|
-
if (severity === 'medium')
|
|
12
|
-
return 'yellow';
|
|
13
|
-
return 'blue';
|
|
14
|
-
};
|
|
15
|
-
const getSeverityIcon = (severity) => {
|
|
16
|
-
if (severity === 'critical')
|
|
17
|
-
return '🔴';
|
|
18
|
-
if (severity === 'high')
|
|
19
|
-
return '🟠';
|
|
20
|
-
if (severity === 'medium')
|
|
21
|
-
return '🟡';
|
|
22
|
-
return '🔵';
|
|
23
|
-
};
|
|
24
|
-
// Group issues by severity
|
|
25
|
-
const grouped = {
|
|
26
|
-
critical: issues.filter(i => i.severity === 'critical'),
|
|
27
|
-
high: issues.filter(i => i.severity === 'high'),
|
|
28
|
-
medium: issues.filter(i => i.severity === 'medium'),
|
|
29
|
-
low: issues.filter(i => i.severity === 'low'),
|
|
30
|
-
};
|
|
31
|
-
const filteredIssues = selectedSeverity === 'all' ? issues : grouped[selectedSeverity] || [];
|
|
32
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
|
|
33
|
-
React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 2, paddingY: 1, marginBottom: 1 },
|
|
34
|
-
React.createElement(Text, { bold: true, color: "blue" }, "\u26A0\uFE0F Issues Summary"),
|
|
35
|
-
React.createElement(Box, { marginTop: 1 },
|
|
36
|
-
React.createElement(Box, { flexDirection: "column", width: "50%" },
|
|
37
|
-
React.createElement(Text, null,
|
|
38
|
-
React.createElement(Text, { color: "red", bold: true }, "Critical:"),
|
|
39
|
-
' ',
|
|
40
|
-
grouped.critical.length),
|
|
41
|
-
React.createElement(Text, null,
|
|
42
|
-
React.createElement(Text, { color: "magenta", bold: true }, "High:"),
|
|
43
|
-
' ',
|
|
44
|
-
grouped.high.length)),
|
|
45
|
-
React.createElement(Box, { flexDirection: "column", width: "50%" },
|
|
46
|
-
React.createElement(Text, null,
|
|
47
|
-
React.createElement(Text, { color: "yellow", bold: true }, "Medium:"),
|
|
48
|
-
' ',
|
|
49
|
-
grouped.medium.length),
|
|
50
|
-
React.createElement(Text, null,
|
|
51
|
-
React.createElement(Text, { color: "blue", bold: true }, "Low:"),
|
|
52
|
-
' ',
|
|
53
|
-
grouped.low.length)))),
|
|
54
|
-
React.createElement(Box, { flexDirection: "column" },
|
|
55
|
-
React.createElement(Text, { bold: true, underline: true },
|
|
56
|
-
selectedSeverity === 'all' ? 'All Issues' : `${selectedSeverity.toUpperCase()} Issues`,
|
|
57
|
-
" (",
|
|
58
|
-
filteredIssues.length,
|
|
59
|
-
")"),
|
|
60
|
-
filteredIssues.map((issue, idx) => (React.createElement(Box, { key: idx, flexDirection: "column", borderStyle: "round", borderColor: getSeverityColor(issue.severity), paddingX: 2, paddingY: 1, marginTop: 1 },
|
|
61
|
-
React.createElement(Box, null,
|
|
62
|
-
React.createElement(Text, null,
|
|
63
|
-
getSeverityIcon(issue.severity),
|
|
64
|
-
' ',
|
|
65
|
-
React.createElement(Text, { bold: true, color: getSeverityColor(issue.severity) }, issue.message || issue.title))),
|
|
66
|
-
React.createElement(Box, { marginTop: 0.5 },
|
|
67
|
-
React.createElement(Text, { dimColor: true },
|
|
68
|
-
"Category: ",
|
|
69
|
-
issue.category,
|
|
70
|
-
" \u2022 Impact: ",
|
|
71
|
-
issue.impact)),
|
|
72
|
-
issue.evidence && (React.createElement(Box, { marginTop: 0.5 },
|
|
73
|
-
React.createElement(Text, { dimColor: true },
|
|
74
|
-
typeof issue.evidence === 'string'
|
|
75
|
-
? issue.evidence.substring(0, 100)
|
|
76
|
-
: Array.isArray(issue.evidence)
|
|
77
|
-
? issue.evidence.join(', ').substring(0, 100)
|
|
78
|
-
: '',
|
|
79
|
-
(typeof issue.evidence === 'string' ? issue.evidence : issue.evidence?.join(', ') || '').length > 100 ? '...' : ''))),
|
|
80
|
-
React.createElement(Box, { marginTop: 1, borderStyle: "single", borderColor: "cyan", paddingX: 1, paddingY: 0.5 },
|
|
81
|
-
React.createElement(Text, { color: "cyan" },
|
|
82
|
-
"\uD83D\uDCA1 Fix: ",
|
|
83
|
-
issue.suggested_fix || issue.remediation))))))));
|
|
84
|
-
};
|
|
@@ -1,108 +0,0 @@
|
|
|
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
|
-
};
|