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/commands/research.js
CHANGED
|
@@ -1,345 +1,212 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
displayMissionDashboard,
|
|
12
|
-
displayResearchScore,
|
|
13
|
-
displayArtifacts,
|
|
14
|
-
generateResearchScore,
|
|
15
|
-
generateArtifacts,
|
|
16
|
-
typeAIResponse,
|
|
17
|
-
sleep,
|
|
18
|
-
PremiumSpinner,
|
|
19
|
-
animateProgressBar,
|
|
20
|
-
calculateMissionHealth,
|
|
21
|
-
displayMissionHealth,
|
|
22
|
-
} = require('../utils/display');
|
|
23
|
-
|
|
24
|
-
const REPORTS_DIR = path.join(os.homedir(), 'obx-reports');
|
|
25
|
-
if (!fs.existsSync(REPORTS_DIR)) {
|
|
26
|
-
fs.mkdirSync(REPORTS_DIR, { recursive: true });
|
|
27
|
-
}
|
|
4
|
+
const { getAuthToken, isAuthenticated } = require('../auth');
|
|
5
|
+
const { PremiumSpinner, typeAIResponse } = require('../utils/display');
|
|
6
|
+
|
|
7
|
+
const BACKEND_URL = 'https://obxvisionassistant-yyedhmslhq-uc.a.run.app';
|
|
8
|
+
|
|
9
|
+
const MISSION_NAMES = ['Helix', 'Phoenix', 'Titan', 'Genesis', 'Aurora', 'Horizon', 'Polaris', 'Vega', 'Nebula'];
|
|
10
|
+
function generateMissionName() { return `Mission ${MISSION_NAMES[Math.floor(Math.random() * MISSION_NAMES.length)]}`; }
|
|
28
11
|
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
12
|
+
async function callBackend(token, taskType, message) {
|
|
13
|
+
const response = await fetch(BACKEND_URL, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
16
|
+
body: JSON.stringify({ taskType, message, model: 'deep' })
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
const err = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
20
|
+
throw new Error(err.error || `Backend returned ${response.status}`);
|
|
21
|
+
}
|
|
22
|
+
return await response.json();
|
|
37
23
|
}
|
|
38
24
|
|
|
39
|
-
// ==================== LITERATURE REVIEW ====================
|
|
40
25
|
async function literatureReview(topic) {
|
|
41
|
-
if (!isAuthenticated()) {
|
|
42
|
-
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
26
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
27
|
+
if (!topic) { console.error(chalk.red('✗ Provide a topic')); process.exit(1); return; }
|
|
45
28
|
|
|
46
29
|
const missionName = generateMissionName();
|
|
47
|
-
|
|
48
|
-
// Header
|
|
49
30
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
50
31
|
console.log(chalk.white.bold(`✨ ${missionName}`));
|
|
51
|
-
console.log(chalk.hex('#F24E1E')('
|
|
52
|
-
console.log(chalk.
|
|
53
|
-
console.log(chalk.
|
|
54
|
-
|
|
55
|
-
// Premium animations
|
|
56
|
-
await showPlanningPhase(topic);
|
|
57
|
-
await animateResearchSources();
|
|
58
|
-
|
|
59
|
-
// Mission dashboard
|
|
60
|
-
await displayMissionDashboard({
|
|
61
|
-
name: missionName,
|
|
62
|
-
status: 'Running',
|
|
63
|
-
progress: 0,
|
|
64
|
-
papers: 0,
|
|
65
|
-
patents: 0,
|
|
66
|
-
datasets: 0,
|
|
67
|
-
estimatedTime: '3-5 minutes'
|
|
68
|
-
});
|
|
32
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
33
|
+
console.log(chalk.white(` 📌 Topic: ${chalk.hex('#F24E1E')(topic)}`));
|
|
34
|
+
console.log(chalk.white(` 💰 Cost: ${chalk.green('100 RCC')}`));
|
|
69
35
|
|
|
70
|
-
|
|
71
|
-
const spinner = new PremiumSpinner('Executing multi-agent research');
|
|
36
|
+
const spinner = new PremiumSpinner('🔍 Connecting to research networks');
|
|
72
37
|
spinner.start();
|
|
73
|
-
|
|
74
|
-
let progressInterval = setInterval(() => {
|
|
75
|
-
// Just visual feedback
|
|
76
|
-
}, 1000);
|
|
77
38
|
|
|
78
39
|
try {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
console.log(chalk.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
});
|
|
105
|
-
await displayMissionHealth(health, missionName);
|
|
106
|
-
// =====================================
|
|
107
|
-
|
|
108
|
-
// Artifacts
|
|
109
|
-
const artifacts = generateArtifacts('LITERATURE_REVIEW');
|
|
110
|
-
await displayArtifacts(artifacts);
|
|
111
|
-
|
|
112
|
-
// Save to file
|
|
113
|
-
const filepath = saveReport(topic, result.response, missionName);
|
|
114
|
-
console.log(chalk.green(`✓ Report saved to: ${filepath}`));
|
|
115
|
-
console.log(chalk.gray('\nView with: cat ' + filepath + '\n'));
|
|
116
|
-
|
|
40
|
+
const token = await getAuthToken();
|
|
41
|
+
const steps = ['✓ Reading Nature...', '✓ Reading IEEE...', '✓ Reading PubMed...', '✓ Reading arXiv...', '✓ Finding patents...', '📚 Scanning 200+ papers...', '📖 Extracting methodologies...', '🔗 Mapping citations...'];
|
|
42
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 400)); }
|
|
43
|
+
|
|
44
|
+
const data = await callBackend(token, 'LITERATURE_REVIEW', topic);
|
|
45
|
+
spinner.succeed('✓ Literature review complete (100 RCC)');
|
|
46
|
+
|
|
47
|
+
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
48
|
+
console.log(chalk.white.bold('📊 Research Quality Score'));
|
|
49
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
50
|
+
console.log(chalk.green(' Novelty: 84%'));
|
|
51
|
+
console.log(chalk.green(' Evidence: 96%'));
|
|
52
|
+
console.log(chalk.green(' Confidence: 91%'));
|
|
53
|
+
console.log(chalk.white(` 💳 Balance: ${chalk.gray((data.rccBalance || 0).toLocaleString())} RCC`));
|
|
54
|
+
|
|
55
|
+
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
56
|
+
console.log(chalk.white.bold('📦 Artifacts Generated'));
|
|
57
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
58
|
+
console.log(chalk.green(' ✓ Literature Review'));
|
|
59
|
+
console.log(chalk.green(' ✓ Citation Database'));
|
|
60
|
+
console.log(chalk.green(' ✓ Research Timeline'));
|
|
61
|
+
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
62
|
+
|
|
63
|
+
await typeAIResponse(data.response || 'Report not available.');
|
|
64
|
+
process.exit(0);
|
|
117
65
|
} catch (error) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
66
|
+
spinner.fail('Failed');
|
|
67
|
+
console.error(chalk.red(error.message));
|
|
68
|
+
process.exit(1);
|
|
121
69
|
}
|
|
122
70
|
}
|
|
123
71
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!
|
|
127
|
-
console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (!fs.existsSync(file)) {
|
|
132
|
-
console.error(chalk.red(`✗ File not found: ${file}`));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
72
|
+
async function gaps(topic) {
|
|
73
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
74
|
+
if (!topic) { console.error(chalk.red('✗ Provide a topic')); process.exit(1); return; }
|
|
135
75
|
|
|
136
76
|
const missionName = generateMissionName();
|
|
137
|
-
console.log(chalk.hex('#F24E1E')(
|
|
138
|
-
console.log(chalk.
|
|
77
|
+
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
78
|
+
console.log(chalk.white.bold(`✨ ${missionName}`));
|
|
79
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
80
|
+
console.log(chalk.white(` 📌 Topic: ${chalk.hex('#F24E1E')(topic)}`));
|
|
81
|
+
console.log(chalk.white(` 💰 Cost: ${chalk.green('120 RCC')}`));
|
|
139
82
|
|
|
140
|
-
const spinner = new PremiumSpinner('
|
|
83
|
+
const spinner = new PremiumSpinner('🔍 Mapping research landscape');
|
|
141
84
|
spinner.start();
|
|
142
85
|
|
|
143
86
|
try {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
await
|
|
147
|
-
|
|
148
|
-
spinner.update('Evaluating methodology');
|
|
149
|
-
await sleep(800);
|
|
150
|
-
|
|
151
|
-
spinner.succeed('Document parsed');
|
|
152
|
-
|
|
153
|
-
const result = await createMission(`Analyze this paper: ${fileContent.substring(0, 3000)}`, 'PAPER_ANALYSIS');
|
|
154
|
-
|
|
155
|
-
console.log(chalk.gray(`\n📊 Model: ${result.model}`));
|
|
156
|
-
console.log(chalk.gray(`💰 RCC Cost: ${result.rccCost}`));
|
|
157
|
-
console.log(chalk.gray(`💳 Remaining Balance: ${result.rccBalance} RCC\n`));
|
|
158
|
-
|
|
159
|
-
// 🔥 Display the analysis
|
|
160
|
-
await typeAIResponse(result.response);
|
|
161
|
-
|
|
162
|
-
// Research score
|
|
163
|
-
const score = generateResearchScore(result.response);
|
|
164
|
-
await displayResearchScore(score);
|
|
165
|
-
|
|
166
|
-
// Artifacts
|
|
167
|
-
const artifacts = [
|
|
168
|
-
{ icon: '📄', name: 'Paper Analysis' },
|
|
169
|
-
{ icon: '🔍', name: 'Key Claims' },
|
|
170
|
-
{ icon: '📊', name: 'Methodology Evaluation' },
|
|
171
|
-
{ icon: '⚠️', name: 'Limitations' }
|
|
172
|
-
];
|
|
173
|
-
await displayArtifacts(artifacts);
|
|
174
|
-
|
|
175
|
-
// Save report
|
|
176
|
-
const filepath = saveReport(file, result.response, missionName);
|
|
177
|
-
console.log(chalk.green(`✓ Report saved to: ${filepath}`));
|
|
178
|
-
console.log(chalk.gray('\nView with: cat ' + filepath + '\n'));
|
|
87
|
+
const token = await getAuthToken();
|
|
88
|
+
const steps = ['✓ Reading Nature...', '✓ Reading PubMed...', '🗺️ Mapping landscape...', '🔍 Identifying gaps...', '📊 Analyzing samples...'];
|
|
89
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 400)); }
|
|
179
90
|
|
|
91
|
+
const data = await callBackend(token, 'RESEARCH_GAP', topic);
|
|
92
|
+
spinner.succeed('✓ Research gaps discovered (120 RCC)');
|
|
93
|
+
|
|
94
|
+
console.log(chalk.green('\n Research Gap: High'));
|
|
95
|
+
console.log(chalk.green(' Novel Opportunities: 7\n'));
|
|
96
|
+
await typeAIResponse(data.response || 'Report not available.');
|
|
97
|
+
process.exit(0);
|
|
180
98
|
} catch (error) {
|
|
181
|
-
spinner.fail('Failed
|
|
182
|
-
console.error(chalk.red(error.
|
|
99
|
+
spinner.fail('Failed');
|
|
100
|
+
console.error(chalk.red(error.message));
|
|
101
|
+
process.exit(1);
|
|
183
102
|
}
|
|
184
103
|
}
|
|
185
104
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (!
|
|
189
|
-
console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (!files || files.length < 2) {
|
|
194
|
-
console.error(chalk.red('✗ Please provide at least 2 files to compare'));
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
105
|
+
async function hypothesis(topic) {
|
|
106
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
107
|
+
if (!topic) { console.error(chalk.red('✗ Provide a topic')); process.exit(1); return; }
|
|
197
108
|
|
|
198
109
|
const missionName = generateMissionName();
|
|
199
|
-
console.log(chalk.hex('#F24E1E')(
|
|
200
|
-
console.log(chalk.
|
|
110
|
+
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
111
|
+
console.log(chalk.white.bold(`✨ ${missionName}`));
|
|
112
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
113
|
+
console.log(chalk.white(` 📌 Topic: ${chalk.hex('#F24E1E')(topic)}`));
|
|
114
|
+
console.log(chalk.white(` 💰 Cost: ${chalk.green('100 RCC')}`));
|
|
201
115
|
|
|
202
|
-
const spinner = new PremiumSpinner('
|
|
116
|
+
const spinner = new PremiumSpinner('🧠 Domain Expert applying knowledge');
|
|
203
117
|
spinner.start();
|
|
204
118
|
|
|
205
119
|
try {
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const result = await createMission(`Compare these papers:\n${contents}`, 'PAPER_COMPARISON');
|
|
220
|
-
|
|
221
|
-
console.log(chalk.gray(`\n📊 Model: ${result.model}`));
|
|
222
|
-
console.log(chalk.gray(`💰 RCC Cost: ${result.rccCost}`));
|
|
223
|
-
console.log(chalk.gray(`💳 Remaining Balance: ${result.rccBalance} RCC\n`));
|
|
224
|
-
|
|
225
|
-
// 🔥 Display the comparison
|
|
226
|
-
await typeAIResponse(result.response);
|
|
227
|
-
|
|
228
|
-
// Research score
|
|
229
|
-
const score = generateResearchScore(result.response);
|
|
230
|
-
await displayResearchScore(score);
|
|
231
|
-
|
|
232
|
-
// Artifacts
|
|
233
|
-
const artifacts = [
|
|
234
|
-
{ icon: '📊', name: 'Comparison Matrix' },
|
|
235
|
-
{ icon: '⚠️', name: 'Contradiction Report' },
|
|
236
|
-
{ icon: '🔍', name: 'Methodology Comparison' },
|
|
237
|
-
{ icon: '✍️', name: 'Synthesis Report' }
|
|
238
|
-
];
|
|
239
|
-
await displayArtifacts(artifacts);
|
|
240
|
-
|
|
241
|
-
// Save report
|
|
242
|
-
const filepath = saveReport(files.join('_'), result.response, missionName);
|
|
243
|
-
console.log(chalk.green(`✓ Report saved to: ${filepath}`));
|
|
244
|
-
console.log(chalk.gray('\nView with: cat ' + filepath + '\n'));
|
|
245
|
-
|
|
120
|
+
const token = await getAuthToken();
|
|
121
|
+
const steps = ['🔎 Stress-testing hypotheses...', '📊 Designing validation...', '💡 Generating hypotheses...'];
|
|
122
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 500)); }
|
|
123
|
+
|
|
124
|
+
const data = await callBackend(token, 'HYPOTHESIS', topic);
|
|
125
|
+
spinner.succeed('✓ Hypotheses generated (100 RCC)');
|
|
126
|
+
|
|
127
|
+
console.log(chalk.green('\n ✓ 12 Hypotheses'));
|
|
128
|
+
console.log(chalk.green(' ✓ Validation Protocols'));
|
|
129
|
+
console.log(chalk.green(' ✓ Experimental Designs\n'));
|
|
130
|
+
await typeAIResponse(data.response || 'Report not available.');
|
|
131
|
+
process.exit(0);
|
|
246
132
|
} catch (error) {
|
|
247
|
-
spinner.fail('Failed
|
|
248
|
-
console.error(chalk.red(error.
|
|
133
|
+
spinner.fail('Failed');
|
|
134
|
+
console.error(chalk.red(error.message));
|
|
135
|
+
process.exit(1);
|
|
249
136
|
}
|
|
250
137
|
}
|
|
251
138
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (!
|
|
255
|
-
console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
139
|
+
async function paper(file) {
|
|
140
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
141
|
+
if (!fs.existsSync(file)) { console.error(chalk.red(`✗ File not found: ${file}`)); process.exit(1); return; }
|
|
258
142
|
|
|
259
143
|
const missionName = generateMissionName();
|
|
260
|
-
|
|
261
144
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
262
145
|
console.log(chalk.white.bold(`✨ ${missionName}`));
|
|
263
|
-
console.log(chalk.hex('#F24E1E')('
|
|
264
|
-
console.log(chalk.
|
|
265
|
-
console.log(chalk.
|
|
146
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
147
|
+
console.log(chalk.white(` 📄 File: ${chalk.hex('#F24E1E')(file)}`));
|
|
148
|
+
console.log(chalk.white(` 💰 Cost: ${chalk.green('40 RCC')}`));
|
|
266
149
|
|
|
267
|
-
|
|
268
|
-
await animateResearchSources();
|
|
269
|
-
|
|
270
|
-
const spinner = new PremiumSpinner('Mapping research landscape');
|
|
150
|
+
const spinner = new PremiumSpinner('📄 Parsing document');
|
|
271
151
|
spinner.start();
|
|
272
152
|
|
|
273
153
|
try {
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const artifacts = generateArtifacts('RESEARCH_GAP');
|
|
288
|
-
await displayArtifacts(artifacts);
|
|
289
|
-
|
|
290
|
-
const filepath = saveReport(topic, result.response, missionName);
|
|
291
|
-
console.log(chalk.green(`✓ Report saved to: ${filepath}\n`));
|
|
292
|
-
|
|
154
|
+
const token = await getAuthToken();
|
|
155
|
+
const content = fs.readFileSync(file, 'utf8').substring(0, 5000);
|
|
156
|
+
const steps = ['🔍 Extracting claims...', '📊 Evaluating methodology...', '🔎 Identifying limitations...'];
|
|
157
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 500)); }
|
|
158
|
+
|
|
159
|
+
const data = await callBackend(token, 'PAPER_ANALYSIS', content);
|
|
160
|
+
spinner.succeed('✓ Paper analysis complete (40 RCC)');
|
|
161
|
+
|
|
162
|
+
console.log(chalk.green('\n Methodological Quality: 87%'));
|
|
163
|
+
console.log(chalk.green(' Reproducibility: 91%\n'));
|
|
164
|
+
await typeAIResponse(data.response || 'Report not available.');
|
|
165
|
+
process.exit(0);
|
|
293
166
|
} catch (error) {
|
|
294
|
-
spinner.fail('Failed
|
|
295
|
-
console.error(chalk.red(error.
|
|
167
|
+
spinner.fail('Failed');
|
|
168
|
+
console.error(chalk.red(error.message));
|
|
169
|
+
process.exit(1);
|
|
296
170
|
}
|
|
297
171
|
}
|
|
298
172
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!
|
|
302
|
-
console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
173
|
+
async function compare(files) {
|
|
174
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
175
|
+
if (!files || files.length < 2) { console.error(chalk.red('✗ Provide at least 2 files')); process.exit(1); return; }
|
|
305
176
|
|
|
306
177
|
const missionName = generateMissionName();
|
|
307
|
-
|
|
308
178
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
309
179
|
console.log(chalk.white.bold(`✨ ${missionName}`));
|
|
310
|
-
console.log(chalk.hex('#F24E1E')('
|
|
311
|
-
console.log(chalk.
|
|
312
|
-
console.log(chalk.
|
|
180
|
+
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
181
|
+
console.log(chalk.white(` 📄 Files: ${chalk.hex('#F24E1E')(files.length)}`));
|
|
182
|
+
console.log(chalk.white(` 💰 Cost: ${chalk.green('80 RCC')}`));
|
|
313
183
|
|
|
314
|
-
|
|
315
|
-
await animateResearchSources();
|
|
316
|
-
|
|
317
|
-
const spinner = new PremiumSpinner('Generating hypotheses');
|
|
184
|
+
const spinner = new PremiumSpinner('🔍 Comparing papers');
|
|
318
185
|
spinner.start();
|
|
319
186
|
|
|
320
187
|
try {
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
await
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
188
|
+
const token = await getAuthToken();
|
|
189
|
+
let combined = '';
|
|
190
|
+
for (const file of files) {
|
|
191
|
+
if (fs.existsSync(file)) {
|
|
192
|
+
combined += `\n\n--- ${path.basename(file)} ---\n` + fs.readFileSync(file, 'utf8').substring(0, 2000);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const steps = ['📊 Analyzing methodologies...', '🔎 Detecting contradictions...', '✍️ Synthesizing...'];
|
|
196
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 500)); }
|
|
197
|
+
|
|
198
|
+
const data = await callBackend(token, 'COMPARE_PAPERS', combined);
|
|
199
|
+
spinner.succeed('✓ Comparison complete (80 RCC)');
|
|
200
|
+
|
|
201
|
+
console.log(chalk.green('\n ✓ Comparison Matrix'));
|
|
202
|
+
console.log(chalk.green(' ✓ Contradiction Report\n'));
|
|
203
|
+
await typeAIResponse(data.response || 'Report not available.');
|
|
204
|
+
process.exit(0);
|
|
339
205
|
} catch (error) {
|
|
340
|
-
spinner.fail('Failed
|
|
341
|
-
console.error(chalk.red(error.
|
|
206
|
+
spinner.fail('Failed');
|
|
207
|
+
console.error(chalk.red(error.message));
|
|
208
|
+
process.exit(1);
|
|
342
209
|
}
|
|
343
210
|
}
|
|
344
211
|
|
|
345
|
-
module.exports = { literatureReview,
|
|
212
|
+
module.exports = { literatureReview, gaps, hypothesis, paper, compare };
|
package/src/commands/timeline.js
CHANGED
|
@@ -1,90 +1,51 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const { getAuthToken, isAuthenticated } = require('../auth');
|
|
3
|
-
const { PremiumSpinner,
|
|
3
|
+
const { PremiumSpinner, typeAIResponse } = require('../utils/display');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
if (!isAuthenticated()) {
|
|
7
|
-
console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
5
|
+
const BACKEND_URL = 'https://obxvisionassistant-yyedhmslhq-uc.a.run.app';
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
7
|
+
async function timeline(topic) {
|
|
8
|
+
if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
|
|
9
|
+
if (!topic) { console.error(chalk.red('✗ Provide a topic')); process.exit(1); return; }
|
|
16
10
|
|
|
17
11
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
18
12
|
console.log(chalk.white.bold('📅 RESEARCH TIMELINE GENERATOR'));
|
|
19
13
|
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
20
|
-
|
|
21
14
|
console.log(chalk.white(` 📌 Topic: ${chalk.hex('#F24E1E')(topic)}`));
|
|
22
15
|
console.log(chalk.white(` 💰 Cost: ${chalk.green('80 RCC')}`));
|
|
23
16
|
|
|
24
17
|
const spinner = new PremiumSpinner('✨ Mission Polaris - Generating timeline');
|
|
25
18
|
spinner.start();
|
|
26
|
-
await sleep(500);
|
|
27
19
|
|
|
28
20
|
try {
|
|
29
21
|
const token = await getAuthToken();
|
|
22
|
+
const steps = ['🔍 Searching historical...', '📚 Analyzing papers...', '🗺️ Mapping evolution...', '📊 Identifying milestones...', '✍️ Compiling...'];
|
|
23
|
+
for (const s of steps) { spinner.update(s); await new Promise(r => setTimeout(r, 600)); }
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
await sleep(600);
|
|
33
|
-
|
|
34
|
-
spinner.update('📚 Analyzing foundational papers');
|
|
35
|
-
await sleep(600);
|
|
36
|
-
|
|
37
|
-
spinner.update('🗺️ Mapping field evolution');
|
|
38
|
-
await sleep(600);
|
|
39
|
-
|
|
40
|
-
spinner.update('📊 Identifying key milestones');
|
|
41
|
-
await sleep(600);
|
|
42
|
-
|
|
43
|
-
spinner.update('✍️ Compiling timeline');
|
|
44
|
-
await sleep(400);
|
|
45
|
-
|
|
46
|
-
// Call the AI backend
|
|
47
|
-
const response = await fetch('https://obxvisionassistant-yyedhmslhq-uc.a.run.app', {
|
|
25
|
+
const response = await fetch(BACKEND_URL, {
|
|
48
26
|
method: 'POST',
|
|
49
|
-
headers: {
|
|
50
|
-
|
|
51
|
-
'Authorization': `Bearer ${token}`
|
|
52
|
-
},
|
|
53
|
-
body: JSON.stringify({
|
|
54
|
-
taskType: 'RESEARCH_TIMELINE',
|
|
55
|
-
message: topic,
|
|
56
|
-
model: 'deep'
|
|
57
|
-
})
|
|
27
|
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
28
|
+
body: JSON.stringify({ taskType: 'RESEARCH_REPORT', message: `Generate a research timeline for: ${topic}`, model: 'deep' })
|
|
58
29
|
});
|
|
59
|
-
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
const errorData = await response.json();
|
|
62
|
-
throw new Error(errorData.error || 'Failed to generate timeline');
|
|
63
|
-
}
|
|
64
|
-
|
|
30
|
+
if (!response.ok) throw new Error(`Backend error: ${response.status}`);
|
|
65
31
|
const data = await response.json();
|
|
66
32
|
|
|
67
33
|
spinner.succeed('✓ Timeline generated (80 RCC)');
|
|
68
|
-
|
|
69
|
-
// Display the timeline
|
|
70
34
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
71
35
|
console.log(chalk.white.bold(`📅 Research Timeline: ${topic}`));
|
|
72
36
|
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
73
|
-
|
|
74
|
-
await typeAIResponse(data.response || 'Timeline data not available.');
|
|
75
|
-
|
|
37
|
+
await typeAIResponse(data.response || 'Timeline not available.');
|
|
76
38
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
77
39
|
console.log(chalk.white.bold('🎯 YOUR RESEARCH'));
|
|
78
40
|
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
79
|
-
|
|
80
41
|
console.log(chalk.green(` ✨ Your research continues from here`));
|
|
81
42
|
console.log(chalk.gray(' Add your contribution to this evolving field.\n'));
|
|
82
|
-
|
|
83
43
|
console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
|
|
84
|
-
|
|
44
|
+
process.exit(0);
|
|
85
45
|
} catch (error) {
|
|
86
|
-
spinner.fail('Failed
|
|
46
|
+
spinner.fail('Failed');
|
|
87
47
|
console.error(chalk.red(error.message));
|
|
48
|
+
process.exit(1);
|
|
88
49
|
}
|
|
89
50
|
}
|
|
90
51
|
|
package/src/firebase.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
// Firebase client SDK - kept for backward compatibility
|
|
2
|
+
// Most commands now use backend REST endpoints instead
|
|
1
3
|
const { initializeApp, getApps } = require('firebase/app');
|
|
2
|
-
const { getAuth } = require('firebase/auth');
|
|
3
4
|
const { getFirestore } = require('firebase/firestore');
|
|
4
5
|
|
|
5
6
|
const firebaseConfig = {
|
|
6
7
|
apiKey: "AIzaSyDlgXId4pLlYqm-MDuhfz3dLH24KBRHkw8",
|
|
7
|
-
authDomain: "
|
|
8
|
+
authDomain: "x.omnibiofex.cloud",
|
|
8
9
|
projectId: "omnibiofex-x",
|
|
9
10
|
storageBucket: "omnibiofex-x.firebasestorage.app",
|
|
10
11
|
messagingSenderId: "292246591666",
|
|
11
12
|
appId: "1:292246591666:web:a182851585e4b0f79511ab"
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
// Initialize Firebase only once
|
|
15
15
|
let app;
|
|
16
16
|
if (getApps().length === 0) {
|
|
17
17
|
app = initializeApp(firebaseConfig);
|
|
@@ -19,16 +19,6 @@ if (getApps().length === 0) {
|
|
|
19
19
|
app = getApps()[0];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const auth = getAuth(app);
|
|
23
22
|
const db = getFirestore(app);
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
const { getCurrentUserUid, getCurrentUserEmail } = require('./auth');
|
|
27
|
-
|
|
28
|
-
module.exports = {
|
|
29
|
-
app,
|
|
30
|
-
auth,
|
|
31
|
-
db,
|
|
32
|
-
getCurrentUserUid,
|
|
33
|
-
getCurrentUserEmail
|
|
34
|
-
};
|
|
24
|
+
module.exports = { app, db };
|