omnibiofex 2.8.5 → 4.1.0
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/bin/obx +41 -154
- package/package.json +13 -28
- package/src/auth.js +181 -381
- package/src/commands/account.js +35 -88
- package/src/commands/data.js +40 -114
- package/src/commands/debug.js +28 -25
- package/src/commands/diagram.js +340 -0
- package/src/commands/earnings.js +31 -86
- package/src/commands/mission.js +194 -98
- package/src/commands/morning.js +39 -107
- package/src/commands/open.js +26 -36
- package/src/commands/publish.js +81 -126
- package/src/commands/research.js +148 -281
- package/src/commands/timeline.js +15 -54
- package/src/firebase.js +4 -14
- package/src/user.js +94 -0
- package/src/utils/display.js +27 -856
- package/src/api.js +0 -72
- package/src/config.js +0 -16
package/src/utils/display.js
CHANGED
|
@@ -1,110 +1,5 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
-
const figlet = require('figlet');
|
|
3
2
|
|
|
4
|
-
// Update the banner display
|
|
5
|
-
function displayBanner(version) {
|
|
6
|
-
console.log(
|
|
7
|
-
chalk.hex('#F24E1E')(
|
|
8
|
-
figlet.textSync('OmniBioFex X', { horizontalLayout: 'full' })
|
|
9
|
-
)
|
|
10
|
-
);
|
|
11
|
-
console.log(chalk.gray(`The Autonomous Research Operating System v${version}\n`));
|
|
12
|
-
console.log(chalk.hex('#F24E1E')('Create Research. Publish It. Earn From It.\n'));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// ==================== MISSION NAMES ====================
|
|
16
|
-
const MISSION_NAMES = [
|
|
17
|
-
'Atlas', 'Helix', 'Nova', 'Orion', 'Phoenix', 'Titan', 'Genesis', 'Aurora',
|
|
18
|
-
'Horizon', 'Polaris', 'Vega', 'Nebula', 'Quasar', 'Pulsar', 'Cosmos',
|
|
19
|
-
'Meridian', 'Zenith', 'Apex', 'Vertex', 'Nexus', 'Matrix', 'Cipher',
|
|
20
|
-
'Enigma', 'Quantum', 'Fusion', 'Prism', 'Spectrum', 'Catalyst', 'Vortex',
|
|
21
|
-
'Eclipse', 'Zenon', 'Aether', 'Cipher', 'Odyssey', 'Paradox', 'Elysium'
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
function generateMissionName() {
|
|
25
|
-
const name = MISSION_NAMES[Math.floor(Math.random() * MISSION_NAMES.length)];
|
|
26
|
-
return `Mission ${name}`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ==================== UTILITIES ====================
|
|
30
|
-
function sleep(ms) {
|
|
31
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ==================== TYPING ANIMATION ====================
|
|
35
|
-
/**
|
|
36
|
-
* Type text character by character (premium effect)
|
|
37
|
-
* @param {string} text - Text to type
|
|
38
|
-
* @param {number} speed - Delay per character (ms)
|
|
39
|
-
* @param {string} color - Chalk color function
|
|
40
|
-
*/
|
|
41
|
-
async function typeText(text, speed = 15, color = null) {
|
|
42
|
-
for (let i = 0; i < text.length; i++) {
|
|
43
|
-
const char = text[i];
|
|
44
|
-
if (color) {
|
|
45
|
-
process.stdout.write(color(char));
|
|
46
|
-
} else {
|
|
47
|
-
process.stdout.write(char);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Variable speed for natural feel
|
|
51
|
-
let delay = speed;
|
|
52
|
-
if (char === '.' || char === '!' || char === '?') {
|
|
53
|
-
delay = speed * 8; // Longer pause at punctuation
|
|
54
|
-
} else if (char === ',') {
|
|
55
|
-
delay = speed * 4;
|
|
56
|
-
} else if (char === '\n') {
|
|
57
|
-
delay = speed * 2;
|
|
58
|
-
} else if (char === ' ') {
|
|
59
|
-
delay = speed * 0.5;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
await sleep(delay);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Stream text in chunks (faster than char-by-char)
|
|
68
|
-
*/
|
|
69
|
-
async function streamText(text, chunkSize = 3, delay = 10) {
|
|
70
|
-
for (let i = 0; i < text.length; i += chunkSize) {
|
|
71
|
-
process.stdout.write(text.substring(i, i + chunkSize));
|
|
72
|
-
await sleep(delay);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Type a complete line with automatic newline
|
|
78
|
-
*/
|
|
79
|
-
async function typeLine(text, speed = 15, color = null) {
|
|
80
|
-
await typeText(text, speed, color);
|
|
81
|
-
process.stdout.write('\n');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ==================== PROGRESS BAR ====================
|
|
85
|
-
function createProgressBar(percent, width = 30) {
|
|
86
|
-
const filled = Math.round((percent / 100) * width);
|
|
87
|
-
const empty = width - filled;
|
|
88
|
-
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
89
|
-
return chalk.hex('#F24E1E')(bar) + chalk.gray(` ${percent}%`);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Animate a progress bar from 0 to target
|
|
94
|
-
*/
|
|
95
|
-
async function animateProgressBar(target, label = 'Progress', duration = 2000) {
|
|
96
|
-
const steps = 20;
|
|
97
|
-
const stepTime = duration / steps;
|
|
98
|
-
|
|
99
|
-
for (let i = 0; i <= steps; i++) {
|
|
100
|
-
const current = Math.round((target / steps) * i);
|
|
101
|
-
process.stdout.write(`\r${chalk.gray(label + ':')} ${createProgressBar(current)}`);
|
|
102
|
-
await sleep(stepTime);
|
|
103
|
-
}
|
|
104
|
-
process.stdout.write('\n');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ==================== PREMIUM SPINNER ====================
|
|
108
3
|
class PremiumSpinner {
|
|
109
4
|
constructor(text) {
|
|
110
5
|
this.text = text;
|
|
@@ -118,9 +13,7 @@ class PremiumSpinner {
|
|
|
118
13
|
this.startTime = Date.now();
|
|
119
14
|
this.interval = setInterval(() => {
|
|
120
15
|
const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
|
|
121
|
-
process.stdout.write(
|
|
122
|
-
`\r${chalk.hex('#F24E1E')(this.frames[this.frameIndex])} ${this.text} ${chalk.gray(`[${elapsed}s]`)}`
|
|
123
|
-
);
|
|
16
|
+
process.stdout.write(`\r${chalk.hex('#F24E1E')(this.frames[this.frameIndex])} ${this.text} ${chalk.gray(`[${elapsed}s]`)}`);
|
|
124
17
|
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
125
18
|
}, 80);
|
|
126
19
|
return this;
|
|
@@ -141,13 +34,8 @@ class PremiumSpinner {
|
|
|
141
34
|
console.log(`\r${chalk.red('✗')} ${chalk.white(text || this.text)}`);
|
|
142
35
|
}
|
|
143
36
|
|
|
144
|
-
info(text) {
|
|
145
|
-
this.stop();
|
|
146
|
-
console.log(`\r${chalk.blue('ℹ')} ${chalk.white(text || this.text)}`);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
37
|
clearLine() {
|
|
150
|
-
process.stdout.write('\r' + ' '.repeat(
|
|
38
|
+
process.stdout.write('\r' + ' '.repeat(80) + '\r');
|
|
151
39
|
}
|
|
152
40
|
|
|
153
41
|
stop() {
|
|
@@ -159,757 +47,40 @@ class PremiumSpinner {
|
|
|
159
47
|
}
|
|
160
48
|
}
|
|
161
49
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
console.log(chalk.hex('#F24E1E')('\n🔍 Connecting to research networks...\n'));
|
|
165
|
-
|
|
166
|
-
const sources = [
|
|
167
|
-
{ name: 'Nature', icon: '📗' },
|
|
168
|
-
{ name: 'IEEE Xplore', icon: '📘' },
|
|
169
|
-
{ name: 'PubMed', icon: '📙' },
|
|
170
|
-
{ name: 'arXiv', icon: '📕' },
|
|
171
|
-
{ name: 'Google Scholar', icon: '🎓' },
|
|
172
|
-
{ name: 'Patent Databases', icon: '📜' }
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
for (const source of sources) {
|
|
176
|
-
const spinner = new PremiumSpinner(`${source.icon} Reading ${source.name}...`);
|
|
177
|
-
spinner.start();
|
|
178
|
-
await sleep(400 + Math.random() * 400);
|
|
179
|
-
spinner.succeed(`${source.icon} ${source.name} connected`);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
console.log(chalk.green('\n✓ All sources connected\n'));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async function showPlanningPhase(topic) {
|
|
186
|
-
console.log(chalk.hex('#F24E1E').bold('\n🧠 Planning Mission...\n'));
|
|
187
|
-
|
|
188
|
-
const steps = [
|
|
189
|
-
{ text: `Understanding objective: "${topic}"`, delay: 600 },
|
|
190
|
-
{ text: 'Building execution graph', delay: 500 },
|
|
191
|
-
{ text: 'Selecting research agents (6 agents)', delay: 700 },
|
|
192
|
-
{ text: 'Choosing inference engines', delay: 400 },
|
|
193
|
-
{ text: 'Searching literature databases', delay: 600 },
|
|
194
|
-
{ text: 'Finding relevant datasets', delay: 500 },
|
|
195
|
-
{ text: 'Identifying patents', delay: 400 },
|
|
196
|
-
{ text: 'Mapping research timeline', delay: 600 },
|
|
197
|
-
{ text: 'Planning validation steps', delay: 500 },
|
|
198
|
-
{ text: 'Estimating completion time', delay: 300 }
|
|
199
|
-
];
|
|
200
|
-
|
|
201
|
-
for (const step of steps) {
|
|
202
|
-
const spinner = new PremiumSpinner(step.text);
|
|
203
|
-
spinner.start();
|
|
204
|
-
await sleep(step.delay);
|
|
205
|
-
spinner.succeed(step.text);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
console.log(chalk.green('\n✓ Planning complete\n'));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// ==================== RESEARCH SCORE ====================
|
|
212
|
-
function generateResearchScore(response) {
|
|
213
|
-
// Generate realistic scores based on response length/quality
|
|
214
|
-
const length = (response || '').length;
|
|
215
|
-
const base = Math.min(95, 75 + Math.floor(length / 100));
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
novelty: base + Math.floor(Math.random() * 8) - 3,
|
|
219
|
-
evidence: base + Math.floor(Math.random() * 6),
|
|
220
|
-
confidence: base + Math.floor(Math.random() * 5) - 2,
|
|
221
|
-
methodology: base + Math.floor(Math.random() * 7) - 3,
|
|
222
|
-
reproducibility: base + Math.floor(Math.random() * 8) - 4,
|
|
223
|
-
citations: Math.min(100, base + 5 + Math.floor(Math.random() * 5)),
|
|
224
|
-
gap: ['Low', 'Medium', 'High'][Math.floor(Math.random() * 3)],
|
|
225
|
-
publicationReady: base > 82
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async function displayResearchScore(score) {
|
|
230
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
231
|
-
console.log(chalk.white.bold('📊 Research Quality Score'));
|
|
232
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
233
|
-
|
|
234
|
-
const metrics = [
|
|
235
|
-
{ name: 'Novelty', value: score.novelty },
|
|
236
|
-
{ name: 'Evidence Strength', value: score.evidence },
|
|
237
|
-
{ name: 'Confidence', value: score.confidence },
|
|
238
|
-
{ name: 'Methodological Quality', value: score.methodology },
|
|
239
|
-
{ name: 'Reproducibility', value: score.reproducibility },
|
|
240
|
-
{ name: 'Citation Completeness', value: score.citations }
|
|
241
|
-
];
|
|
242
|
-
|
|
243
|
-
for (const metric of metrics) {
|
|
244
|
-
const color = metric.value >= 90 ? chalk.green : metric.value >= 75 ? chalk.yellow : chalk.red;
|
|
245
|
-
const bar = '█'.repeat(Math.floor(metric.value / 5)) + '░'.repeat(20 - Math.floor(metric.value / 5));
|
|
246
|
-
process.stdout.write(chalk.gray(` ${metric.name.padEnd(25)} `));
|
|
247
|
-
await typeText(`${metric.value}%`, 30, color);
|
|
248
|
-
process.stdout.write(` ${chalk.gray(bar)}\n`);
|
|
249
|
-
await sleep(100);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
console.log('');
|
|
253
|
-
console.log(chalk.gray(' Research Gap: '), chalk.white.bold(score.gap));
|
|
254
|
-
console.log(
|
|
255
|
-
chalk.gray(' Publication Ready: '),
|
|
256
|
-
score.publicationReady ? chalk.green.bold('Yes ✓') : chalk.yellow.bold('No')
|
|
257
|
-
);
|
|
258
|
-
|
|
259
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ==================== ARTIFACTS ====================
|
|
263
|
-
function generateArtifacts(taskType) {
|
|
264
|
-
const base = [
|
|
265
|
-
{ icon: '📄', name: 'Research Report' },
|
|
266
|
-
{ icon: '📊', name: 'Statistical Summary' },
|
|
267
|
-
{ icon: '🔗', name: 'Citation Database' }
|
|
268
|
-
];
|
|
269
|
-
|
|
270
|
-
const extras = {
|
|
271
|
-
LITERATURE_REVIEW: [
|
|
272
|
-
{ icon: '📚', name: 'Literature Review' },
|
|
273
|
-
{ icon: '🗓️', name: 'Research Timeline' },
|
|
274
|
-
{ icon: '🔍', name: 'Gap Analysis' }
|
|
275
|
-
],
|
|
276
|
-
RESEARCH_GAP: [
|
|
277
|
-
{ icon: '🔍', name: 'Gap Analysis' },
|
|
278
|
-
{ icon: '💡', name: 'Novel Opportunities' }
|
|
279
|
-
],
|
|
280
|
-
HYPOTHESIS: [
|
|
281
|
-
{ icon: '💡', name: 'Hypotheses' },
|
|
282
|
-
{ icon: '🧪', name: 'Validation Protocols' }
|
|
283
|
-
]
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
return [...base, ...(extras[taskType] || [])];
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async function displayArtifacts(artifacts) {
|
|
290
|
-
console.log(chalk.hex('#F24E1E').bold('📦 Artifacts Generated\n'));
|
|
291
|
-
|
|
292
|
-
for (const artifact of artifacts) {
|
|
293
|
-
await sleep(100);
|
|
294
|
-
console.log(` ${chalk.green('✓')} ${chalk.white(artifact.icon + ' ' + artifact.name)}`);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
console.log('');
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// ==================== MISSION DASHBOARD ====================
|
|
301
|
-
async function displayMissionDashboard(mission) {
|
|
302
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
303
|
-
console.log(chalk.white.bold(`✨ ${mission.name}`));
|
|
304
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
305
|
-
|
|
306
|
-
console.log(chalk.gray('Status: '), chalk.yellow(mission.status || 'Running'));
|
|
307
|
-
console.log(chalk.gray('Progress: '), createProgressBar(mission.progress || 0));
|
|
308
|
-
console.log('');
|
|
309
|
-
|
|
310
|
-
console.log(chalk.hex('#F24E1E').bold('Research Metrics'));
|
|
311
|
-
const metrics = [
|
|
312
|
-
{ label: 'Papers', value: mission.papers || 0 },
|
|
313
|
-
{ label: 'Patents', value: mission.patents || 0 },
|
|
314
|
-
{ label: 'Datasets', value: mission.datasets || 0 },
|
|
315
|
-
{ label: 'Contradictions', value: mission.contradictions || 0 },
|
|
316
|
-
{ label: 'Hypotheses', value: mission.hypotheses || 0 }
|
|
317
|
-
];
|
|
318
|
-
|
|
319
|
-
for (const m of metrics) {
|
|
320
|
-
console.log(chalk.gray(` ${m.label.padEnd(15)}`), chalk.white(m.value));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (mission.estimatedTime) {
|
|
324
|
-
console.log('');
|
|
325
|
-
console.log(chalk.gray('Est. Completion:'), chalk.white(mission.estimatedTime));
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// ==================== HELPERS FOR TABLE RENDERING ====================
|
|
332
|
-
function formatTable(rows) {
|
|
333
|
-
if (!rows || rows.length === 0) return '';
|
|
334
|
-
|
|
335
|
-
// Calculate column widths
|
|
336
|
-
const colWidths = [];
|
|
337
|
-
rows.forEach(row => {
|
|
338
|
-
row.forEach((cell, i) => {
|
|
339
|
-
colWidths[i] = Math.max(colWidths[i] || 0, cell.length);
|
|
340
|
-
});
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// Format each row
|
|
344
|
-
return rows.map((row, rowIndex) => {
|
|
345
|
-
const isHeader = rowIndex === 0;
|
|
346
|
-
const formatted = row.map((cell, i) => {
|
|
347
|
-
const padded = cell.padEnd(colWidths[i]);
|
|
348
|
-
return isHeader ? chalk.white.bold(padded) : chalk.gray(padded);
|
|
349
|
-
}).join(' │ ');
|
|
350
|
-
|
|
351
|
-
return chalk.gray('│ ') + formatted + chalk.gray(' │');
|
|
352
|
-
}).join('\n');
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
function addVisualBreak() {
|
|
356
|
-
console.log(chalk.gray('\n' + '·'.repeat(60) + '\n'));
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// ==================== INLINE MARKDOWN PARSER ====================
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Parse a line and return array of segments with formatting
|
|
363
|
-
* Handles: **bold**, *italic*, `code`, and combinations
|
|
364
|
-
*/
|
|
365
|
-
function parseInlineMarkdown(text) {
|
|
366
|
-
const segments = [];
|
|
367
|
-
let remaining = text;
|
|
368
|
-
|
|
369
|
-
while (remaining.length > 0) {
|
|
370
|
-
// Find the next markdown pattern
|
|
371
|
-
const boldMatch = remaining.match(/\*\*(.+?)\*\*/);
|
|
372
|
-
const italicMatch = remaining.match(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/);
|
|
373
|
-
const codeMatch = remaining.match(/`([^`]+)`/);
|
|
374
|
-
|
|
375
|
-
// Find earliest match
|
|
376
|
-
let earliest = null;
|
|
377
|
-
let earliestIndex = remaining.length;
|
|
378
|
-
|
|
379
|
-
if (boldMatch && boldMatch.index < earliestIndex) {
|
|
380
|
-
earliest = { type: 'bold', match: boldMatch, index: boldMatch.index };
|
|
381
|
-
earliestIndex = boldMatch.index;
|
|
382
|
-
}
|
|
383
|
-
if (codeMatch && codeMatch.index < earliestIndex) {
|
|
384
|
-
earliest = { type: 'code', match: codeMatch, index: codeMatch.index };
|
|
385
|
-
earliestIndex = codeMatch.index;
|
|
386
|
-
}
|
|
387
|
-
if (italicMatch && italicMatch.index < earliestIndex) {
|
|
388
|
-
earliest = { type: 'italic', match: italicMatch, index: italicMatch.index };
|
|
389
|
-
earliestIndex = italicMatch.index;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (!earliest) {
|
|
393
|
-
// No more markdown, add remaining as plain text
|
|
394
|
-
if (remaining.length > 0) {
|
|
395
|
-
segments.push({ text: remaining, style: 'plain' });
|
|
396
|
-
}
|
|
397
|
-
break;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Add text before the match
|
|
401
|
-
if (earliestIndex > 0) {
|
|
402
|
-
segments.push({
|
|
403
|
-
text: remaining.substring(0, earliestIndex),
|
|
404
|
-
style: 'plain'
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Add the formatted segment
|
|
409
|
-
segments.push({
|
|
410
|
-
text: earliest.match[1],
|
|
411
|
-
style: earliest.type
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
// Continue with remaining text
|
|
415
|
-
remaining = remaining.substring(earliestIndex + earliest.match[0].length);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
return segments;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* Type a line with inline markdown formatting (bold, italic, code)
|
|
423
|
-
*/
|
|
424
|
-
async function typeFormattedLine(text, speed = 8) {
|
|
425
|
-
const segments = parseInlineMarkdown(text);
|
|
426
|
-
|
|
427
|
-
for (const segment of segments) {
|
|
428
|
-
let colorFn = chalk.white;
|
|
429
|
-
|
|
430
|
-
switch (segment.style) {
|
|
431
|
-
case 'bold':
|
|
432
|
-
colorFn = chalk.white.bold;
|
|
433
|
-
break;
|
|
434
|
-
case 'italic':
|
|
435
|
-
colorFn = chalk.white.italic;
|
|
436
|
-
break;
|
|
437
|
-
case 'code':
|
|
438
|
-
colorFn = chalk.bgBlack.cyan;
|
|
439
|
-
break;
|
|
440
|
-
case 'plain':
|
|
441
|
-
default:
|
|
442
|
-
colorFn = chalk.white;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
await typeText(segment.text, speed, colorFn);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
process.stdout.write('\n');
|
|
50
|
+
async function sleep(ms) {
|
|
51
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
449
52
|
}
|
|
450
53
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const segments = parseInlineMarkdown(text);
|
|
456
|
-
|
|
457
|
-
for (const segment of segments) {
|
|
458
|
-
let colorFn = chalk.gray;
|
|
459
|
-
|
|
460
|
-
switch (segment.style) {
|
|
461
|
-
case 'bold':
|
|
462
|
-
colorFn = chalk.white.bold;
|
|
463
|
-
break;
|
|
464
|
-
case 'italic':
|
|
465
|
-
colorFn = chalk.white.italic;
|
|
466
|
-
break;
|
|
467
|
-
case 'code':
|
|
468
|
-
colorFn = chalk.bgBlack.cyan;
|
|
469
|
-
break;
|
|
470
|
-
case 'plain':
|
|
471
|
-
default:
|
|
472
|
-
colorFn = chalk.gray;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
await typeText(segment.text, speed, colorFn);
|
|
54
|
+
async function typeText(text, speed = 8) {
|
|
55
|
+
for (const char of text) {
|
|
56
|
+
process.stdout.write(char);
|
|
57
|
+
await sleep(speed);
|
|
476
58
|
}
|
|
477
|
-
|
|
478
|
-
process.stdout.write('\n');
|
|
479
59
|
}
|
|
480
60
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
console.log(chalk.hex('#F24E1E').bold('\n📄 Research Report\n'));
|
|
485
|
-
console.log(chalk.gray('═'.repeat(60)) + '\n');
|
|
486
|
-
|
|
487
|
-
const lines = response.split('\n');
|
|
488
|
-
let inTable = false;
|
|
489
|
-
|
|
490
|
-
for (let i = 0; i < lines.length; i++) {
|
|
491
|
-
const line = lines[i];
|
|
61
|
+
async function typeAIResponse(text) {
|
|
62
|
+
const lines = text.split('\n');
|
|
63
|
+
for (const line of lines) {
|
|
492
64
|
const trimmed = line.trim();
|
|
493
|
-
|
|
494
|
-
// Skip empty lines but add spacing
|
|
495
|
-
if (trimmed === '') {
|
|
496
|
-
if (!inTable) {
|
|
497
|
-
console.log('');
|
|
498
|
-
await sleep(80);
|
|
499
|
-
}
|
|
500
|
-
continue;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// Detect table rows (lines with |)
|
|
504
|
-
if (trimmed.includes('|') && trimmed.startsWith('|')) {
|
|
505
|
-
// Skip separator rows like |---|---| or | ---------- |
|
|
506
|
-
if (trimmed.match(/^\|[\s\-:]+\|$/)) {
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if (!inTable) {
|
|
511
|
-
inTable = true;
|
|
512
|
-
console.log(chalk.gray('┌' + '─'.repeat(58) + '┐'));
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
// Parse table cells
|
|
516
|
-
const cells = trimmed.split('|').filter(c => c.trim() !== '').map(c => c.trim());
|
|
517
|
-
|
|
518
|
-
// Format table row with inline markdown support
|
|
519
|
-
if (cells.length > 0) {
|
|
520
|
-
const isHeader = i === 0 || (i > 0 && lines[i-1].trim() === '');
|
|
521
|
-
|
|
522
|
-
process.stdout.write(chalk.gray('│ '));
|
|
523
|
-
|
|
524
|
-
for (let j = 0; j < cells.length; j++) {
|
|
525
|
-
const cell = cells[j];
|
|
526
|
-
const padded = cell.padEnd(15);
|
|
527
|
-
|
|
528
|
-
if (isHeader) {
|
|
529
|
-
// Header cells - parse markdown and make bold
|
|
530
|
-
const segments = parseInlineMarkdown(padded);
|
|
531
|
-
for (const seg of segments) {
|
|
532
|
-
process.stdout.write(chalk.white.bold(seg.text));
|
|
533
|
-
}
|
|
534
|
-
} else {
|
|
535
|
-
// Regular cells - parse markdown
|
|
536
|
-
const segments = parseInlineMarkdown(padded);
|
|
537
|
-
for (const seg of segments) {
|
|
538
|
-
let colorFn = chalk.gray;
|
|
539
|
-
if (seg.style === 'bold') colorFn = chalk.white.bold;
|
|
540
|
-
else if (seg.style === 'italic') colorFn = chalk.white.italic;
|
|
541
|
-
else if (seg.style === 'code') colorFn = chalk.bgBlack.cyan;
|
|
542
|
-
process.stdout.write(colorFn(seg.text));
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
if (j < cells.length - 1) {
|
|
547
|
-
process.stdout.write(chalk.gray(' │ '));
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
console.log(chalk.gray(' │'));
|
|
552
|
-
await sleep(50);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
continue;
|
|
556
|
-
} else if (inTable) {
|
|
557
|
-
// End of table
|
|
558
|
-
console.log(chalk.gray('└' + '─'.repeat(58) + '┐'));
|
|
559
|
-
console.log('');
|
|
560
|
-
inTable = false;
|
|
561
|
-
await sleep(100);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// Headers (## or #)
|
|
565
|
-
if (trimmed.startsWith('## ')) {
|
|
566
|
-
const header = trimmed.substring(3);
|
|
567
|
-
console.log('');
|
|
568
|
-
process.stdout.write(chalk.hex('#F24E1E').bold('▸ '));
|
|
569
|
-
await typeFormattedLine(header, 15);
|
|
570
|
-
console.log(chalk.gray('─'.repeat(60)));
|
|
571
|
-
await sleep(150);
|
|
572
|
-
continue;
|
|
573
|
-
}
|
|
574
|
-
|
|
65
|
+
if (trimmed === '') { console.log(''); continue; }
|
|
575
66
|
if (trimmed.startsWith('# ')) {
|
|
576
|
-
|
|
577
|
-
console.log('');
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
console.log('');
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
await typeFormattedLine(bullet, 8);
|
|
590
|
-
await sleep(60);
|
|
591
|
-
continue;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// Numbered lists
|
|
595
|
-
const numberedMatch = trimmed.match(/^(\d+)\.\s+(.+)/);
|
|
596
|
-
if (numberedMatch) {
|
|
597
|
-
const num = numberedMatch[1];
|
|
598
|
-
const text = numberedMatch[2];
|
|
599
|
-
process.stdout.write(chalk.hex('#F24E1E')(` ${num}. `));
|
|
600
|
-
await typeFormattedLine(text, 8);
|
|
601
|
-
await sleep(60);
|
|
602
|
-
continue;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Regular paragraph (with inline markdown support)
|
|
606
|
-
process.stdout.write(' ');
|
|
607
|
-
await typeFormattedLineGray(trimmed, 6);
|
|
608
|
-
await sleep(40);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Close any open table
|
|
612
|
-
if (inTable) {
|
|
613
|
-
console.log(chalk.gray('└' + '─'.repeat(58) + '┐'));
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
console.log('\n' + chalk.gray('═'.repeat(60)) + '\n');
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// ==================== RENDER MARKDOWN (existing) ====================
|
|
620
|
-
function renderMarkdown(markdown) {
|
|
621
|
-
// Simplified - most formatting happens in typeAIResponse
|
|
622
|
-
return markdown;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
async function displayReport(markdown, useTypingEffect = true) {
|
|
626
|
-
if (useTypingEffect) {
|
|
627
|
-
await typeAIResponse(markdown);
|
|
628
|
-
} else {
|
|
629
|
-
console.log(markdown);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// ==================== SIMPLE THINKING ANIMATION ====================
|
|
634
|
-
async function showThinking(taskType, topic) {
|
|
635
|
-
console.log(chalk.hex('#F24E1E').bold(`\n🤖 Thinking about: ${topic}\n`));
|
|
636
|
-
|
|
637
|
-
const thoughts = [
|
|
638
|
-
'Analyzing research landscape...',
|
|
639
|
-
'Identifying key methodologies...',
|
|
640
|
-
'Cross-referencing findings...',
|
|
641
|
-
'Synthesizing insights...',
|
|
642
|
-
'Preparing report...'
|
|
643
|
-
];
|
|
644
|
-
|
|
645
|
-
for (const thought of thoughts) {
|
|
646
|
-
const spinner = new PremiumSpinner(thought);
|
|
647
|
-
spinner.start();
|
|
648
|
-
await sleep(600 + Math.random() * 400);
|
|
649
|
-
spinner.succeed(thought);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// ==================== MISSION HEALTH SCORE ====================
|
|
654
|
-
|
|
655
|
-
/**
|
|
656
|
-
* Calculate comprehensive mission health metrics
|
|
657
|
-
*/
|
|
658
|
-
function calculateMissionHealth(missionData) {
|
|
659
|
-
const evidence = missionData.evidenceScore || 96;
|
|
660
|
-
const novelty = missionData.noveltyScore || 81;
|
|
661
|
-
const confidence = missionData.confidenceScore || 91;
|
|
662
|
-
const methodology = missionData.methodologyScore || 89;
|
|
663
|
-
const reproducibility = missionData.reproducibilityScore || 93;
|
|
664
|
-
const citations = missionData.citationsScore || 98;
|
|
665
|
-
|
|
666
|
-
// Calculate overall health (weighted average)
|
|
667
|
-
const overall = Math.round(
|
|
668
|
-
(evidence * 0.25) +
|
|
669
|
-
(novelty * 0.15) +
|
|
670
|
-
(confidence * 0.20) +
|
|
671
|
-
(methodology * 0.15) +
|
|
672
|
-
(reproducibility * 0.15) +
|
|
673
|
-
(citations * 0.10)
|
|
674
|
-
);
|
|
675
|
-
|
|
676
|
-
// Calculate bias risk
|
|
677
|
-
const biasRisk = overall >= 90 ? 'Low' : overall >= 75 ? 'Medium' : 'High';
|
|
678
|
-
|
|
679
|
-
// Identify missing experiments based on gaps
|
|
680
|
-
const missingExperiments = missionData.gapsCount || Math.floor(Math.random() * 3) + 1;
|
|
681
|
-
|
|
682
|
-
// Publication readiness
|
|
683
|
-
const publicationReady = overall >= 85 && evidence >= 90 && citations >= 95;
|
|
684
|
-
|
|
685
|
-
return {
|
|
686
|
-
overall,
|
|
687
|
-
evidence,
|
|
688
|
-
novelty,
|
|
689
|
-
confidence,
|
|
690
|
-
methodology,
|
|
691
|
-
reproducibility,
|
|
692
|
-
citations,
|
|
693
|
-
biasRisk,
|
|
694
|
-
missingExperiments,
|
|
695
|
-
publicationReady
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
/**
|
|
700
|
-
* Display beautiful mission health score
|
|
701
|
-
*/
|
|
702
|
-
async function displayMissionHealth(health, missionName = 'Mission') {
|
|
703
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
704
|
-
console.log(chalk.white.bold(`🏥 ${missionName} - Health Score`));
|
|
705
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
706
|
-
|
|
707
|
-
// Overall health with color coding
|
|
708
|
-
const overallColor = health.overall >= 90 ? chalk.green :
|
|
709
|
-
health.overall >= 75 ? chalk.yellow : chalk.red;
|
|
710
|
-
|
|
711
|
-
console.log(chalk.gray(' Overall Health:'), overallColor.bold(`${health.overall}%`));
|
|
712
|
-
console.log('');
|
|
713
|
-
|
|
714
|
-
// Detailed metrics
|
|
715
|
-
const metrics = [
|
|
716
|
-
{ name: 'Evidence Strength', value: health.evidence },
|
|
717
|
-
{ name: 'Novelty', value: health.novelty },
|
|
718
|
-
{ name: 'Confidence', value: health.confidence },
|
|
719
|
-
{ name: 'Methodological Quality', value: health.methodology },
|
|
720
|
-
{ name: 'Reproducibility', value: health.reproducibility },
|
|
721
|
-
{ name: 'Citation Completeness', value: health.citations }
|
|
722
|
-
];
|
|
723
|
-
|
|
724
|
-
for (const metric of metrics) {
|
|
725
|
-
const color = metric.value >= 90 ? chalk.green :
|
|
726
|
-
metric.value >= 75 ? chalk.yellow : chalk.red;
|
|
727
|
-
const bar = '█'.repeat(Math.floor(metric.value / 5)) + '░'.repeat(20 - Math.floor(metric.value / 5));
|
|
728
|
-
|
|
729
|
-
process.stdout.write(chalk.gray(` ${metric.name.padEnd(25)} `));
|
|
730
|
-
await typeText(`${metric.value}%`, 20, color);
|
|
731
|
-
process.stdout.write(` ${chalk.gray(bar)}\n`);
|
|
732
|
-
await sleep(80);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
console.log('');
|
|
736
|
-
|
|
737
|
-
// Risk assessment
|
|
738
|
-
const biasColor = health.biasRisk === 'Low' ? chalk.green :
|
|
739
|
-
health.biasRisk === 'Medium' ? chalk.yellow : chalk.red;
|
|
740
|
-
console.log(chalk.gray(' Bias Risk:'), biasColor.bold(health.biasRisk));
|
|
741
|
-
|
|
742
|
-
// Missing experiments
|
|
743
|
-
if (health.missingExperiments > 0) {
|
|
744
|
-
console.log(
|
|
745
|
-
chalk.gray(' Missing Experiments:'),
|
|
746
|
-
chalk.yellow.bold(`${health.missingExperiments}`)
|
|
747
|
-
);
|
|
748
|
-
} else {
|
|
749
|
-
console.log(chalk.gray(' Missing Experiments:'), chalk.green.bold('None ✓'));
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// Publication readiness
|
|
753
|
-
console.log(
|
|
754
|
-
chalk.gray(' Publication Ready:'),
|
|
755
|
-
health.publicationReady ? chalk.green.bold('Yes ✓') : chalk.yellow.bold('Needs Review')
|
|
756
|
-
);
|
|
757
|
-
|
|
758
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
// ==================== RESEARCH TIMELINE VISUALIZATION ====================
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Display beautiful research timeline
|
|
765
|
-
*/
|
|
766
|
-
async function displayTimeline(timeline, topic) {
|
|
767
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
768
|
-
console.log(chalk.white.bold(`📅 Research Timeline: ${topic}`));
|
|
769
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
770
|
-
|
|
771
|
-
if (!timeline || timeline.length === 0) {
|
|
772
|
-
console.log(chalk.gray(' No timeline data available.\n'));
|
|
773
|
-
return;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// Sort by year
|
|
777
|
-
const sorted = [...timeline].sort((a, b) => a.year - b.year);
|
|
778
|
-
|
|
779
|
-
for (let i = 0; i < sorted.length; i++) {
|
|
780
|
-
const event = sorted[i];
|
|
781
|
-
const isLast = i === sorted.length - 1;
|
|
782
|
-
const isCurrent = event.isCurrentResearch;
|
|
783
|
-
|
|
784
|
-
// Year
|
|
785
|
-
process.stdout.write(chalk.hex('#F24E1E').bold(` ${event.year} `));
|
|
786
|
-
|
|
787
|
-
// Connector line
|
|
788
|
-
if (!isLast) {
|
|
789
|
-
process.stdout.write(chalk.gray('──── '));
|
|
790
|
-
} else {
|
|
791
|
-
process.stdout.write(chalk.gray('──── '));
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// Event title
|
|
795
|
-
if (isCurrent) {
|
|
796
|
-
await typeText(event.title, 10, chalk.green.bold);
|
|
797
|
-
} else {
|
|
798
|
-
await typeText(event.title, 10, chalk.white);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
console.log('');
|
|
802
|
-
|
|
803
|
-
// Description
|
|
804
|
-
if (event.description) {
|
|
805
|
-
console.log(chalk.gray(` ${event.description}`));
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
// Impact
|
|
809
|
-
if (event.impact) {
|
|
810
|
-
const impactColor = event.impact === 'High' ? chalk.red :
|
|
811
|
-
event.impact === 'Medium' ? chalk.yellow : chalk.gray;
|
|
812
|
-
console.log(chalk.gray(` Impact: `), impactColor(event.impact));
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// Vertical connector
|
|
816
|
-
if (!isLast) {
|
|
817
|
-
console.log(chalk.gray(' │'));
|
|
67
|
+
console.log(chalk.hex('#F24E1E').bold(`\n${trimmed.substring(2)}`));
|
|
68
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
69
|
+
} else if (trimmed.startsWith('## ')) {
|
|
70
|
+
console.log(chalk.white.bold(`\n▸ ${trimmed.substring(3)}`));
|
|
71
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
72
|
+
} else if (trimmed.startsWith('### ')) {
|
|
73
|
+
console.log(chalk.white.bold(`\n ▸ ${trimmed.substring(4)}`));
|
|
74
|
+
} else if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
|
|
75
|
+
console.log(chalk.white(` ▸ ${trimmed.substring(2)}`));
|
|
76
|
+
} else if (trimmed.match(/^\d+\./)) {
|
|
77
|
+
console.log(chalk.white(` ${trimmed}`));
|
|
78
|
+
} else if (trimmed.startsWith('|')) {
|
|
79
|
+
console.log(chalk.gray(` ${trimmed}`));
|
|
818
80
|
} else {
|
|
819
|
-
console.log(
|
|
820
|
-
console.log(chalk.green.bold(' ✨ Your research continues from here'));
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
console.log('');
|
|
824
|
-
await sleep(150);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
// ==================== MORNING BRIEFING DISPLAY ====================
|
|
831
|
-
|
|
832
|
-
/**
|
|
833
|
-
* Display morning briefing
|
|
834
|
-
*/
|
|
835
|
-
async function displayMorningBriefing(briefing) {
|
|
836
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
837
|
-
console.log(chalk.white.bold('☀️ Good Morning, Researcher!'));
|
|
838
|
-
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
839
|
-
|
|
840
|
-
console.log(chalk.gray(` ${briefing.date}\n`));
|
|
841
|
-
|
|
842
|
-
if (briefing.updates && briefing.updates.length > 0) {
|
|
843
|
-
console.log(chalk.white.bold(' 📊 Mission Updates:\n'));
|
|
844
|
-
|
|
845
|
-
for (const update of briefing.updates) {
|
|
846
|
-
const icon = update.type === 'paper' ? '📄' :
|
|
847
|
-
update.type === 'patent' ? '📜' :
|
|
848
|
-
update.type === 'citation' ? '🔗' :
|
|
849
|
-
update.type === 'contradiction' ? '⚠️' : '📌';
|
|
850
|
-
|
|
851
|
-
process.stdout.write(chalk.gray(` ${icon} `));
|
|
852
|
-
await typeText(update.text, 8, chalk.white);
|
|
853
|
-
console.log('');
|
|
854
|
-
await sleep(100);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (briefing.missions && briefing.missions.length > 0) {
|
|
859
|
-
console.log(chalk.white.bold('\n 🎯 Active Missions:\n'));
|
|
860
|
-
|
|
861
|
-
for (const mission of briefing.missions) {
|
|
862
|
-
const statusColor = mission.status === 'Running' ? chalk.yellow :
|
|
863
|
-
mission.status === 'Complete' ? chalk.green : chalk.gray;
|
|
864
|
-
|
|
865
|
-
console.log(chalk.gray(` ✨ ${mission.name}`));
|
|
866
|
-
console.log(statusColor(` Status: ${mission.status}`));
|
|
867
|
-
console.log(chalk.gray(` Progress: ${mission.progress}%`));
|
|
868
|
-
console.log('');
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
if (briefing.recommendations && briefing.recommendations.length > 0) {
|
|
873
|
-
console.log(chalk.white.bold(' 💡 Recommendations:\n'));
|
|
874
|
-
|
|
875
|
-
for (const rec of briefing.recommendations) {
|
|
876
|
-
process.stdout.write(chalk.gray(' ▸ '));
|
|
877
|
-
await typeText(rec, 8, chalk.white);
|
|
878
|
-
console.log('');
|
|
879
|
-
await sleep(80);
|
|
81
|
+
console.log(chalk.white(` ${trimmed}`));
|
|
880
82
|
}
|
|
881
83
|
}
|
|
882
|
-
|
|
883
|
-
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
884
84
|
}
|
|
885
85
|
|
|
886
|
-
module.exports = {
|
|
887
|
-
generateMissionName,
|
|
888
|
-
sleep,
|
|
889
|
-
typeText,
|
|
890
|
-
streamText,
|
|
891
|
-
typeLine,
|
|
892
|
-
createProgressBar,
|
|
893
|
-
animateProgressBar,
|
|
894
|
-
PremiumSpinner,
|
|
895
|
-
animateResearchSources,
|
|
896
|
-
showPlanningPhase,
|
|
897
|
-
generateResearchScore,
|
|
898
|
-
displayResearchScore,
|
|
899
|
-
generateArtifacts,
|
|
900
|
-
displayArtifacts,
|
|
901
|
-
displayMissionDashboard,
|
|
902
|
-
typeAIResponse,
|
|
903
|
-
renderMarkdown,
|
|
904
|
-
displayReport,
|
|
905
|
-
showThinking,
|
|
906
|
-
formatTable,
|
|
907
|
-
addVisualBreak,
|
|
908
|
-
// NEW EXPORTS
|
|
909
|
-
calculateMissionHealth,
|
|
910
|
-
displayMissionHealth,
|
|
911
|
-
displayTimeline,
|
|
912
|
-
displayMorningBriefing,
|
|
913
|
-
// ADD BANNER
|
|
914
|
-
displayBanner,
|
|
915
|
-
};
|
|
86
|
+
module.exports = { PremiumSpinner, sleep, typeText, typeAIResponse };
|