omnibiofex 4.1.0 → 4.3.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/package.json +1 -1
- package/src/commands/diagram.js +172 -177
package/package.json
CHANGED
package/src/commands/diagram.js
CHANGED
|
@@ -13,186 +13,170 @@ if (!fs.existsSync(DIAGRAMS_DIR)) {
|
|
|
13
13
|
fs.mkdirSync(DIAGRAMS_DIR, { recursive: true });
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
// Diagram styles
|
|
16
|
+
// Diagram styles with costs
|
|
17
17
|
const STYLES = {
|
|
18
|
-
minimal: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
detailed: {
|
|
24
|
-
name: 'Detailed',
|
|
25
|
-
cost: 80,
|
|
26
|
-
description: 'Comprehensive ecosystem with all components'
|
|
27
|
-
},
|
|
28
|
-
flowchart: {
|
|
29
|
-
name: 'Flowchart',
|
|
30
|
-
cost: 60,
|
|
31
|
-
description: 'Step-by-step process flow'
|
|
32
|
-
},
|
|
33
|
-
network: {
|
|
34
|
-
name: 'Network',
|
|
35
|
-
cost: 70,
|
|
36
|
-
description: 'Interconnected nodes and relationships'
|
|
37
|
-
}
|
|
18
|
+
minimal: { name: 'Minimal', cost: 50, description: 'Clean, simple flowchart' },
|
|
19
|
+
detailed: { name: 'Detailed', cost: 80, description: 'Comprehensive ecosystem' },
|
|
20
|
+
flowchart: { name: 'Flowchart', cost: 60, description: 'Step-by-step process' },
|
|
21
|
+
network: { name: 'Network', cost: 70, description: 'Interconnected nodes' }
|
|
38
22
|
};
|
|
39
23
|
|
|
40
|
-
// Generate ASCII
|
|
41
|
-
function
|
|
42
|
-
const
|
|
24
|
+
// Generate ASCII banner (single line)
|
|
25
|
+
function banner(title, width = 80) {
|
|
26
|
+
const safeTitle = (title || 'DIAGRAM').substring(0, width - 4);
|
|
27
|
+
const padding = width - safeTitle.length - 4;
|
|
43
28
|
const leftPad = Math.floor(padding / 2);
|
|
44
29
|
const rightPad = padding - leftPad;
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Generate ASCII banner
|
|
49
|
-
function banner(title, width = 80) {
|
|
50
|
-
const top = `╔${'═'.repeat(width)}╗`;
|
|
51
|
-
const bottom = `╚${'═'.repeat(width)}╝`;
|
|
52
|
-
const content = box(title, width);
|
|
53
|
-
return `${top}\n${content}\n${bottom}`;
|
|
30
|
+
return `╔${'═'.repeat(width)}╗\n║ ${' '.repeat(leftPad)}${safeTitle}${' '.repeat(rightPad)} ║\n╚${'═'.repeat(width)}╝`;
|
|
54
31
|
}
|
|
55
32
|
|
|
56
|
-
// Generate node
|
|
57
|
-
function
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const padding = Math.max(0, width - text.length - 2);
|
|
33
|
+
// Generate single-line node
|
|
34
|
+
function nodeLine(text, width = 40) {
|
|
35
|
+
const safeText = (text || '').substring(0, width - 4);
|
|
36
|
+
const padding = width - safeText.length - 4;
|
|
61
37
|
const leftPad = Math.floor(padding / 2);
|
|
62
38
|
const rightPad = padding - leftPad;
|
|
63
|
-
|
|
64
|
-
return `${top}\n${content}\n${bottom}`;
|
|
39
|
+
return `┌${'─'.repeat(width)}┐\n│ ${' '.repeat(leftPad)}${safeText}${' '.repeat(rightPad)} │\n└${'─'.repeat(width)}┘`;
|
|
65
40
|
}
|
|
66
41
|
|
|
67
42
|
// Generate arrow
|
|
68
|
-
function arrow(
|
|
69
|
-
|
|
70
|
-
case 'down': return '│\n▼';
|
|
71
|
-
case 'right': return '───▶';
|
|
72
|
-
case 'left': return '◀───';
|
|
73
|
-
case 'up': return '▲\n│';
|
|
74
|
-
default: return '│\n▼';
|
|
75
|
-
}
|
|
43
|
+
function arrow() {
|
|
44
|
+
return '│\n▼';
|
|
76
45
|
}
|
|
77
46
|
|
|
78
|
-
// Generate
|
|
79
|
-
function
|
|
47
|
+
// Generate detailed diagram (vertical layout)
|
|
48
|
+
function generateDetailedDiagram(topic, data) {
|
|
80
49
|
const width = 60;
|
|
81
|
-
let
|
|
50
|
+
let lines = [];
|
|
82
51
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
diagram += `${' '.repeat(29)}${arrow('down')}\n`;
|
|
52
|
+
lines.push(banner(`${topic.toUpperCase()} RESEARCH ECOSYSTEM`, width));
|
|
53
|
+
lines.push('');
|
|
86
54
|
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
diagram += `${' '.repeat(10)}${node('Analysis', 20)}\n`;
|
|
91
|
-
diagram += `${' '.repeat(19)}${arrow('down')}\n`;
|
|
92
|
-
diagram += `${' '.repeat(10)}${node('Solution', 20)}\n`;
|
|
55
|
+
// Problem
|
|
56
|
+
lines.push(nodeLine('Research Problem', width));
|
|
57
|
+
lines.push(arrow());
|
|
93
58
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
function generateDetailedDiagram(topic, components) {
|
|
99
|
-
const width = 80;
|
|
100
|
-
let diagram = banner(`${topic.toUpperCase()} RESEARCH ECOSYSTEM`, width) + '\n\n';
|
|
59
|
+
// Input sources (vertical list)
|
|
60
|
+
const sources = (data.components && data.components.length > 0)
|
|
61
|
+
? data.components.slice(0, 3)
|
|
62
|
+
: ['Literature Review', 'Data Collection', 'Theory Analysis'];
|
|
101
63
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
64
|
+
lines.push(nodeLine('Input Sources', width));
|
|
65
|
+
lines.push(arrow());
|
|
66
|
+
sources.forEach(source => {
|
|
67
|
+
lines.push(` • ${source}`);
|
|
68
|
+
});
|
|
69
|
+
lines.push(arrow());
|
|
105
70
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
diagram += `${' '.repeat(15)}\\ | /\n`;
|
|
110
|
-
diagram += `${' '.repeat(16)}\\ | /\n`;
|
|
111
|
-
diagram += `${' '.repeat(17)}▼ ▼ ▼\n`;
|
|
112
|
-
diagram += `${' '.repeat(15)}${node('Integration Layer', 30)}\n`;
|
|
113
|
-
diagram += `${' '.repeat(29)}${arrow('down')}\n`;
|
|
71
|
+
// Integration
|
|
72
|
+
lines.push(nodeLine('Integration Layer', width));
|
|
73
|
+
lines.push(arrow());
|
|
114
74
|
|
|
115
75
|
// Analysis phase
|
|
116
|
-
|
|
117
|
-
|
|
76
|
+
lines.push(nodeLine('Analysis Phase', width));
|
|
77
|
+
lines.push(arrow());
|
|
118
78
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
79
|
+
const methods = (data.methods && data.methods.length > 0)
|
|
80
|
+
? data.methods.slice(0, 4)
|
|
81
|
+
: ['Statistical Analysis', 'Qualitative Review', 'Comparative Study', 'Predictive Modeling'];
|
|
82
|
+
|
|
83
|
+
lines.push(nodeLine('Methods', width));
|
|
84
|
+
lines.push(arrow());
|
|
85
|
+
methods.forEach(method => {
|
|
86
|
+
lines.push(` • ${method}`);
|
|
87
|
+
});
|
|
88
|
+
lines.push(arrow());
|
|
89
|
+
|
|
90
|
+
// Synthesis
|
|
91
|
+
lines.push(nodeLine('Synthesis & Insights', width));
|
|
92
|
+
lines.push(arrow());
|
|
127
93
|
|
|
128
94
|
// Output phase
|
|
129
|
-
|
|
130
|
-
|
|
95
|
+
lines.push(nodeLine('Output Phase', width));
|
|
96
|
+
lines.push(arrow());
|
|
97
|
+
|
|
98
|
+
const outputs = (data.outputs && data.outputs.length > 0)
|
|
99
|
+
? data.outputs.slice(0, 3)
|
|
100
|
+
: ['Publication', 'Implementation', 'Future Work'];
|
|
131
101
|
|
|
132
|
-
|
|
133
|
-
|
|
102
|
+
lines.push(nodeLine('Outputs', width));
|
|
103
|
+
lines.push(arrow());
|
|
104
|
+
outputs.forEach(output => {
|
|
105
|
+
lines.push(` • ${output}`);
|
|
106
|
+
});
|
|
134
107
|
|
|
135
|
-
return
|
|
108
|
+
return lines.join('\n');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Generate minimal diagram
|
|
112
|
+
function generateMinimalDiagram(topic, data) {
|
|
113
|
+
const width = 50;
|
|
114
|
+
let lines = [];
|
|
115
|
+
|
|
116
|
+
lines.push(banner(topic.toUpperCase(), width));
|
|
117
|
+
lines.push('');
|
|
118
|
+
lines.push(nodeLine('Problem', width));
|
|
119
|
+
lines.push(arrow());
|
|
120
|
+
lines.push(nodeLine('Research', width));
|
|
121
|
+
lines.push(arrow());
|
|
122
|
+
lines.push(nodeLine('Analysis', width));
|
|
123
|
+
lines.push(arrow());
|
|
124
|
+
lines.push(nodeLine('Solution', width));
|
|
125
|
+
|
|
126
|
+
return lines.join('\n');
|
|
136
127
|
}
|
|
137
128
|
|
|
138
129
|
// Generate flowchart diagram
|
|
139
|
-
function generateFlowchartDiagram(topic,
|
|
140
|
-
const width =
|
|
141
|
-
|
|
130
|
+
function generateFlowchartDiagram(topic, data) {
|
|
131
|
+
const width = 55;
|
|
132
|
+
const steps = (data.steps && data.steps.length > 0)
|
|
133
|
+
? data.steps
|
|
134
|
+
: ['Research', 'Analysis', 'Implementation', 'Testing', 'Deployment'];
|
|
142
135
|
|
|
143
|
-
let
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
136
|
+
let lines = [];
|
|
137
|
+
lines.push(banner(`${topic.toUpperCase()} WORKFLOW`, width));
|
|
138
|
+
lines.push('');
|
|
139
|
+
|
|
140
|
+
steps.forEach((step, i) => {
|
|
141
|
+
lines.push(nodeLine(`Step ${i + 1}: ${step}`, width));
|
|
142
|
+
if (i < steps.length - 1) {
|
|
143
|
+
lines.push(arrow());
|
|
149
144
|
}
|
|
150
|
-
|
|
151
|
-
}
|
|
145
|
+
});
|
|
152
146
|
|
|
153
|
-
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push(nodeLine('✓ Complete', width));
|
|
154
149
|
|
|
155
|
-
return
|
|
150
|
+
return lines.join('\n');
|
|
156
151
|
}
|
|
157
152
|
|
|
158
153
|
// Generate network diagram
|
|
159
|
-
function generateNetworkDiagram(topic,
|
|
160
|
-
const width =
|
|
161
|
-
|
|
154
|
+
function generateNetworkDiagram(topic, data) {
|
|
155
|
+
const width = 50;
|
|
156
|
+
const nodes = (data.nodes && data.nodes.length > 0)
|
|
157
|
+
? data.nodes.slice(0, 5)
|
|
158
|
+
: ['Component A', 'Component B', 'Component C', 'Component D', 'Component E'];
|
|
159
|
+
|
|
160
|
+
let lines = [];
|
|
161
|
+
lines.push(banner(`${topic.toUpperCase()} NETWORK`, width));
|
|
162
|
+
lines.push('');
|
|
162
163
|
|
|
163
164
|
// Central node
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
diagram += `${' '.repeat(20)}┌────────┼────────┐\n`;
|
|
167
|
-
diagram += `${' '.repeat(20)}│ │ │\n`;
|
|
168
|
-
diagram += `${' '.repeat(20)}▼ ▼ ▼\n`;
|
|
165
|
+
lines.push(nodeLine(topic, width));
|
|
166
|
+
lines.push(arrow());
|
|
169
167
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
// Connected nodes
|
|
169
|
+
lines.push(nodeLine('Connected Components', width));
|
|
170
|
+
lines.push(arrow());
|
|
171
|
+
nodes.forEach(node => {
|
|
172
|
+
lines.push(` ├─ ${node}`);
|
|
173
|
+
});
|
|
174
|
+
lines.push(arrow());
|
|
176
175
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// Generate Mermaid diagram for markdown
|
|
181
|
-
function generateMermaidDiagram(topic, components, style) {
|
|
182
|
-
let mermaid = '```mermaid\n';
|
|
183
|
-
mermaid += 'graph TD\n';
|
|
184
|
-
mermaid += ` A[${topic}] --> B[Research Phase]\n`;
|
|
185
|
-
mermaid += ` B --> C[Analysis Phase]\n`;
|
|
186
|
-
mermaid += ` C --> D[Output Phase]\n`;
|
|
176
|
+
// Integration
|
|
177
|
+
lines.push(nodeLine('Integration & Synthesis', width));
|
|
187
178
|
|
|
188
|
-
|
|
189
|
-
components.forEach((comp, i) => {
|
|
190
|
-
mermaid += ` B --> E${i}[${comp}]\n`;
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
mermaid += '```';
|
|
195
|
-
return mermaid;
|
|
179
|
+
return lines.join('\n');
|
|
196
180
|
}
|
|
197
181
|
|
|
198
182
|
// Main diagram command
|
|
@@ -205,14 +189,13 @@ async function diagram(topic, options = {}) {
|
|
|
205
189
|
|
|
206
190
|
if (!topic) {
|
|
207
191
|
console.error(chalk.red('✗ Please provide a topic'));
|
|
208
|
-
console.log(chalk.gray('Usage: obx diagram "topic" [--style minimal|detailed|flowchart|network] [--save]
|
|
192
|
+
console.log(chalk.gray('Usage: obx diagram "topic" [--style minimal|detailed|flowchart|network] [--save]'));
|
|
209
193
|
process.exit(1);
|
|
210
194
|
return;
|
|
211
195
|
}
|
|
212
196
|
|
|
213
197
|
const style = options.style || 'detailed';
|
|
214
198
|
const save = options.save || false;
|
|
215
|
-
const publish = options.publish || false;
|
|
216
199
|
const cost = STYLES[style]?.cost || 80;
|
|
217
200
|
|
|
218
201
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
|
|
@@ -229,10 +212,10 @@ async function diagram(topic, options = {}) {
|
|
|
229
212
|
try {
|
|
230
213
|
const token = await getAuthToken();
|
|
231
214
|
|
|
232
|
-
// Call AI backend to get components/structure
|
|
233
215
|
spinner.update('Analyzing topic with AI');
|
|
234
216
|
await sleep(500);
|
|
235
217
|
|
|
218
|
+
// Use DEEP_RESEARCH task type (already supported by backend)
|
|
236
219
|
const response = await fetch(BACKEND_URL, {
|
|
237
220
|
method: 'POST',
|
|
238
221
|
headers: {
|
|
@@ -240,22 +223,27 @@ async function diagram(topic, options = {}) {
|
|
|
240
223
|
'Authorization': `Bearer ${token}`
|
|
241
224
|
},
|
|
242
225
|
body: JSON.stringify({
|
|
243
|
-
taskType: '
|
|
244
|
-
message: `Generate a structured breakdown of "${topic}" for an ASCII diagram.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
226
|
+
taskType: 'DEEP_RESEARCH',
|
|
227
|
+
message: `Generate a structured breakdown of "${topic}" for an ASCII diagram.
|
|
228
|
+
|
|
229
|
+
Return ONLY a valid JSON object with this exact structure (no other text):
|
|
230
|
+
{
|
|
231
|
+
"components": ["component1", "component2", "component3"],
|
|
232
|
+
"methods": ["method1", "method2", "method3", "method4"],
|
|
233
|
+
"steps": ["step1", "step2", "step3", "step4", "step5"],
|
|
234
|
+
"nodes": ["node1", "node2", "node3", "node4", "node5"],
|
|
235
|
+
"outputs": ["output1", "output2", "output3"]
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
Make the components, methods, steps, nodes, and outputs specific to "${topic}".
|
|
239
|
+
Return ONLY the JSON object, nothing else.`,
|
|
253
240
|
model: 'deep'
|
|
254
241
|
})
|
|
255
242
|
});
|
|
256
243
|
|
|
257
244
|
if (!response.ok) {
|
|
258
|
-
|
|
245
|
+
const errorText = await response.text();
|
|
246
|
+
throw new Error(`Backend returned ${response.status}: ${errorText.substring(0, 100)}`);
|
|
259
247
|
}
|
|
260
248
|
|
|
261
249
|
spinner.update('Rendering ASCII art');
|
|
@@ -263,13 +251,26 @@ async function diagram(topic, options = {}) {
|
|
|
263
251
|
|
|
264
252
|
const data = await response.json();
|
|
265
253
|
|
|
266
|
-
// Parse AI response
|
|
267
|
-
let aiData = {
|
|
254
|
+
// Parse AI response with safe defaults
|
|
255
|
+
let aiData = {
|
|
256
|
+
components: [],
|
|
257
|
+
methods: [],
|
|
258
|
+
steps: [],
|
|
259
|
+
nodes: [],
|
|
260
|
+
outputs: []
|
|
261
|
+
};
|
|
262
|
+
|
|
268
263
|
try {
|
|
269
|
-
|
|
270
|
-
const jsonMatch =
|
|
264
|
+
const responseText = data.response || '';
|
|
265
|
+
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
|
266
|
+
|
|
271
267
|
if (jsonMatch) {
|
|
272
|
-
|
|
268
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
269
|
+
aiData.components = Array.isArray(parsed.components) ? parsed.components : [];
|
|
270
|
+
aiData.methods = Array.isArray(parsed.methods) ? parsed.methods : [];
|
|
271
|
+
aiData.steps = Array.isArray(parsed.steps) ? parsed.steps : [];
|
|
272
|
+
aiData.nodes = Array.isArray(parsed.nodes) ? parsed.nodes : [];
|
|
273
|
+
aiData.outputs = Array.isArray(parsed.outputs) ? parsed.outputs : [];
|
|
273
274
|
}
|
|
274
275
|
} catch (e) {
|
|
275
276
|
console.log(chalk.yellow(' ⚠ Using default structure'));
|
|
@@ -279,30 +280,27 @@ async function diagram(topic, options = {}) {
|
|
|
279
280
|
let asciiDiagram;
|
|
280
281
|
switch (style) {
|
|
281
282
|
case 'minimal':
|
|
282
|
-
asciiDiagram = generateMinimalDiagram(topic, aiData
|
|
283
|
+
asciiDiagram = generateMinimalDiagram(topic, aiData);
|
|
283
284
|
break;
|
|
284
285
|
case 'flowchart':
|
|
285
|
-
asciiDiagram = generateFlowchartDiagram(topic, aiData
|
|
286
|
+
asciiDiagram = generateFlowchartDiagram(topic, aiData);
|
|
286
287
|
break;
|
|
287
288
|
case 'network':
|
|
288
|
-
asciiDiagram = generateNetworkDiagram(topic, aiData
|
|
289
|
+
asciiDiagram = generateNetworkDiagram(topic, aiData);
|
|
289
290
|
break;
|
|
290
291
|
case 'detailed':
|
|
291
292
|
default:
|
|
292
|
-
asciiDiagram = generateDetailedDiagram(topic, aiData
|
|
293
|
+
asciiDiagram = generateDetailedDiagram(topic, aiData);
|
|
293
294
|
break;
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
// Generate Mermaid version
|
|
297
|
-
const mermaidDiagram = generateMermaidDiagram(topic, aiData.components, style);
|
|
298
|
-
|
|
299
297
|
spinner.succeed('✓ Diagram generated');
|
|
300
298
|
|
|
301
299
|
// Display diagram
|
|
302
300
|
console.log('\n' + chalk.cyan(asciiDiagram) + '\n');
|
|
303
301
|
|
|
304
302
|
// Save if requested
|
|
305
|
-
if (save
|
|
303
|
+
if (save) {
|
|
306
304
|
const timestamp = Date.now();
|
|
307
305
|
const safeTopic = topic.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 50);
|
|
308
306
|
|
|
@@ -310,22 +308,14 @@ async function diagram(topic, options = {}) {
|
|
|
310
308
|
const txtFilename = `${safeTopic}-${timestamp}.txt`;
|
|
311
309
|
const txtPath = path.join(DIAGRAMS_DIR, txtFilename);
|
|
312
310
|
fs.writeFileSync(txtPath, asciiDiagram, 'utf8');
|
|
313
|
-
console.log(chalk.green(` 💾 Saved
|
|
311
|
+
console.log(chalk.green(` 💾 Saved: ${txtPath}`));
|
|
314
312
|
|
|
315
|
-
// Save Markdown version
|
|
313
|
+
// Save Markdown version
|
|
316
314
|
const mdFilename = `${safeTopic}-${timestamp}.md`;
|
|
317
315
|
const mdPath = path.join(DIAGRAMS_DIR, mdFilename);
|
|
318
|
-
const mdContent = `# ${topic} Research Diagram\n\n**Style:** ${STYLES[style].name}\n**Generated:** ${new Date().toLocaleString()}\n\n
|
|
316
|
+
const mdContent = `# ${topic} Research Diagram\n\n**Style:** ${STYLES[style].name}\n**Generated:** ${new Date().toLocaleString()}\n\n\`\`\`\n${asciiDiagram}\n\`\`\`\n`;
|
|
319
317
|
fs.writeFileSync(mdPath, mdContent, 'utf8');
|
|
320
|
-
console.log(chalk.green(` 💾 Saved
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Publish if requested
|
|
324
|
-
if (publish) {
|
|
325
|
-
console.log(chalk.yellow('\n 📤 To publish this diagram as research:'));
|
|
326
|
-
console.log(chalk.gray(' 1. Review the saved markdown file'));
|
|
327
|
-
console.log(chalk.gray(' 2. Run: obx publish'));
|
|
328
|
-
console.log(chalk.gray(' 3. Select the diagram from your missions'));
|
|
318
|
+
console.log(chalk.green(` 💾 Saved: ${mdPath}`));
|
|
329
319
|
}
|
|
330
320
|
|
|
331
321
|
console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
|
|
@@ -333,6 +323,11 @@ async function diagram(topic, options = {}) {
|
|
|
333
323
|
} catch (error) {
|
|
334
324
|
spinner.fail('Failed to generate diagram');
|
|
335
325
|
console.error(chalk.red(error.message));
|
|
326
|
+
|
|
327
|
+
if (error.message.includes('402') || error.message.includes('Insufficient')) {
|
|
328
|
+
console.log(chalk.yellow('\n 💡 You need more RCC credits. Run: obx buy'));
|
|
329
|
+
}
|
|
330
|
+
|
|
336
331
|
process.exit(1);
|
|
337
332
|
}
|
|
338
333
|
}
|