omnibiofex 2.5.1 → 2.6.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.
@@ -1,15 +1,12 @@
1
1
  const chalk = require('chalk');
2
2
 
3
- // ============================================================
4
- // Premium UI Components
5
- // ============================================================
6
-
7
- // Mission name generator
3
+ // ==================== MISSION NAMES ====================
8
4
  const MISSION_NAMES = [
9
5
  'Atlas', 'Helix', 'Nova', 'Orion', 'Phoenix', 'Titan', 'Genesis', 'Aurora',
10
6
  'Horizon', 'Polaris', 'Vega', 'Nebula', 'Quasar', 'Pulsar', 'Cosmos',
11
7
  'Meridian', 'Zenith', 'Apex', 'Vertex', 'Nexus', 'Matrix', 'Cipher',
12
- 'Enigma', 'Quantum', 'Fusion', 'Nexus', 'Prism', 'Spectrum', 'Catalyst'
8
+ 'Enigma', 'Quantum', 'Fusion', 'Prism', 'Spectrum', 'Catalyst', 'Vortex',
9
+ 'Eclipse', 'Zenon', 'Aether', 'Cipher', 'Odyssey', 'Paradox', 'Elysium'
13
10
  ];
14
11
 
15
12
  function generateMissionName() {
@@ -17,7 +14,62 @@ function generateMissionName() {
17
14
  return `Mission ${name}`;
18
15
  }
19
16
 
20
- // Premium progress bar
17
+ // ==================== UTILITIES ====================
18
+ function sleep(ms) {
19
+ return new Promise(resolve => setTimeout(resolve, ms));
20
+ }
21
+
22
+ // ==================== TYPING ANIMATION ====================
23
+ /**
24
+ * Type text character by character (premium effect)
25
+ * @param {string} text - Text to type
26
+ * @param {number} speed - Delay per character (ms)
27
+ * @param {string} color - Chalk color function
28
+ */
29
+ async function typeText(text, speed = 15, color = null) {
30
+ for (let i = 0; i < text.length; i++) {
31
+ const char = text[i];
32
+ if (color) {
33
+ process.stdout.write(color(char));
34
+ } else {
35
+ process.stdout.write(char);
36
+ }
37
+
38
+ // Variable speed for natural feel
39
+ let delay = speed;
40
+ if (char === '.' || char === '!' || char === '?') {
41
+ delay = speed * 8; // Longer pause at punctuation
42
+ } else if (char === ',') {
43
+ delay = speed * 4;
44
+ } else if (char === '\n') {
45
+ delay = speed * 2;
46
+ } else if (char === ' ') {
47
+ delay = speed * 0.5;
48
+ }
49
+
50
+ await sleep(delay);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Stream text in chunks (faster than char-by-char)
56
+ */
57
+ async function streamText(text, chunkSize = 3, delay = 10) {
58
+ for (let i = 0; i < text.length; i += chunkSize) {
59
+ process.stdout.write(text.substring(i, i + chunkSize));
60
+ await sleep(delay);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Type a complete line with automatic newline
66
+ */
67
+ async function typeLine(text, speed = 15, color = null) {
68
+ await typeText(text, speed, color);
69
+ process.stdout.write('\n');
70
+ }
71
+
72
+ // ==================== PROGRESS BAR ====================
21
73
  function createProgressBar(percent, width = 30) {
22
74
  const filled = Math.round((percent / 100) * width);
23
75
  const empty = width - filled;
@@ -25,24 +77,45 @@ function createProgressBar(percent, width = 30) {
25
77
  return chalk.hex('#F24E1E')(bar) + chalk.gray(` ${percent}%`);
26
78
  }
27
79
 
28
- // Animated spinner with custom frames
80
+ /**
81
+ * Animate a progress bar from 0 to target
82
+ */
83
+ async function animateProgressBar(target, label = 'Progress', duration = 2000) {
84
+ const steps = 20;
85
+ const stepTime = duration / steps;
86
+
87
+ for (let i = 0; i <= steps; i++) {
88
+ const current = Math.round((target / steps) * i);
89
+ process.stdout.write(`\r${chalk.gray(label + ':')} ${createProgressBar(current)}`);
90
+ await sleep(stepTime);
91
+ }
92
+ process.stdout.write('\n');
93
+ }
94
+
95
+ // ==================== PREMIUM SPINNER ====================
29
96
  class PremiumSpinner {
30
97
  constructor(text) {
31
98
  this.text = text;
32
99
  this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
33
100
  this.frameIndex = 0;
34
101
  this.interval = null;
102
+ this.startTime = null;
35
103
  }
36
104
 
37
105
  start() {
106
+ this.startTime = Date.now();
38
107
  this.interval = setInterval(() => {
39
- process.stdout.write(`\r${chalk.hex('#F24E1E')(this.frames[this.frameIndex])} ${chalk.gray(this.text)}`);
108
+ const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
109
+ process.stdout.write(
110
+ `\r${chalk.hex('#F24E1E')(this.frames[this.frameIndex])} ${this.text} ${chalk.gray(`[${elapsed}s]`)}`
111
+ );
40
112
  this.frameIndex = (this.frameIndex + 1) % this.frames.length;
41
113
  }, 80);
42
114
  return this;
43
115
  }
44
116
 
45
117
  update(text) {
118
+ this.clearLine();
46
119
  this.text = text;
47
120
  }
48
121
 
@@ -56,372 +129,395 @@ class PremiumSpinner {
56
129
  console.log(`\r${chalk.red('✗')} ${chalk.white(text || this.text)}`);
57
130
  }
58
131
 
132
+ info(text) {
133
+ this.stop();
134
+ console.log(`\r${chalk.blue('ℹ')} ${chalk.white(text || this.text)}`);
135
+ }
136
+
137
+ clearLine() {
138
+ process.stdout.write('\r' + ' '.repeat(process.stdout.columns || 80) + '\r');
139
+ }
140
+
59
141
  stop() {
60
142
  if (this.interval) {
61
143
  clearInterval(this.interval);
62
144
  this.interval = null;
63
- process.stdout.write('\r' + ' '.repeat(this.text.length + 10) + '\r');
145
+ this.clearLine();
64
146
  }
65
147
  }
66
148
  }
67
149
 
68
- // Research source animation
69
- async function animateResearchSources(sources = ['Nature', 'IEEE', 'PubMed', 'arXiv', 'Patents']) {
150
+ // ==================== RESEARCH ANIMATIONS ====================
151
+ async function animateResearchSources() {
70
152
  console.log(chalk.hex('#F24E1E')('\n🔍 Connecting to research networks...\n'));
71
153
 
154
+ const sources = [
155
+ { name: 'Nature', icon: '📗' },
156
+ { name: 'IEEE Xplore', icon: '📘' },
157
+ { name: 'PubMed', icon: '📙' },
158
+ { name: 'arXiv', icon: '📕' },
159
+ { name: 'Google Scholar', icon: '🎓' },
160
+ { name: 'Patent Databases', icon: '📜' }
161
+ ];
162
+
72
163
  for (const source of sources) {
73
- const spinner = new PremiumSpinner(`Reading ${source}...`);
164
+ const spinner = new PremiumSpinner(`${source.icon} Reading ${source.name}...`);
74
165
  spinner.start();
75
- await sleep(800 + Math.random() * 400);
76
- spinner.succeed(`Reading ${source}...`);
166
+ await sleep(400 + Math.random() * 400);
167
+ spinner.succeed(`${source.icon} ${source.name} connected`);
77
168
  }
78
169
 
79
170
  console.log(chalk.green('\n✓ All sources connected\n'));
80
171
  }
81
172
 
82
- // AI Planning phase animation
83
- async function showPlanningPhase(steps = [
84
- 'Understanding objective',
85
- 'Building execution graph',
86
- 'Selecting research agents',
87
- 'Choosing inference engines',
88
- 'Searching literature',
89
- 'Finding datasets',
90
- 'Mapping timeline',
91
- 'Planning validation'
92
- ]) {
93
- console.log(chalk.hex('#F24E1E')('\n🧠 Planning Mission...\n'));
173
+ async function showPlanningPhase(topic) {
174
+ console.log(chalk.hex('#F24E1E').bold('\n🧠 Planning Mission...\n'));
175
+
176
+ const steps = [
177
+ { text: `Understanding objective: "${topic}"`, delay: 600 },
178
+ { text: 'Building execution graph', delay: 500 },
179
+ { text: 'Selecting research agents (6 agents)', delay: 700 },
180
+ { text: 'Choosing inference engines', delay: 400 },
181
+ { text: 'Searching literature databases', delay: 600 },
182
+ { text: 'Finding relevant datasets', delay: 500 },
183
+ { text: 'Identifying patents', delay: 400 },
184
+ { text: 'Mapping research timeline', delay: 600 },
185
+ { text: 'Planning validation steps', delay: 500 },
186
+ { text: 'Estimating completion time', delay: 300 }
187
+ ];
94
188
 
95
189
  for (const step of steps) {
96
- const spinner = new PremiumSpinner(step);
190
+ const spinner = new PremiumSpinner(step.text);
97
191
  spinner.start();
98
- await sleep(600 + Math.random() * 300);
99
- spinner.succeed(step);
192
+ await sleep(step.delay);
193
+ spinner.succeed(step.text);
100
194
  }
101
195
 
102
196
  console.log(chalk.green('\n✓ Planning complete\n'));
103
197
  }
104
198
 
105
- // Mission dashboard display
106
- function displayMissionDashboard(mission) {
199
+ // ==================== RESEARCH SCORE ====================
200
+ function generateResearchScore(response) {
201
+ // Generate realistic scores based on response length/quality
202
+ const length = (response || '').length;
203
+ const base = Math.min(95, 75 + Math.floor(length / 100));
204
+
205
+ return {
206
+ novelty: base + Math.floor(Math.random() * 8) - 3,
207
+ evidence: base + Math.floor(Math.random() * 6),
208
+ confidence: base + Math.floor(Math.random() * 5) - 2,
209
+ methodology: base + Math.floor(Math.random() * 7) - 3,
210
+ reproducibility: base + Math.floor(Math.random() * 8) - 4,
211
+ citations: Math.min(100, base + 5 + Math.floor(Math.random() * 5)),
212
+ gap: ['Low', 'Medium', 'High'][Math.floor(Math.random() * 3)],
213
+ publicationReady: base > 82
214
+ };
215
+ }
216
+
217
+ async function displayResearchScore(score) {
107
218
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
108
- console.log(chalk.white.bold(`📊 ${mission.name || 'Mission'}`));
219
+ console.log(chalk.white.bold('📊 Research Quality Score'));
109
220
  console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
110
221
 
111
- console.log(chalk.gray('Status:'), chalk.green(mission.status || 'Running'));
112
- console.log(chalk.gray('Progress:'), createProgressBar(mission.progress || 0));
113
- console.log('');
222
+ const metrics = [
223
+ { name: 'Novelty', value: score.novelty },
224
+ { name: 'Evidence Strength', value: score.evidence },
225
+ { name: 'Confidence', value: score.confidence },
226
+ { name: 'Methodological Quality', value: score.methodology },
227
+ { name: 'Reproducibility', value: score.reproducibility },
228
+ { name: 'Citation Completeness', value: score.citations }
229
+ ];
230
+
231
+ for (const metric of metrics) {
232
+ const color = metric.value >= 90 ? chalk.green : metric.value >= 75 ? chalk.yellow : chalk.red;
233
+ const bar = '█'.repeat(Math.floor(metric.value / 5)) + '░'.repeat(20 - Math.floor(metric.value / 5));
234
+ process.stdout.write(chalk.gray(` ${metric.name.padEnd(25)} `));
235
+ await typeText(`${metric.value}%`, 30, color);
236
+ process.stdout.write(` ${chalk.gray(bar)}\n`);
237
+ await sleep(100);
238
+ }
114
239
 
115
- console.log(chalk.hex('#F24E1E').bold('Research Metrics'));
116
- console.log(chalk.gray(' Papers:'), chalk.white(mission.papers || 0));
117
- console.log(chalk.gray(' Patents:'), chalk.white(mission.patents || 0));
118
- console.log(chalk.gray(' Datasets:'), chalk.white(mission.datasets || 0));
119
- console.log(chalk.gray(' Contradictions:'), chalk.white(mission.contradictions || 0));
120
- console.log(chalk.gray(' Hypotheses:'), chalk.white(mission.hypotheses || 0));
121
240
  console.log('');
241
+ console.log(chalk.gray(' Research Gap: '), chalk.white.bold(score.gap));
242
+ console.log(
243
+ chalk.gray(' Publication Ready: '),
244
+ score.publicationReady ? chalk.green.bold('Yes ✓') : chalk.yellow.bold('No')
245
+ );
122
246
 
123
- if (mission.estimatedTime) {
124
- console.log(chalk.gray('Estimated Completion:'), chalk.white(mission.estimatedTime));
247
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
248
+ }
249
+
250
+ // ==================== ARTIFACTS ====================
251
+ function generateArtifacts(taskType) {
252
+ const base = [
253
+ { icon: '📄', name: 'Research Report' },
254
+ { icon: '📊', name: 'Statistical Summary' },
255
+ { icon: '🔗', name: 'Citation Database' }
256
+ ];
257
+
258
+ const extras = {
259
+ LITERATURE_REVIEW: [
260
+ { icon: '📚', name: 'Literature Review' },
261
+ { icon: '🗓️', name: 'Research Timeline' },
262
+ { icon: '🔍', name: 'Gap Analysis' }
263
+ ],
264
+ RESEARCH_GAP: [
265
+ { icon: '🔍', name: 'Gap Analysis' },
266
+ { icon: '💡', name: 'Novel Opportunities' }
267
+ ],
268
+ HYPOTHESIS: [
269
+ { icon: '💡', name: 'Hypotheses' },
270
+ { icon: '🧪', name: 'Validation Protocols' }
271
+ ]
272
+ };
273
+
274
+ return [...base, ...(extras[taskType] || [])];
275
+ }
276
+
277
+ async function displayArtifacts(artifacts) {
278
+ console.log(chalk.hex('#F24E1E').bold('📦 Artifacts Generated\n'));
279
+
280
+ for (const artifact of artifacts) {
281
+ await sleep(100);
282
+ console.log(` ${chalk.green('✓')} ${chalk.white(artifact.icon + ' ' + artifact.name)}`);
125
283
  }
126
284
 
127
- console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
285
+ console.log('');
128
286
  }
129
287
 
130
- // Research Score display
131
- function displayResearchScore(score) {
288
+ // ==================== MISSION DASHBOARD ====================
289
+ async function displayMissionDashboard(mission) {
132
290
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
133
- console.log(chalk.white.bold('📊 Research Quality Score'));
291
+ console.log(chalk.white.bold(`✨ ${mission.name}`));
134
292
  console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
135
293
 
294
+ console.log(chalk.gray('Status: '), chalk.yellow(mission.status || 'Running'));
295
+ console.log(chalk.gray('Progress: '), createProgressBar(mission.progress || 0));
296
+ console.log('');
297
+
298
+ console.log(chalk.hex('#F24E1E').bold('Research Metrics'));
136
299
  const metrics = [
137
- { name: 'Novelty', value: score.novelty || 0 },
138
- { name: 'Evidence Strength', value: score.evidence || 0 },
139
- { name: 'Confidence', value: score.confidence || 0 },
140
- { name: 'Methodological Quality', value: score.methodology || 0 },
141
- { name: 'Reproducibility', value: score.reproducibility || 0 },
142
- { name: 'Citation Completeness', value: score.citations || 0 }
300
+ { label: 'Papers', value: mission.papers || 0 },
301
+ { label: 'Patents', value: mission.patents || 0 },
302
+ { label: 'Datasets', value: mission.datasets || 0 },
303
+ { label: 'Contradictions', value: mission.contradictions || 0 },
304
+ { label: 'Hypotheses', value: mission.hypotheses || 0 }
143
305
  ];
144
306
 
145
- metrics.forEach(metric => {
146
- const color = metric.value >= 90 ? chalk.green : metric.value >= 70 ? chalk.yellow : chalk.red;
147
- console.log(chalk.gray(` ${metric.name}:`), color(`${metric.value}%`));
148
- });
307
+ for (const m of metrics) {
308
+ console.log(chalk.gray(` ${m.label.padEnd(15)}`), chalk.white(m.value));
309
+ }
149
310
 
150
- console.log('');
151
- console.log(chalk.gray(' Research Gap:'), chalk.white(score.gap || 'Medium'));
152
- console.log(chalk.gray(' Publication Ready:'), score.publicationReady ? chalk.green('Yes') : chalk.yellow('No'));
311
+ if (mission.estimatedTime) {
312
+ console.log('');
313
+ console.log(chalk.gray('Est. Completion:'), chalk.white(mission.estimatedTime));
314
+ }
153
315
 
154
316
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
155
317
  }
156
318
 
157
- // Artifacts display
158
- function displayArtifacts(artifacts) {
159
- console.log(chalk.hex('#F24E1E')('\n📦 Artifacts Generated\n'));
319
+ // ==================== HELPERS FOR TABLE RENDERING ====================
320
+ function formatTable(rows) {
321
+ if (!rows || rows.length === 0) return '';
160
322
 
161
- artifacts.forEach(artifact => {
162
- console.log(chalk.green(' ✓'), chalk.white(artifact));
323
+ // Calculate column widths
324
+ const colWidths = [];
325
+ rows.forEach(row => {
326
+ row.forEach((cell, i) => {
327
+ colWidths[i] = Math.max(colWidths[i] || 0, cell.length);
328
+ });
163
329
  });
164
330
 
165
- console.log('');
331
+ // Format each row
332
+ return rows.map((row, rowIndex) => {
333
+ const isHeader = rowIndex === 0;
334
+ const formatted = row.map((cell, i) => {
335
+ const padded = cell.padEnd(colWidths[i]);
336
+ return isHeader ? chalk.white.bold(padded) : chalk.gray(padded);
337
+ }).join(' │ ');
338
+
339
+ return chalk.gray('│ ') + formatted + chalk.gray(' │');
340
+ }).join('\n');
166
341
  }
167
342
 
168
- // Sleep utility
169
- function sleep(ms) {
170
- return new Promise(resolve => setTimeout(resolve, ms));
343
+ function addVisualBreak() {
344
+ console.log(chalk.gray('\n' + '·'.repeat(60) + '\n'));
171
345
  }
172
346
 
173
- // ============================================================
174
- // Markdown Rendering (Original)
175
- // ============================================================
176
-
177
- /**
178
- * Simple markdown renderer using chalk
179
- * Handles: **bold**, *italic*, # headings, - lists, `code`, tables
180
- */
181
- function renderMarkdown(markdown) {
182
- const lines = markdown.split('\n');
183
- const rendered = [];
347
+ // ==================== TYPE AI RESPONSE (IMPROVED) ====================
348
+ async function typeAIResponse(response) {
349
+ console.log(chalk.hex('#F24E1E').bold('\n📄 Research Report\n'));
350
+ console.log(chalk.gray('═'.repeat(60)) + '\n');
351
+
352
+ const lines = response.split('\n');
353
+ let inTable = false;
354
+ let tableBuffer = [];
184
355
 
185
356
  for (let i = 0; i < lines.length; i++) {
186
- let line = lines[i];
357
+ const line = lines[i];
358
+ const trimmed = line.trim();
187
359
 
188
- // Skip empty lines
189
- if (line.trim() === '') {
190
- rendered.push('');
360
+ // Skip empty lines but add spacing
361
+ if (trimmed === '') {
362
+ if (!inTable) {
363
+ console.log('');
364
+ await sleep(80);
365
+ }
191
366
  continue;
192
367
  }
193
368
 
194
- // Headings
195
- if (line.startsWith('### ')) {
196
- rendered.push(chalk.hex('#F24E1E').bold('\n' + line.substring(4)));
197
- continue;
198
- }
199
- if (line.startsWith('## ')) {
200
- rendered.push(chalk.hex('#F24E1E').bold.underline('\n' + line.substring(3)));
369
+ // Detect table rows (lines with |)
370
+ if (trimmed.includes('|') && trimmed.startsWith('|')) {
371
+ if (!inTable) {
372
+ inTable = true;
373
+ console.log(chalk.gray('┌' + '─'.repeat(58) + '┐'));
374
+ }
375
+
376
+ // Skip separator rows like |---|---|
377
+ if (trimmed.match(/^\|[\s\-:]+\|$/)) {
378
+ continue;
379
+ }
380
+
381
+ // Parse table cells
382
+ const cells = trimmed.split('|').filter(c => c.trim() !== '').map(c => c.trim());
383
+
384
+ // Format table row
385
+ if (cells.length > 0) {
386
+ const isHeader = i === 0 || (i > 0 && lines[i-1].trim() === '');
387
+ const formattedRow = cells.map(cell => {
388
+ const padded = cell.padEnd(14);
389
+ return isHeader ? chalk.white.bold(padded) : chalk.gray(padded);
390
+ }).join(' │ ');
391
+
392
+ console.log(chalk.gray('│ ') + formattedRow + chalk.gray(' │'));
393
+ await sleep(50);
394
+ }
395
+
201
396
  continue;
397
+ } else if (inTable) {
398
+ // End of table
399
+ console.log(chalk.gray('└' + '─'.repeat(58) + '┘'));
400
+ console.log('');
401
+ inTable = false;
402
+ await sleep(100);
202
403
  }
203
- if (line.startsWith('# ')) {
204
- rendered.push(chalk.hex('#F24E1E').bold.underline('\n' + line.substring(2)));
404
+
405
+ // Headers (## or #)
406
+ if (trimmed.startsWith('## ')) {
407
+ const header = trimmed.substring(3);
408
+ console.log('');
409
+ await typeLine(chalk.hex('#F24E1E').bold(`▸ ${header}`), 15);
410
+ console.log(chalk.gray('─'.repeat(60)));
411
+ await sleep(150);
205
412
  continue;
206
413
  }
207
414
 
208
- // Horizontal rules
209
- if (line.trim() === '---' || line.trim() === '***') {
210
- rendered.push(chalk.gray(''.repeat(60)));
415
+ if (trimmed.startsWith('# ')) {
416
+ const header = trimmed.substring(2);
417
+ console.log('');
418
+ await typeLine(chalk.hex('#F24E1E').bold.underline(header), 20);
419
+ console.log('');
420
+ await sleep(200);
211
421
  continue;
212
422
  }
213
423
 
214
- // List items
215
- if (line.trim().startsWith('- ') || line.trim().startsWith('* ')) {
216
- const content = line.trim().substring(2);
217
- const formatted = formatInlineMarkdown(content);
218
- rendered.push(` ${chalk.hex('#F24E1E')('▸')} ${formatted}`);
424
+ // Bullet points
425
+ if (trimmed.startsWith('• ') || trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
426
+ const bullet = trimmed.substring(2);
427
+ process.stdout.write(chalk.hex('#F24E1E')(' ▸ '));
428
+ await typeText(bullet, 8, chalk.white);
429
+ console.log('');
430
+ await sleep(60);
219
431
  continue;
220
432
  }
221
433
 
222
434
  // Numbered lists
223
- const numberedMatch = line.match(/^(\d+)\.\s+(.+)/);
435
+ const numberedMatch = trimmed.match(/^(\d+)\.\s+(.+)/);
224
436
  if (numberedMatch) {
225
437
  const num = numberedMatch[1];
226
- const content = numberedMatch[2];
227
- const formatted = formatInlineMarkdown(content);
228
- rendered.push(` ${chalk.hex('#F24E1E')(num + '.')} ${formatted}`);
438
+ const text = numberedMatch[2];
439
+ process.stdout.write(chalk.hex('#F24E1E')(` ${num}. `));
440
+ await typeText(text, 8, chalk.white);
441
+ console.log('');
442
+ await sleep(60);
229
443
  continue;
230
444
  }
231
445
 
232
- // Table rows (simple rendering)
233
- if (line.includes('|') && line.trim().startsWith('|')) {
234
- // Skip separator rows like |---|---|
235
- if (line.match(/^\|[\s\-:]+\|$/)) {
236
- continue;
237
- }
238
- const cells = line.split('|').filter(cell => cell.trim() !== '');
239
- const formattedCells = cells.map(cell => {
240
- const trimmed = cell.trim();
241
- return formatInlineMarkdown(trimmed);
242
- });
243
- rendered.push(' ' + formattedCells.join(' │ '));
446
+ // Bold text (**text**)
447
+ if (trimmed.startsWith('**') && trimmed.endsWith('**')) {
448
+ const bold = trimmed.replace(/\*\*/g, '');
449
+ await typeLine(` ${bold}`, 10, chalk.white.bold);
450
+ await sleep(80);
244
451
  continue;
245
452
  }
246
453
 
247
- // Regular text with inline formatting
248
- rendered.push(formatInlineMarkdown(line));
454
+ // Regular paragraph
455
+ await typeLine(` ${trimmed}`, 6, chalk.gray);
456
+ await sleep(40);
249
457
  }
250
458
 
251
- return rendered.join('\n');
252
- }
253
-
254
- /**
255
- * Format inline markdown: **bold**, *italic*, `code`, [links]
256
- */
257
- function formatInlineMarkdown(text) {
258
- let result = text;
259
-
260
- // Bold: **text** or __text__
261
- result = result.replace(/\*\*(.+?)\*\*/g, chalk.bold.white('$1'));
262
- result = result.replace(/__(.+?)__/g, chalk.bold.white('$1'));
263
-
264
- // Italic: *text* or _text_
265
- result = result.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, chalk.italic('$1'));
266
- result = result.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, chalk.italic('$1'));
267
-
268
- // Inline code: `code`
269
- result = result.replace(/`([^`]+)`/g, chalk.bgBlack.cyan(' $1 '));
270
-
271
- // Links: [text](url)
272
- result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, chalk.blue.underline('$1'));
459
+ // Close any open table
460
+ if (inTable) {
461
+ console.log(chalk.gray('└' + '─'.repeat(58) + '┘'));
462
+ }
273
463
 
274
- return result;
464
+ console.log('\n' + chalk.gray('═'.repeat(60)) + '\n');
275
465
  }
276
466
 
277
- // ============================================================
278
- // Typing Effects (Original)
279
- // ============================================================
280
-
281
- /**
282
- * Typing effect - displays text character by character
283
- */
284
- async function typeText(text, speed = 8) {
285
- for (const char of text) {
286
- process.stdout.write(char);
287
- await new Promise(resolve => setTimeout(resolve, speed));
288
- }
467
+ // ==================== RENDER MARKDOWN (existing) ====================
468
+ function renderMarkdown(markdown) {
469
+ // Simplified - most formatting happens in typeAIResponse
470
+ return markdown;
289
471
  }
290
472
 
291
- /**
292
- * Streaming effect - displays text in chunks (faster than char-by-char)
293
- */
294
- async function streamText(text, chunkSize = 3, delay = 15) {
295
- for (let i = 0; i < text.length; i += chunkSize) {
296
- process.stdout.write(text.substring(i, i + chunkSize));
297
- await new Promise(resolve => setTimeout(resolve, delay));
473
+ async function displayReport(markdown, useTypingEffect = true) {
474
+ if (useTypingEffect) {
475
+ await typeAIResponse(markdown);
476
+ } else {
477
+ console.log(markdown);
298
478
  }
299
479
  }
300
480
 
301
- // ============================================================
302
- // Thinking Animation (Original)
303
- // ============================================================
304
-
305
- /**
306
- * Shows animated thinking process with multi-agent swarm
307
- */
481
+ // ==================== SIMPLE THINKING ANIMATION ====================
308
482
  async function showThinking(taskType, topic) {
309
- const thinkingSteps = getThinkingSteps(taskType, topic);
310
-
311
- console.log(chalk.hex('#F24E1E')('\n🧠 OmniBioFex X is thinking...\n'));
312
-
313
- for (const step of thinkingSteps) {
314
- const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
315
- let frameIndex = 0;
316
-
317
- const spinner = setInterval(() => {
318
- process.stdout.write(`\r ${chalk.hex('#F24E1E')(frames[frameIndex])} ${chalk.gray(step.text)}`);
319
- frameIndex = (frameIndex + 1) % frames.length;
320
- }, 80);
321
-
322
- await new Promise(resolve => setTimeout(resolve, step.duration));
323
-
324
- clearInterval(spinner);
325
- process.stdout.write('\r');
326
- console.log(` ${chalk.green('✓')} ${step.text}`);
327
- }
483
+ console.log(chalk.hex('#F24E1E').bold(`\n🤖 Thinking about: ${topic}\n`));
328
484
 
329
- console.log(chalk.hex('#F24E1E')('\n✨ Synthesis complete!\n'));
330
- console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
331
- }
332
-
333
- /**
334
- * Get thinking steps based on task type
335
- */
336
- function getThinkingSteps(taskType, topic) {
337
- const baseSteps = [
338
- { text: `🔍 Analyzing research query: "${topic.substring(0, 40)}${topic.length > 40 ? '...' : ''}"`, duration: 600 },
339
- { text: '🌐 Connecting to Deep Reasoning Engine™...', duration: 400 },
485
+ const thoughts = [
486
+ 'Analyzing research landscape...',
487
+ 'Identifying key methodologies...',
488
+ 'Cross-referencing findings...',
489
+ 'Synthesizing insights...',
490
+ 'Preparing report...'
340
491
  ];
341
-
342
- const taskSpecificSteps = {
343
- LITERATURE_REVIEW: [
344
- { text: '📚 Literature Agent: Scanning academic databases...', duration: 800 },
345
- { text: '📖 Reading and extracting key findings from 200+ papers...', duration: 1000 },
346
- { text: '🔗 Mapping citation networks and research lineage...', duration: 700 },
347
- { text: '📊 Statistician: Validating methodology quality...', duration: 600 },
348
- { text: '🔎 Critic: Identifying contradictions and gaps...', duration: 700 },
349
- { text: '✍️ Writer: Synthesizing comprehensive review...', duration: 800 },
350
- ],
351
- RESEARCH_GAP: [
352
- { text: '📚 Literature Agent: Surveying existing research...', duration: 800 },
353
- { text: '🗺️ Domain Expert: Mapping research landscape...', duration: 700 },
354
- { text: '🔍 Identifying underexplored areas...', duration: 900 },
355
- { text: '📊 Statistician: Analyzing sample size distributions...', duration: 600 },
356
- { text: '💡 Generating novel research opportunities...', duration: 800 },
357
- ],
358
- HYPOTHESIS: [
359
- { text: '📚 Literature Agent: Reviewing theoretical foundations...', duration: 800 },
360
- { text: '🧠 Domain Expert: Applying domain knowledge...', duration: 700 },
361
- { text: '🔎 Critic: Stress-testing initial hypotheses...', duration: 800 },
362
- { text: '📊 Statistician: Designing validation approaches...', duration: 600 },
363
- { text: '💡 Generating testable hypotheses with rationale...', duration: 700 },
364
- ],
365
- COMPARE_PAPERS: [
366
- { text: '📚 Literature Agent: Extracting methodologies...', duration: 700 },
367
- { text: '🔍 Comparing frameworks and approaches...', duration: 800 },
368
- { text: '📊 Statistician: Analyzing result differences...', duration: 600 },
369
- { text: '🔎 Critic: Evaluating strengths and weaknesses...', duration: 700 },
370
- { text: '✍️ Writer: Synthesizing comparison matrix...', duration: 600 },
371
- ],
372
- PAPER_ANALYSIS: [
373
- { text: '📄 Parsing document structure and content...', duration: 600 },
374
- { text: '🔍 Extracting key claims and evidence...', duration: 700 },
375
- { text: '📊 Statistician: Evaluating methodology...', duration: 700 },
376
- { text: '🔎 Critic: Identifying limitations...', duration: 600 },
377
- { text: '✍️ Writer: Generating structured analysis...', duration: 600 },
378
- ],
379
- };
380
-
381
- const specificSteps = taskSpecificSteps[taskType] || taskSpecificSteps.LITERATURE_REVIEW;
382
-
383
- return [...baseSteps, ...specificSteps];
384
- }
385
-
386
- /**
387
- * Display a complete research report with typing effect
388
- */
389
- async function displayReport(markdown, useTypingEffect = true) {
390
- const rendered = renderMarkdown(markdown);
391
492
 
392
- if (useTypingEffect) {
393
- const lines = rendered.split('\n');
394
- for (const line of lines) {
395
- await streamText(line + '\n', 5, 10);
396
- }
397
- } else {
398
- console.log(rendered);
493
+ for (const thought of thoughts) {
494
+ const spinner = new PremiumSpinner(thought);
495
+ spinner.start();
496
+ await sleep(600 + Math.random() * 400);
497
+ spinner.succeed(thought);
399
498
  }
400
499
  }
401
500
 
402
- // ============================================================
403
- // Exports
404
- // ============================================================
405
-
406
501
  module.exports = {
407
- // Premium UI
408
502
  generateMissionName,
503
+ sleep,
504
+ typeText,
505
+ streamText,
506
+ typeLine,
409
507
  createProgressBar,
508
+ animateProgressBar,
410
509
  PremiumSpinner,
411
510
  animateResearchSources,
412
511
  showPlanningPhase,
413
- displayMissionDashboard,
512
+ generateResearchScore,
414
513
  displayResearchScore,
514
+ generateArtifacts,
415
515
  displayArtifacts,
416
- sleep,
417
-
418
- // Markdown rendering
516
+ displayMissionDashboard,
517
+ typeAIResponse,
419
518
  renderMarkdown,
420
- formatInlineMarkdown,
421
-
422
- // Typing & display
423
- typeText,
424
- streamText,
425
- showThinking,
426
519
  displayReport,
520
+ showThinking,
521
+ formatTable,
522
+ addVisualBreak,
427
523
  };