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.
- package/package.json +1 -1
- package/src/commands/mission.js +47 -36
- package/src/commands/research.js +174 -235
- package/src/utils/display.js +367 -271
package/src/utils/display.js
CHANGED
|
@@ -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', '
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
145
|
+
this.clearLine();
|
|
64
146
|
}
|
|
65
147
|
}
|
|
66
148
|
}
|
|
67
149
|
|
|
68
|
-
//
|
|
69
|
-
async function animateResearchSources(
|
|
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(
|
|
164
|
+
const spinner = new PremiumSpinner(`${source.icon} Reading ${source.name}...`);
|
|
74
165
|
spinner.start();
|
|
75
|
-
await sleep(
|
|
76
|
-
spinner.succeed(
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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(
|
|
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
|
-
//
|
|
106
|
-
function
|
|
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(
|
|
219
|
+
console.log(chalk.white.bold('📊 Research Quality Score'));
|
|
109
220
|
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
110
221
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
124
|
-
|
|
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(
|
|
285
|
+
console.log('');
|
|
128
286
|
}
|
|
129
287
|
|
|
130
|
-
//
|
|
131
|
-
function
|
|
288
|
+
// ==================== MISSION DASHBOARD ====================
|
|
289
|
+
async function displayMissionDashboard(mission) {
|
|
132
290
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
133
|
-
console.log(chalk.white.bold(
|
|
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
|
-
{
|
|
138
|
-
{
|
|
139
|
-
{
|
|
140
|
-
{
|
|
141
|
-
{
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
307
|
+
for (const m of metrics) {
|
|
308
|
+
console.log(chalk.gray(` ${m.label.padEnd(15)}`), chalk.white(m.value));
|
|
309
|
+
}
|
|
149
310
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
//
|
|
158
|
-
function
|
|
159
|
-
|
|
319
|
+
// ==================== HELPERS FOR TABLE RENDERING ====================
|
|
320
|
+
function formatTable(rows) {
|
|
321
|
+
if (!rows || rows.length === 0) return '';
|
|
160
322
|
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
|
|
357
|
+
const line = lines[i];
|
|
358
|
+
const trimmed = line.trim();
|
|
187
359
|
|
|
188
|
-
// Skip empty lines
|
|
189
|
-
if (
|
|
190
|
-
|
|
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
|
-
//
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
204
|
-
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
//
|
|
215
|
-
if (
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
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 =
|
|
435
|
+
const numberedMatch = trimmed.match(/^(\d+)\.\s+(.+)/);
|
|
224
436
|
if (numberedMatch) {
|
|
225
437
|
const num = numberedMatch[1];
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
//
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
|
248
|
-
|
|
454
|
+
// Regular paragraph
|
|
455
|
+
await typeLine(` ${trimmed}`, 6, chalk.gray);
|
|
456
|
+
await sleep(40);
|
|
249
457
|
}
|
|
250
458
|
|
|
251
|
-
|
|
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
|
-
|
|
464
|
+
console.log('\n' + chalk.gray('═'.repeat(60)) + '\n');
|
|
275
465
|
}
|
|
276
466
|
|
|
277
|
-
//
|
|
278
|
-
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
-
|
|
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
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
-
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
512
|
+
generateResearchScore,
|
|
414
513
|
displayResearchScore,
|
|
514
|
+
generateArtifacts,
|
|
415
515
|
displayArtifacts,
|
|
416
|
-
|
|
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
|
};
|