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.
@@ -1,147 +1,243 @@
1
1
  const chalk = require('chalk');
2
2
  const inquirer = require('inquirer');
3
- const { createMission } = require('../api');
4
- const { isAuthenticated } = require('../auth');
5
- const {
6
- generateMissionName,
7
- showPlanningPhase,
8
- displayMissionDashboard,
9
- animateProgressBar,
10
- PremiumSpinner,
11
- sleep
12
- } = require('../utils/display');
3
+ const { getAuthToken, isAuthenticated } = require('../auth');
4
+ const { PremiumSpinner, sleep, typeAIResponse } = require('../utils/display');
5
+
6
+ const BACKEND_URL = 'https://obxvisionassistant-yyedhmslhq-uc.a.run.app';
7
+ const GET_USER_DATA_URL = 'https://getuserdata-yyedhmslhq-uc.a.run.app';
8
+
9
+ const RCC_COSTS = {
10
+ QUICK_RESEARCH: 10,
11
+ DEEP_RESEARCH: 50,
12
+ LITERATURE_REVIEW: 100,
13
+ MULTI_AGENT: 150
14
+ };
15
+
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
+ ];
21
+
22
+ function generateMissionName() {
23
+ return `Mission ${MISSION_NAMES[Math.floor(Math.random() * MISSION_NAMES.length)]}`;
24
+ }
25
+
26
+ // ✅ Helper: Fetch user data from backend
27
+ async function fetchUserData(token) {
28
+ const response = await fetch(GET_USER_DATA_URL, {
29
+ headers: { 'Authorization': `Bearer ${token}` }
30
+ });
31
+ if (!response.ok) {
32
+ const err = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
33
+ throw new Error(err.error || `Backend returned ${response.status}`);
34
+ }
35
+ return await response.json();
36
+ }
13
37
 
14
38
  async function missionCreate() {
15
39
  if (!isAuthenticated()) {
16
40
  console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
41
+ process.exit(1);
17
42
  return;
18
43
  }
19
44
 
20
- console.log(chalk.hex('#F24E1E').bold('\n🎯 Create New Research Mission\n'));
45
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
46
+ console.log(chalk.white.bold('🎯 CREATE RESEARCH MISSION'));
47
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
21
48
 
22
49
  const answers = await inquirer.prompt([
50
+ { type: 'input', name: 'topic', message: 'Research topic:', validate: (i) => i.length > 0 || 'Required' },
23
51
  {
24
- type: 'input',
25
- name: 'topic',
26
- message: 'Research topic:',
27
- validate: (input) => input.length > 0 || 'Topic is required'
28
- },
29
- {
30
- type: 'list',
31
- name: 'depth',
32
- message: 'Research depth:',
52
+ type: 'list', name: 'depth', message: 'Research depth:',
33
53
  choices: [
34
- { name: 'Quick (10 RCC)', value: 'QUICK_RESEARCH' },
35
- { name: 'Deep (50 RCC)', value: 'DEEP_RESEARCH' },
54
+ { name: 'Quick Research (10 RCC)', value: 'QUICK_RESEARCH' },
55
+ { name: 'Deep Research (50 RCC)', value: 'DEEP_RESEARCH' },
36
56
  { name: 'Literature Review (100 RCC)', value: 'LITERATURE_REVIEW' },
37
57
  { name: 'Academic (150 RCC)', value: 'MULTI_AGENT' }
38
58
  ]
39
59
  }
40
60
  ]);
41
61
 
62
+ const cost = RCC_COSTS[answers.depth] || 10;
42
63
  const missionName = generateMissionName();
43
64
 
44
- console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
45
- console.log(chalk.white.bold(`✨ ${missionName}`));
46
- console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════'));
47
- console.log(chalk.gray(`Topic: ${answers.topic}`));
48
- console.log(chalk.gray(`Depth: ${answers.depth}\n`));
65
+ console.log(chalk.hex('#F24E1E')(`\n✨ ${missionName}`));
49
66
 
50
- // Planning phase animation
51
- await showPlanningPhase(answers.topic);
67
+ const steps = [
68
+ '🧠 Planning Mission...', '✓ Understanding objective', '✓ Building execution graph',
69
+ '✓ Selecting research agents', '✓ Choosing inference engines', '✓ Searching literature',
70
+ '✓ Finding datasets', '✓ Mapping timeline', '✓ Planning validation'
71
+ ];
52
72
 
53
- const { start } = await inquirer.prompt([
54
- {
55
- type: 'confirm',
56
- name: 'start',
57
- message: 'Begin mission?',
58
- default: true
59
- }
60
- ]);
73
+ for (const step of steps) { console.log(chalk.white(step)); await sleep(300); }
61
74
 
62
- if (!start) {
63
- console.log(chalk.yellow('Mission cancelled.'));
64
- return;
65
- }
75
+ const { start } = await inquirer.prompt([{
76
+ type: 'confirm', name: 'start', message: 'Begin mission?', default: true
77
+ }]);
78
+
79
+ if (!start) { console.log(chalk.yellow('Mission cancelled.')); process.exit(0); return; }
66
80
 
67
- const spinner = new PremiumSpinner('Initializing mission');
81
+ const spinner = new PremiumSpinner('Creating mission');
68
82
  spinner.start();
69
83
 
70
84
  try {
71
- spinner.update('Creating mission');
72
- const result = await createMission(answers.topic, answers.depth, answers.depth);
85
+ const token = await getAuthToken();
86
+ spinner.update('Calling AI backend');
73
87
 
74
- spinner.succeed('Mission initialized');
75
-
76
- await displayMissionDashboard({
77
- name: missionName,
78
- status: 'Running',
79
- progress: 0,
80
- papers: 0,
81
- patents: 0,
82
- datasets: 0,
83
- contradictions: 0,
84
- hypotheses: 0,
85
- estimatedTime: result.estimatedTime || '18 minutes'
88
+ const response = await fetch(BACKEND_URL, {
89
+ method: 'POST',
90
+ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
91
+ body: JSON.stringify({ taskType: answers.depth, message: answers.topic, model: 'deep' })
86
92
  });
93
+
94
+ if (!response.ok) {
95
+ const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
96
+ throw new Error(errorData.error || `Backend returned ${response.status}`);
97
+ }
98
+
99
+ const data = await response.json();
100
+ spinner.succeed('✓ Mission completed');
101
+
102
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
103
+ console.log(chalk.white.bold(`📊 ${missionName} - Completed`));
104
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
105
+
106
+ console.log(chalk.white(` 📌 Topic: ${chalk.hex('#F24E1E')(answers.topic)}`));
107
+ console.log(chalk.white(` ⛽ RCC Cost: ${chalk.green(cost + ' RCC')}`));
108
+ console.log(chalk.white(` 🤖 Model: ${chalk.gray(data.model || 'Deep Reasoning Engine™')}`));
109
+ console.log(chalk.white(` 💳 Balance: ${chalk.gray((data.rccBalance || 0).toLocaleString()) + ' RCC'}`));
110
+
111
+ console.log(chalk.white.bold('\n\n📄 Research Report'));
112
+ console.log(chalk.gray('─'.repeat(60)));
113
+ await typeAIResponse(data.response || 'Report not available.');
114
+
115
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
116
+ console.log(chalk.white.bold('📦 ARTIFACTS GENERATED'));
117
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
87
118
 
88
- console.log(chalk.gray(`Mission ID: ${result.uid}`));
89
- console.log(chalk.gray(`RCC Cost: ${result.rccCost}`));
90
- console.log(chalk.gray(`Remaining Balance: ${result.rccBalance} RCC`));
91
- console.log(chalk.hex('#F24E1E')('\nMission started. We\'ll notify you when complete.'));
92
- console.log(chalk.gray('Check status: ') + chalk.white('obx mission status\n'));
93
-
119
+ console.log(chalk.green(' ✓ Literature Review'));
120
+ console.log(chalk.green(' ✓ Research Timeline'));
121
+ console.log(chalk.green(' ✓ Gap Analysis'));
122
+ console.log(chalk.green(' Citation Database'));
123
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
124
+ console.log(chalk.gray('Next steps: obx publish | obx earnings | obx mission status\n'));
125
+ process.exit(0);
126
+
94
127
  } catch (error) {
95
128
  spinner.fail('Failed to create mission');
96
- console.error(chalk.red(error.response?.data?.error || error.message));
129
+ console.error(chalk.red(error.message));
130
+ process.exit(1);
97
131
  }
98
132
  }
99
133
 
100
134
  async function missionStatus() {
101
- if (!isAuthenticated()) {
102
- console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
103
- return;
104
- }
105
-
106
- console.log(chalk.hex('#F24E1E').bold('\n📊 Active Missions\n'));
107
-
108
- // Simulate a mission for demo
109
- await displayMissionDashboard({
110
- name: 'Mission Atlas',
111
- status: 'Running',
112
- progress: 52,
113
- papers: 243,
114
- patents: 12,
115
- datasets: 8,
116
- contradictions: 5,
117
- hypotheses: 3,
118
- estimatedTime: '11 minutes'
119
- });
135
+ if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
120
136
 
121
- console.log(chalk.gray('No additional active missions.\n'));
137
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
138
+ console.log(chalk.white.bold('📊 ACTIVE MISSIONS'));
139
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
140
+
141
+ const spinner = new PremiumSpinner('Fetching missions');
142
+ spinner.start();
143
+
144
+ try {
145
+ const token = await getAuthToken();
146
+ const userData = await fetchUserData(token);
147
+ spinner.succeed('Missions loaded');
148
+
149
+ const active = userData.missions.filter(m => m.status === 'running' || m.status === 'pending');
150
+
151
+ if (active.length === 0) {
152
+ console.log(chalk.yellow(' No active missions.\n'));
153
+ console.log(chalk.gray(' Create one with: obx mission create\n'));
154
+ } else {
155
+ active.forEach((m, i) => {
156
+ console.log(chalk.white(`\n ${i + 1}. ${chalk.hex('#F24E1E')(m.missionName || m.id)}`));
157
+ console.log(chalk.white(` Topic: ${(m.message || '').substring(0, 50)}`));
158
+ console.log(chalk.yellow(` Status: ${m.status}`));
159
+ });
160
+ }
161
+ process.exit(0);
162
+ } catch (error) {
163
+ spinner.fail('Failed');
164
+ console.error(chalk.red(error.message));
165
+ process.exit(1);
166
+ }
122
167
  }
123
168
 
124
169
  async function missionResults() {
125
- if (!isAuthenticated()) {
126
- console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
127
- return;
128
- }
170
+ if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
171
+
172
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
173
+ console.log(chalk.white.bold('📄 COMPLETED MISSIONS'));
174
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
175
+
176
+ const spinner = new PremiumSpinner('Fetching missions');
177
+ spinner.start();
129
178
 
130
- console.log(chalk.hex('#F24E1E').bold('\n📄 Completed Missions\n'));
131
- console.log(chalk.gray('Use the web dashboard to view all reports:'));
132
- console.log(chalk.white(' https://x.omnibiofex.cloud/dash\n'));
133
- console.log(chalk.gray('Or check local reports:'));
134
- console.log(chalk.white(' ~/obx-reports/\n'));
179
+ try {
180
+ const token = await getAuthToken();
181
+ const userData = await fetchUserData(token);
182
+ spinner.succeed('Missions loaded');
183
+
184
+ const completed = userData.missions.filter(m => m.status === 'completed');
185
+
186
+ if (completed.length === 0) {
187
+ console.log(chalk.yellow(' No completed missions.\n'));
188
+ } else {
189
+ completed.forEach((m, i) => {
190
+ const pub = m.isPublished ? chalk.green('✓ Published') : chalk.gray('○ Unpublished');
191
+ console.log(chalk.white(`\n ${i + 1}. ${chalk.hex('#F24E1E')(m.missionName || m.id)} ${pub}`));
192
+ console.log(chalk.white(` Topic: ${(m.message || '').substring(0, 50)}`));
193
+ console.log(chalk.gray(` Cost: ${m.rccCost || 0} RCC`));
194
+ });
195
+ }
196
+ process.exit(0);
197
+ } catch (error) {
198
+ spinner.fail('Failed');
199
+ console.error(chalk.red(error.message));
200
+ process.exit(1);
201
+ }
135
202
  }
136
203
 
137
204
  async function missionList() {
138
- if (!isAuthenticated()) {
139
- console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
140
- return;
141
- }
205
+ if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
206
+
207
+ console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
208
+ console.log(chalk.white.bold('📋 ALL MISSIONS'));
209
+ console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
142
210
 
143
- console.log(chalk.hex('#F24E1E').bold('\n📋 All Missions\n'));
144
- console.log(chalk.gray('Total missions: Check dashboard at https://x.omnibiofex.cloud/dash\n'));
211
+ const spinner = new PremiumSpinner('Fetching missions');
212
+ spinner.start();
213
+
214
+ try {
215
+ const token = await getAuthToken();
216
+ const userData = await fetchUserData(token);
217
+ spinner.succeed('Missions loaded');
218
+
219
+ const missions = userData.missions;
220
+
221
+ if (missions.length === 0) {
222
+ console.log(chalk.yellow(' No missions yet.\n'));
223
+ console.log(chalk.gray(' Create one with: obx mission create\n'));
224
+ } else {
225
+ console.log(chalk.white(` 📊 Total: ${userData.stats.totalMissions} missions`));
226
+ console.log(chalk.green(` ✅ Completed: ${userData.stats.completed}`));
227
+ console.log(chalk.yellow(` ⏳ Active: ${userData.stats.active}`));
228
+ console.log(chalk.hex('#F24E1E')(` 📤 Published: ${userData.stats.published}\n`));
229
+
230
+ missions.forEach((m, i) => {
231
+ const c = m.status === 'completed' ? chalk.green : m.status === 'running' ? chalk.yellow : chalk.gray;
232
+ console.log(chalk.white(` ${i + 1}. ${chalk.hex('#F24E1E')(m.missionName || m.id)} ${c(`(${m.status})`)}`));
233
+ });
234
+ }
235
+ process.exit(0);
236
+ } catch (error) {
237
+ spinner.fail('Failed');
238
+ console.error(chalk.red(error.message));
239
+ process.exit(1);
240
+ }
145
241
  }
146
242
 
147
243
  module.exports = { missionCreate, missionStatus, missionResults, missionList };
@@ -1,150 +1,82 @@
1
1
  const chalk = require('chalk');
2
- const { isAuthenticated, getCurrentUserUid, getCurrentUserEmail } = require('../auth');
3
- const { db } = require('../firebase');
4
- const { PremiumSpinner, sleep } = require('../utils/display');
5
- const { collection, query, where, orderBy, limit, getDocs } = require('firebase/firestore');
2
+ const { getAuthToken, isAuthenticated } = require('../auth');
3
+ const { PremiumSpinner } = require('../utils/display');
6
4
 
7
- async function morning() {
8
- if (!isAuthenticated()) {
9
- console.error(chalk.red('✗ Not authenticated. Please run: obx login'));
10
- return;
11
- }
5
+ const GET_USER_DATA_URL = 'https://getuserdata-yyedhmslhq-uc.a.run.app';
12
6
 
13
- const uid = getCurrentUserUid();
14
- const email = getCurrentUserEmail();
15
-
16
- if (!uid) {
17
- console.error(chalk.red('✗ Could not extract user ID from token.'));
18
- console.error(chalk.gray('Please run: obx login'));
19
- return;
20
- }
7
+ async function morning() {
8
+ if (!isAuthenticated()) { console.error(chalk.red('✗ Not authenticated')); process.exit(1); return; }
21
9
 
22
- const spinner = new PremiumSpinner('☀️ Fetching your daily briefing');
10
+ const spinner = new PremiumSpinner('☀️ Fetching daily briefing');
23
11
  spinner.start();
24
12
 
25
13
  try {
26
- // Get today's date
27
- const today = new Date();
28
- const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate());
29
- const yesterdayStart = new Date(todayStart);
30
- yesterdayStart.setDate(yesterdayStart.getDate() - 1);
31
-
32
- // Fetch active missions
33
- const activeQuery = query(
34
- collection(db, 'missions'),
35
- where('uid', '==', uid),
36
- where('status', 'in', ['running', 'pending'])
37
- );
38
-
39
- const activeSnapshot = await getDocs(activeQuery);
40
- const activeMissions = [];
41
- activeSnapshot.forEach(doc => {
42
- activeMissions.push({ id: doc.id, ...doc.data() });
14
+ const token = await getAuthToken();
15
+ const response = await fetch(GET_USER_DATA_URL, {
16
+ headers: { 'Authorization': `Bearer ${token}` }
43
17
  });
44
-
45
- // Fetch recent completed missions (last 7 days)
46
- const sevenDaysAgo = new Date();
47
- sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
18
+ if (!response.ok) throw new Error(`Backend error: ${response.status}`);
19
+ const userData = await response.json();
48
20
 
49
- const recentQuery = query(
50
- collection(db, 'missions'),
51
- where('uid', '==', uid),
52
- where('status', '==', 'completed'),
53
- orderBy('createdAt', 'desc'),
54
- limit(10)
55
- );
56
-
57
- const recentSnapshot = await getDocs(recentQuery);
58
- const recentMissions = [];
59
- recentSnapshot.forEach(doc => {
60
- recentMissions.push({ id: doc.id, ...doc.data() });
61
- });
62
-
63
- // Fetch published missions for earnings
64
- const publishedQuery = query(
65
- collection(db, 'missions'),
66
- where('uid', '==', uid),
67
- where('isPublished', '==', true)
68
- );
69
-
70
- const publishedSnapshot = await getDocs(publishedQuery);
71
- const publishedMissions = [];
72
- publishedSnapshot.forEach(doc => {
73
- publishedMissions.push({ id: doc.id, ...doc.data() });
74
- });
75
-
76
- const totalViews = publishedMissions.reduce((sum, m) => sum + (m.views || 0), 0);
77
- const totalEarnings = publishedMissions.reduce((sum, m) => sum + (m.earnings || 0), 0);
78
-
79
21
  spinner.succeed('Daily briefing loaded');
80
-
81
- // Display the briefing
82
- const dateString = today.toLocaleDateString('en-US', {
83
- weekday: 'long',
84
- year: 'numeric',
85
- month: 'long',
86
- day: 'numeric'
22
+
23
+ const today = new Date().toLocaleDateString('en-US', {
24
+ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
87
25
  });
26
+
27
+ const active = userData.missions.filter(m => m.status === 'running' || m.status === 'pending');
28
+ const recent = userData.missions.filter(m => m.status === 'completed').slice(0, 5);
29
+ const published = userData.missions.filter(m => m.isPublished === true);
88
30
 
89
31
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
90
32
  console.log(chalk.white.bold('☀️ GOOD MORNING, RESEARCHER!'));
91
33
  console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
92
-
93
- console.log(chalk.gray(` 👤 ${chalk.white(email || 'Unknown')}`));
94
- console.log(chalk.gray(` 📅 ${chalk.white(dateString)}`));
34
+ console.log(chalk.gray(` 👤 ${chalk.white(userData.user.name || userData.user.email)}`));
35
+ console.log(chalk.gray(` 📅 ${chalk.white(today)}`));
95
36
 
96
- // Active Missions
97
- if (activeMissions.length > 0) {
37
+ if (active.length > 0) {
98
38
  console.log(chalk.white.bold('\n\n🎯 ACTIVE MISSIONS'));
99
39
  console.log(chalk.gray('─'.repeat(60)));
100
-
101
- activeMissions.forEach((m, i) => {
102
- const topic = (m.message || 'No topic').substring(0, 50);
103
- console.log(chalk.white(`\n ✨ ${chalk.hex('#F24E1E')(m.id)}`));
104
- console.log(chalk.white(` Topic: ${topic}`));
40
+ active.forEach(m => {
41
+ console.log(chalk.white(`\n ✨ ${chalk.hex('#F24E1E')(m.missionName || m.id)}`));
42
+ console.log(chalk.white(` Topic: ${(m.message || '').substring(0, 50)}`));
105
43
  console.log(chalk.yellow(` Status: ${m.status}`));
106
44
  });
107
45
  }
108
46
 
109
- // Recent Completions
110
- if (recentMissions.length > 0) {
47
+ if (recent.length > 0) {
111
48
  console.log(chalk.white.bold('\n\n✅ RECENTLY COMPLETED'));
112
49
  console.log(chalk.gray('─'.repeat(60)));
113
-
114
- recentMissions.slice(0, 5).forEach((m, i) => {
115
- const topic = (m.message || 'No topic').substring(0, 50);
116
- const date = m.createdAt?.toDate?.().toLocaleDateString() || 'N/A';
117
- console.log(chalk.white(`\n ${i + 1}. ${topic}`));
50
+ recent.forEach((m, i) => {
51
+ const date = m.createdAt ? new Date(m.createdAt).toLocaleDateString() : 'N/A';
52
+ console.log(chalk.white(`\n ${i + 1}. ${(m.message || '').substring(0, 50)}`));
118
53
  console.log(chalk.gray(` Completed: ${date}`));
119
54
  });
120
55
  }
121
56
 
122
- // Earnings Summary
123
- if (publishedMissions.length > 0) {
57
+ if (published.length > 0) {
124
58
  console.log(chalk.white.bold('\n\n💰 EARNINGS SUMMARY'));
125
59
  console.log(chalk.gray('─'.repeat(60)));
126
-
127
- console.log(chalk.white(`\n 📤 Published Research: ${chalk.green(publishedMissions.length)}`));
128
- console.log(chalk.white(` 👁 Total Views: ${chalk.green(totalViews.toLocaleString())}`));
129
- console.log(chalk.white(` 💰 Total Earnings: ${chalk.green('₹' + totalEarnings.toLocaleString())}`));
60
+ console.log(chalk.white(`\n 📤 Published: ${chalk.green(published.length)}`));
61
+ console.log(chalk.white(` 👁 Views: ${chalk.green(userData.stats.totalViews.toLocaleString())}`));
62
+ console.log(chalk.white(` 💰 Earnings: ${chalk.green('₹' + userData.stats.totalEarnings.toLocaleString())}`));
130
63
  }
131
64
 
132
- // Recommendations
133
65
  console.log(chalk.white.bold('\n\n💡 RECOMMENDATIONS'));
134
66
  console.log(chalk.gray('─'.repeat(60)));
135
-
136
- console.log(chalk.white('\nCheck active missions with "obx mission status"'));
137
- console.log(chalk.white(' ▸ Publish completed research with "obx publish"'));
138
- console.log(chalk.white(' ▸ View earnings with "obx earnings"'));
139
- console.log(chalk.white(' ▸ Generate new research with "obx mission create"'));
67
+ console.log(chalk.white('\n ▸ Check missions: "obx mission status"'));
68
+ console.log(chalk.white(' ▸ Publish research: "obx publish"'));
69
+ console.log(chalk.white(' ▸ View earnings: "obx earnings"'));
70
+ console.log(chalk.white(' ▸ New research: "obx mission create"'));
140
71
 
141
72
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
142
73
  console.log(chalk.gray('Free • No RCC cost'));
143
74
  console.log(chalk.hex('#F24E1E')('═══════════════════════════════════════════════════════════\n'));
144
-
75
+ process.exit(0);
145
76
  } catch (error) {
146
- spinner.fail('Failed to fetch daily briefing');
77
+ spinner.fail('Failed to fetch briefing');
147
78
  console.error(chalk.red(error.message));
79
+ process.exit(1);
148
80
  }
149
81
  }
150
82
 
@@ -2,48 +2,36 @@ const chalk = require('chalk');
2
2
  const open = require('open');
3
3
  const inquirer = require('inquirer');
4
4
 
5
- async function openPage(page) {
6
- const pages = {
7
- 'dashboard': { url: 'https://x.omnibiofex.cloud/dash', name: 'Web Dashboard' },
8
- 'earn': { url: 'https://x.omnibiofex.cloud/earn', name: 'How to Earn' },
9
- 'pricing': { url: 'https://x.omnibiofex.cloud/pricing', name: 'Pricing Plans' },
10
- 'agents': { url: 'https://x.omnibiofex.cloud/agents', name: 'AI Agents' },
11
- 'how-it-works': { url: 'https://x.omnibiofex.cloud/how-it-works', name: 'How It Works' },
12
- 'commands': { url: 'https://x.omnibiofex.cloud/commands', name: 'Commands Reference' },
13
- 'cli-guide': { url: 'https://x.omnibiofex.cloud/cli-guide', name: 'CLI Guide' },
14
- 'auth': { url: 'https://x.omnibiofex.cloud/auth', name: 'Authentication' },
15
- 'home': { url: 'https://x.omnibiofex.cloud/', name: 'Home Page' }
16
- };
5
+ const pages = {
6
+ 'dashboard': { url: 'https://x.omnibiofex.cloud/dash', name: 'Web Dashboard' },
7
+ 'earn': { url: 'https://x.omnibiofex.cloud/earn', name: 'How to Earn' },
8
+ 'pricing': { url: 'https://x.omnibiofex.cloud/pricing', name: 'Pricing Plans' },
9
+ 'agents': { url: 'https://x.omnibiofex.cloud/agents', name: 'AI Agents' },
10
+ 'how-it-works': { url: 'https://x.omnibiofex.cloud/how-it-works', name: 'How It Works' },
11
+ 'commands': { url: 'https://x.omnibiofex.cloud/commands', name: 'Commands Reference' },
12
+ 'cli-guide': { url: 'https://x.omnibiofex.cloud/cli-guide', name: 'CLI Guide' },
13
+ 'home': { url: 'https://x.omnibiofex.cloud/', name: 'Home Page' }
14
+ };
17
15
 
16
+ async function openPage(page) {
18
17
  if (!page) {
19
- const { selectedPage } = await inquirer.prompt([
20
- {
21
- type: 'list',
22
- name: 'selectedPage',
23
- message: 'Which page would you like to open?',
24
- choices: [
25
- { name: '🏠 Home Page', value: 'home' },
26
- { name: '📊 Web Dashboard', value: 'dashboard' },
27
- { name: '💰 How to Earn', value: 'earn' },
28
- { name: '💳 Pricing Plans', value: 'pricing' },
29
- { name: '🤖 AI Agents', value: 'agents' },
30
- { name: '📖 How It Works', value: 'how-it-works' },
31
- { name: '⌨️ Commands Reference', value: 'commands' },
32
- { name: '📘 CLI Guide', value: 'cli-guide' }
33
- ]
34
- }
35
- ]);
18
+ const { selectedPage } = await inquirer.prompt([{
19
+ type: 'list', name: 'selectedPage', message: 'Which page?',
20
+ choices: [
21
+ { name: '🏠 Home', value: 'home' }, { name: '📊 Dashboard', value: 'dashboard' },
22
+ { name: '💰 Earn', value: 'earn' }, { name: '💳 Pricing', value: 'pricing' },
23
+ { name: '🤖 Agents', value: 'agents' }, { name: '📖 How It Works', value: 'how-it-works' },
24
+ { name: '⌨️ Commands', value: 'commands' }, { name: '📘 CLI Guide', value: 'cli-guide' }
25
+ ]
26
+ }]);
36
27
  page = selectedPage;
37
28
  }
38
29
 
39
30
  const pageInfo = pages[page];
40
-
41
31
  if (!pageInfo) {
42
32
  console.error(chalk.red(`✗ Unknown page: ${page}`));
43
- console.log(chalk.gray('\nAvailable pages:'));
44
- Object.keys(pages).forEach(key => {
45
- console.log(chalk.gray(` • ${key}`));
46
- });
33
+ console.log(chalk.gray('\nAvailable: ' + Object.keys(pages).join(', ') + '\n'));
34
+ process.exit(1);
47
35
  return;
48
36
  }
49
37
 
@@ -52,10 +40,12 @@ async function openPage(page) {
52
40
 
53
41
  try {
54
42
  await open(pageInfo.url);
55
- console.log(chalk.green(`✓ Opened ${pageInfo.name} in your browser\n`));
43
+ console.log(chalk.green(`✓ Opened ${pageInfo.name}\n`));
44
+ process.exit(0);
56
45
  } catch (error) {
57
46
  console.error(chalk.red('✗ Failed to open browser'));
58
- console.log(chalk.gray(`\nPlease visit manually: ${pageInfo.url}\n`));
47
+ console.log(chalk.gray(`\nVisit: ${pageInfo.url}\n`));
48
+ process.exit(1);
59
49
  }
60
50
  }
61
51