vantaverse-ai-reviewer 0.1.5 โ†’ 0.2.1

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.
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Interactive Logger - Agentic CLI output with motivating messages
3
+ */
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ // Agentic thinking messages for different phases
7
+ const AGENTIC_MESSAGES = {
8
+ scanning: [
9
+ '๐Ÿ” Scanning project structure...',
10
+ '๐Ÿ“‚ Discovering source files...',
11
+ '๐Ÿงฌ Analyzing file patterns...',
12
+ '๐Ÿ”Ž Indexing codebase...',
13
+ '๐Ÿ“Š Building file tree...'
14
+ ],
15
+ security: [
16
+ '๐Ÿ” Analyzing security patterns...',
17
+ '๐Ÿ›ก๏ธ Checking for vulnerabilities...',
18
+ '๐Ÿ”’ Scanning for exposed secrets...',
19
+ 'โš ๏ธ Reviewing authentication flows...',
20
+ '๐Ÿ”‘ Validating access controls...'
21
+ ],
22
+ codeQuality: [
23
+ '๐Ÿงน Reviewing code quality...',
24
+ '๐Ÿ”ง Analyzing code patterns...',
25
+ '๐Ÿ“ Checking architecture...',
26
+ '๐ŸŽฏ Identifying code smells...',
27
+ 'โœจ Evaluating best practices...'
28
+ ],
29
+ accessibility: [
30
+ 'โ™ฟ Checking accessibility...',
31
+ '๐ŸŽจ Reviewing WCAG compliance...',
32
+ '๐Ÿ–ฅ๏ธ Analyzing screen reader support...',
33
+ 'โŒจ๏ธ Testing keyboard navigation...',
34
+ '๐Ÿ‘๏ธ Checking color contrast...'
35
+ ],
36
+ uiux: [
37
+ '๐ŸŽจ Analyzing user experience...',
38
+ '๐Ÿ“ฑ Reviewing responsive design...',
39
+ 'โšก Checking loading states...',
40
+ '๐Ÿ’ซ Reviewing interactions...',
41
+ '๐ŸŽญ Analyzing UI patterns...'
42
+ ],
43
+ testing: [
44
+ '๐Ÿงช Analyzing test coverage...',
45
+ 'โœ… Reviewing test patterns...',
46
+ '๐Ÿ”ฌ Identifying test gaps...',
47
+ '๐Ÿ“‹ Suggesting test cases...',
48
+ '๐ŸŽฏ Finding edge cases...'
49
+ ],
50
+ overview: [
51
+ '๐Ÿ“‹ Building project overview...',
52
+ '๐Ÿ—๏ธ Analyzing architecture...',
53
+ '๐Ÿ“Š Evaluating project health...',
54
+ '๐ŸŽฏ Identifying priorities...',
55
+ '๐Ÿ’ก Generating recommendations...'
56
+ ]
57
+ };
58
+ // Motivational messages during AI analysis
59
+ const MOTIVATIONAL_MESSAGES = [
60
+ '๐Ÿค– AI is thinking deeply...',
61
+ '๐Ÿง  Processing code patterns...',
62
+ '๐Ÿ’ญ Formulating insights...',
63
+ '๐Ÿ”ฎ Generating recommendations...',
64
+ '๐Ÿ“ Crafting detailed analysis...',
65
+ 'โœจ Almost there...',
66
+ '๐ŸŽฏ Focusing on key issues...',
67
+ '๐Ÿ’ก Finding improvements...',
68
+ '๐Ÿ” Deep diving into code...',
69
+ '๐Ÿ“Š Building comprehensive report...'
70
+ ];
71
+ /**
72
+ * Create an interactive spinner with rotating agentic messages
73
+ */
74
+ export function createAgenticSpinner(initialText) {
75
+ const spin = ora({
76
+ text: initialText,
77
+ color: 'cyan',
78
+ spinner: 'dots'
79
+ });
80
+ let messageInterval = null;
81
+ let currentPhase = 'scanning';
82
+ let messageIndex = 0;
83
+ const updatePhase = (phase) => {
84
+ currentPhase = phase;
85
+ messageIndex = 0;
86
+ const messages = AGENTIC_MESSAGES[phase];
87
+ if (messages && messages.length > 0) {
88
+ spin.text = messages[0];
89
+ }
90
+ };
91
+ const updateFile = (fileName, action) => {
92
+ const shortName = fileName.length > 40
93
+ ? '...' + fileName.slice(-37)
94
+ : fileName;
95
+ spin.text = `${action} ${chalk.cyan(shortName)}`;
96
+ };
97
+ const showThinking = () => {
98
+ if (messageInterval)
99
+ clearInterval(messageInterval);
100
+ let thinkingIndex = 0;
101
+ messageInterval = setInterval(() => {
102
+ spin.text = MOTIVATIONAL_MESSAGES[thinkingIndex % MOTIVATIONAL_MESSAGES.length];
103
+ thinkingIndex++;
104
+ }, 2000);
105
+ };
106
+ const stop = () => {
107
+ if (messageInterval) {
108
+ clearInterval(messageInterval);
109
+ messageInterval = null;
110
+ }
111
+ };
112
+ return { spinner: spin, updatePhase, updateFile, showThinking, stop };
113
+ }
114
+ /**
115
+ * Display file scanning progress
116
+ */
117
+ export function showFileScanProgress(files, onFile) {
118
+ for (const file of files) {
119
+ const ext = file.split('.').pop() || '';
120
+ const icon = getFileIcon(ext);
121
+ const shortName = file.length > 50 ? '...' + file.slice(-47) : file;
122
+ console.log(` ${icon} ${chalk.gray(shortName)} ${chalk.green('[scanned]')}`);
123
+ onFile?.(file);
124
+ }
125
+ }
126
+ /**
127
+ * Get icon for file extension
128
+ */
129
+ function getFileIcon(ext) {
130
+ const icons = {
131
+ 'ts': '๐Ÿ“˜',
132
+ 'tsx': 'โš›๏ธ',
133
+ 'js': '๐Ÿ“™',
134
+ 'jsx': 'โš›๏ธ',
135
+ 'py': '๐Ÿ',
136
+ 'vue': '๐Ÿ’š',
137
+ 'svelte': '๐Ÿงก',
138
+ 'css': '๐ŸŽจ',
139
+ 'scss': '๐ŸŽจ',
140
+ 'html': '๐Ÿ“„',
141
+ 'json': '๐Ÿ“‹',
142
+ 'md': '๐Ÿ“',
143
+ 'yaml': 'โš™๏ธ',
144
+ 'yml': 'โš™๏ธ',
145
+ 'test': '๐Ÿงช',
146
+ 'spec': '๐Ÿงช'
147
+ };
148
+ return icons[ext] || '๐Ÿ“„';
149
+ }
150
+ /**
151
+ * Show analysis phase header with agentic messaging
152
+ */
153
+ export function showAnalysisPhase(phase, fileCount) {
154
+ console.log();
155
+ console.log(chalk.bold.cyan(` โ”Œโ”€ ${phase}`));
156
+ console.log(chalk.gray(` โ”‚ Analyzing ${fileCount} files...`));
157
+ }
158
+ /**
159
+ * Show analysis complete for a phase
160
+ */
161
+ export function showAnalysisComplete(phase, duration, findings) {
162
+ const icon = findings > 0 ? 'โš ๏ธ' : 'โœ…';
163
+ console.log(chalk.gray(` โ”‚ ${icon} ${findings} findings (${duration}ms)`));
164
+ console.log(chalk.cyan(` โ””โ”€ Complete`));
165
+ }
166
+ /**
167
+ * Show real-time AI thinking indicator
168
+ */
169
+ export function showAIThinking(message) {
170
+ process.stdout.write(`\r ${chalk.yellow('๐Ÿค–')} ${chalk.gray(message)} `);
171
+ }
172
+ /**
173
+ * Display test file detection
174
+ */
175
+ export function showTestFileSearch(pattern) {
176
+ console.log(chalk.gray(` ๐Ÿ” Searching for ${chalk.cyan(pattern)} files...`));
177
+ }
178
+ /**
179
+ * Create boxed status display
180
+ */
181
+ export function showStatusBox(items) {
182
+ const maxKeyLen = Math.max(...Object.keys(items).map(k => k.length));
183
+ console.log(chalk.cyan(' โ”Œ' + 'โ”€'.repeat(50) + 'โ”'));
184
+ for (const [key, value] of Object.entries(items)) {
185
+ const paddedKey = key.padEnd(maxKeyLen);
186
+ console.log(chalk.cyan(' โ”‚') + ` ${paddedKey}: ${chalk.white(value)}`.padEnd(50) + chalk.cyan('โ”‚'));
187
+ }
188
+ console.log(chalk.cyan(' โ””' + 'โ”€'.repeat(50) + 'โ”˜'));
189
+ }
190
+ //# sourceMappingURL=interactive-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-logger.js","sourceRoot":"","sources":["../../src/utils/interactive-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Token Estimator - Pre-scan cost estimation
3
+ */
4
+ import type { ScannedFile } from '../core/scanner.js';
5
+ import type { PromptType } from '../ai/prompts.js';
6
+ export interface TokenEstimate {
7
+ inputTokens: number;
8
+ outputTokens: number;
9
+ totalTokens: number;
10
+ estimatedCost: number;
11
+ breakdown: Partial<Record<PromptType, number>>;
12
+ warning?: string;
13
+ }
14
+ /**
15
+ * Estimate token count from file content
16
+ */
17
+ export declare function estimateTokens(content: string): number;
18
+ /**
19
+ * Estimate total cost for scanning files
20
+ */
21
+ export declare function estimateScanCost(files: ScannedFile[], analysisTypes: PromptType[], maxCharsPerBatch?: number): TokenEstimate;
22
+ /**
23
+ * Format estimate for display
24
+ */
25
+ export declare function formatEstimate(estimate: TokenEstimate): string;
26
+ //# sourceMappingURL=token-estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../../src/utils/token-estimator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC5B,KAAK,EAAE,WAAW,EAAE,EACpB,aAAa,EAAE,UAAU,EAAE,EAC3B,gBAAgB,GAAE,MAAc,GACjC,aAAa,CAgDf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAc9D"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Token Estimator - Pre-scan cost estimation
3
+ */
4
+ // Approximate characters per token for code
5
+ const CHARS_PER_TOKEN = 4;
6
+ // Gemini pricing (as of 2024) - adjust as needed
7
+ const PRICE_PER_1M_INPUT_TOKENS = 0.075; // $0.075 per 1M input tokens
8
+ const PRICE_PER_1M_OUTPUT_TOKENS = 0.30; // $0.30 per 1M output tokens
9
+ // Average output tokens per analysis type
10
+ const OUTPUT_TOKENS_BY_TYPE = {
11
+ security: 800,
12
+ codeQuality: 1000,
13
+ accessibility: 600,
14
+ uiux: 700,
15
+ testing: 900,
16
+ overview: 1200
17
+ };
18
+ // Base prompt sizes (approximate)
19
+ const PROMPT_TOKENS_BY_TYPE = {
20
+ security: 200,
21
+ codeQuality: 250,
22
+ accessibility: 220,
23
+ uiux: 200,
24
+ testing: 230,
25
+ overview: 300
26
+ };
27
+ /**
28
+ * Estimate token count from file content
29
+ */
30
+ export function estimateTokens(content) {
31
+ return Math.ceil(content.length / CHARS_PER_TOKEN);
32
+ }
33
+ /**
34
+ * Estimate total cost for scanning files
35
+ */
36
+ export function estimateScanCost(files, analysisTypes, maxCharsPerBatch = 50000) {
37
+ let totalInputTokens = 0;
38
+ let totalOutputTokens = 0;
39
+ const breakdown = {};
40
+ // Calculate input tokens from files (estimate based on size)
41
+ const totalFileSize = files.reduce((sum, f) => sum + f.size, 0);
42
+ const fileTokens = Math.ceil(totalFileSize / CHARS_PER_TOKEN);
43
+ // Cap at max batch size
44
+ const effectiveFileTokens = Math.min(fileTokens, maxCharsPerBatch / CHARS_PER_TOKEN);
45
+ for (const type of analysisTypes) {
46
+ // Input: prompt + context + files
47
+ const promptTokens = PROMPT_TOKENS_BY_TYPE[type];
48
+ const contextTokens = 200; // Estimated context size
49
+ const typeInputTokens = promptTokens + contextTokens + (effectiveFileTokens / analysisTypes.length);
50
+ // Output: estimated response size
51
+ const typeOutputTokens = OUTPUT_TOKENS_BY_TYPE[type];
52
+ breakdown[type] = Math.ceil(typeInputTokens + typeOutputTokens);
53
+ totalInputTokens += typeInputTokens;
54
+ totalOutputTokens += typeOutputTokens;
55
+ }
56
+ const inputCost = (totalInputTokens / 1_000_000) * PRICE_PER_1M_INPUT_TOKENS;
57
+ const outputCost = (totalOutputTokens / 1_000_000) * PRICE_PER_1M_OUTPUT_TOKENS;
58
+ const totalCost = inputCost + outputCost;
59
+ const totalTokens = totalInputTokens + totalOutputTokens;
60
+ let warning;
61
+ if (totalCost > 0.10) {
62
+ warning = `โš ๏ธ High cost estimate: $${totalCost.toFixed(4)}. Consider using --diff mode.`;
63
+ }
64
+ if (totalTokens > 100000) {
65
+ warning = `โš ๏ธ High token usage: ${(totalTokens / 1000).toFixed(1)}k tokens. Consider using --diff mode.`;
66
+ }
67
+ return {
68
+ inputTokens: Math.ceil(totalInputTokens),
69
+ outputTokens: Math.ceil(totalOutputTokens),
70
+ totalTokens: Math.ceil(totalTokens),
71
+ estimatedCost: totalCost,
72
+ breakdown,
73
+ warning
74
+ };
75
+ }
76
+ /**
77
+ * Format estimate for display
78
+ */
79
+ export function formatEstimate(estimate) {
80
+ const lines = [
81
+ `๐Ÿ“Š Token Estimate:`,
82
+ ` Input: ~${(estimate.inputTokens / 1000).toFixed(1)}k tokens`,
83
+ ` Output: ~${(estimate.outputTokens / 1000).toFixed(1)}k tokens`,
84
+ ` Total: ~${(estimate.totalTokens / 1000).toFixed(1)}k tokens`,
85
+ ` Est. Cost: $${estimate.estimatedCost.toFixed(4)}`
86
+ ];
87
+ if (estimate.warning) {
88
+ lines.push(`\n ${estimate.warning}`);
89
+ }
90
+ return lines.join('\n');
91
+ }
92
+ //# sourceMappingURL=token-estimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../../src/utils/token-estimator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantaverse-ai-reviewer",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "AI-powered code review CLI - analyze your codebase with Gemini AI",
5
5
  "type": "module",
6
6
  "bin": {