omnibiofex 2.6.0 → 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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/utils/display.js +138 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnibiofex",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "OmniBioFex X - The Autonomous Research Terminal for AI-powered research missions",
5
5
  "main": "bin/obx",
6
6
  "bin": {
@@ -316,39 +316,152 @@ async function displayMissionDashboard(mission) {
316
316
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
317
317
  }
318
318
 
319
- // ==================== TYPE AI RESPONSE ====================
320
- /**
321
- * Stream the AI response with typing effect
322
- */
319
+ // ==================== HELPERS FOR TABLE RENDERING ====================
320
+ function formatTable(rows) {
321
+ if (!rows || rows.length === 0) return '';
322
+
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
+ });
329
+ });
330
+
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');
341
+ }
342
+
343
+ function addVisualBreak() {
344
+ console.log(chalk.gray('\n' + '·'.repeat(60) + '\n'));
345
+ }
346
+
347
+ // ==================== TYPE AI RESPONSE (IMPROVED) ====================
323
348
  async function typeAIResponse(response) {
324
349
  console.log(chalk.hex('#F24E1E').bold('\n📄 Research Report\n'));
325
- console.log(chalk.gray(''.repeat(60)));
350
+ console.log(chalk.gray(''.repeat(60)) + '\n');
326
351
 
327
- // Stream in chunks for natural feel (faster than char-by-char for long reports)
328
352
  const lines = response.split('\n');
353
+ let inTable = false;
354
+ let tableBuffer = [];
329
355
 
330
- for (const line of lines) {
331
- if (line.trim().startsWith('#')) {
332
- // Headers - type slower and in orange
333
- await typeLine(line, 20, chalk.hex('#F24E1E').bold);
334
- } else if (line.trim().startsWith('- ') || line.trim().startsWith('* ')) {
335
- // List items - normal speed
336
- await typeLine(line, 8, chalk.white);
337
- } else if (line.trim().startsWith('**') && line.trim().endsWith('**')) {
338
- // Bold text
339
- const clean = line.replace(/\*\*/g, '');
340
- await typeLine(clean, 10, chalk.white.bold);
341
- } else if (line.trim() === '') {
356
+ for (let i = 0; i < lines.length; i++) {
357
+ const line = lines[i];
358
+ const trimmed = line.trim();
359
+
360
+ // Skip empty lines but add spacing
361
+ if (trimmed === '') {
362
+ if (!inTable) {
363
+ console.log('');
364
+ await sleep(80);
365
+ }
366
+ continue;
367
+ }
368
+
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
+
396
+ continue;
397
+ } else if (inTable) {
398
+ // End of table
399
+ console.log(chalk.gray('└' + '─'.repeat(58) + '┘'));
342
400
  console.log('');
343
- await sleep(50);
344
- } else {
345
- // Regular text - fast stream
346
- await streamText(line, 4, 5);
401
+ inTable = false;
402
+ await sleep(100);
403
+ }
404
+
405
+ // Headers (## or #)
406
+ if (trimmed.startsWith('## ')) {
407
+ const header = trimmed.substring(3);
347
408
  console.log('');
409
+ await typeLine(chalk.hex('#F24E1E').bold(`▸ ${header}`), 15);
410
+ console.log(chalk.gray('─'.repeat(60)));
411
+ await sleep(150);
412
+ continue;
348
413
  }
414
+
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);
421
+ continue;
422
+ }
423
+
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);
431
+ continue;
432
+ }
433
+
434
+ // Numbered lists
435
+ const numberedMatch = trimmed.match(/^(\d+)\.\s+(.+)/);
436
+ if (numberedMatch) {
437
+ const num = numberedMatch[1];
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);
443
+ continue;
444
+ }
445
+
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);
451
+ continue;
452
+ }
453
+
454
+ // Regular paragraph
455
+ await typeLine(` ${trimmed}`, 6, chalk.gray);
456
+ await sleep(40);
457
+ }
458
+
459
+ // Close any open table
460
+ if (inTable) {
461
+ console.log(chalk.gray('└' + '─'.repeat(58) + '┘'));
349
462
  }
350
463
 
351
- console.log(chalk.gray(''.repeat(60)) + '\n');
464
+ console.log('\n' + chalk.gray(''.repeat(60)) + '\n');
352
465
  }
353
466
 
354
467
  // ==================== RENDER MARKDOWN (existing) ====================
@@ -405,4 +518,6 @@ module.exports = {
405
518
  renderMarkdown,
406
519
  displayReport,
407
520
  showThinking,
521
+ formatTable,
522
+ addVisualBreak,
408
523
  };