omnibiofex 4.2.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 +123 -93
package/package.json
CHANGED
package/src/commands/diagram.js
CHANGED
|
@@ -21,136 +21,162 @@ const STYLES = {
|
|
|
21
21
|
network: { name: 'Network', cost: 70, description: 'Interconnected nodes' }
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
// Generate ASCII banner
|
|
24
|
+
// Generate ASCII banner (single line)
|
|
25
25
|
function banner(title, width = 80) {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const padding = Math.max(0, width - title.length - 2);
|
|
26
|
+
const safeTitle = (title || 'DIAGRAM').substring(0, width - 4);
|
|
27
|
+
const padding = width - safeTitle.length - 4;
|
|
29
28
|
const leftPad = Math.floor(padding / 2);
|
|
30
29
|
const rightPad = padding - leftPad;
|
|
31
|
-
|
|
32
|
-
return `${top}\n${content}\n${bottom}`;
|
|
30
|
+
return `╔${'═'.repeat(width)}╗\n║ ${' '.repeat(leftPad)}${safeTitle}${' '.repeat(rightPad)} ║\n╚${'═'.repeat(width)}╝`;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
// Generate node
|
|
36
|
-
function
|
|
37
|
-
const safeText = text.substring(0, width -
|
|
38
|
-
const padding =
|
|
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;
|
|
39
37
|
const leftPad = Math.floor(padding / 2);
|
|
40
38
|
const rightPad = padding - leftPad;
|
|
41
|
-
|
|
42
|
-
const bottom = `└${'─'.repeat(width)}┘`;
|
|
43
|
-
const content = `│ ${' '.repeat(leftPad)}${safeText}${' '.repeat(rightPad)} │`;
|
|
44
|
-
return `${top}\n${content}\n${bottom}`;
|
|
39
|
+
return `┌${'─'.repeat(width)}┐\n│ ${' '.repeat(leftPad)}${safeText}${' '.repeat(rightPad)} │\n└${'─'.repeat(width)}┘`;
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
// Generate arrow
|
|
48
|
-
function arrow(
|
|
49
|
-
|
|
50
|
-
case 'down': return '│\n▼';
|
|
51
|
-
case 'right': return '───▶';
|
|
52
|
-
case 'left': return '◀───';
|
|
53
|
-
case 'up': return '▲\n│';
|
|
54
|
-
default: return '│\n▼';
|
|
55
|
-
}
|
|
43
|
+
function arrow() {
|
|
44
|
+
return '│\n▼';
|
|
56
45
|
}
|
|
57
46
|
|
|
58
|
-
// Generate detailed diagram
|
|
47
|
+
// Generate detailed diagram (vertical layout)
|
|
59
48
|
function generateDetailedDiagram(topic, data) {
|
|
60
|
-
const width =
|
|
61
|
-
let
|
|
49
|
+
const width = 60;
|
|
50
|
+
let lines = [];
|
|
51
|
+
|
|
52
|
+
lines.push(banner(`${topic.toUpperCase()} RESEARCH ECOSYSTEM`, width));
|
|
53
|
+
lines.push('');
|
|
54
|
+
|
|
55
|
+
// Problem
|
|
56
|
+
lines.push(nodeLine('Research Problem', width));
|
|
57
|
+
lines.push(arrow());
|
|
58
|
+
|
|
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'];
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
lines.push(nodeLine('Input Sources', width));
|
|
65
|
+
lines.push(arrow());
|
|
66
|
+
sources.forEach(source => {
|
|
67
|
+
lines.push(` • ${source}`);
|
|
68
|
+
});
|
|
69
|
+
lines.push(arrow());
|
|
66
70
|
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
diagram += `${' '.repeat(14)}\\ | /\n`;
|
|
71
|
-
diagram += `${' '.repeat(15)}\\ | /\n`;
|
|
72
|
-
diagram += `${' '.repeat(16)}\\ | /\n`;
|
|
73
|
-
diagram += `${' '.repeat(17)}▼ ▼ ▼\n`;
|
|
74
|
-
diagram += `${' '.repeat(15)}${node('Integration Layer', 30)}\n`;
|
|
75
|
-
diagram += `${' '.repeat(29)}${arrow('down')}\n`;
|
|
71
|
+
// Integration
|
|
72
|
+
lines.push(nodeLine('Integration Layer', width));
|
|
73
|
+
lines.push(arrow());
|
|
76
74
|
|
|
77
75
|
// Analysis phase
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
lines.push(nodeLine('Analysis Phase', width));
|
|
77
|
+
lines.push(arrow());
|
|
78
|
+
|
|
79
|
+
const methods = (data.methods && data.methods.length > 0)
|
|
80
|
+
? data.methods.slice(0, 4)
|
|
81
|
+
: ['Statistical Analysis', 'Qualitative Review', 'Comparative Study', 'Predictive Modeling'];
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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());
|
|
90
93
|
|
|
91
94
|
// Output phase
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
lines.push(nodeLine('Output Phase', width));
|
|
96
|
+
lines.push(arrow());
|
|
94
97
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
const outputs = (data.outputs && data.outputs.length > 0)
|
|
99
|
+
? data.outputs.slice(0, 3)
|
|
100
|
+
: ['Publication', 'Implementation', 'Future Work'];
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
lines.push(nodeLine('Outputs', width));
|
|
103
|
+
lines.push(arrow());
|
|
104
|
+
outputs.forEach(output => {
|
|
105
|
+
lines.push(` • ${output}`);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return lines.join('\n');
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
// Generate minimal diagram
|
|
103
112
|
function generateMinimalDiagram(topic, data) {
|
|
104
|
-
const width =
|
|
105
|
-
let
|
|
113
|
+
const width = 50;
|
|
114
|
+
let lines = [];
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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));
|
|
114
125
|
|
|
115
|
-
return
|
|
126
|
+
return lines.join('\n');
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
// Generate flowchart diagram
|
|
119
130
|
function generateFlowchartDiagram(topic, data) {
|
|
120
|
-
const width =
|
|
121
|
-
const steps = data.steps
|
|
122
|
-
|
|
131
|
+
const width = 55;
|
|
132
|
+
const steps = (data.steps && data.steps.length > 0)
|
|
133
|
+
? data.steps
|
|
134
|
+
: ['Research', 'Analysis', 'Implementation', 'Testing', 'Deployment'];
|
|
135
|
+
|
|
136
|
+
let lines = [];
|
|
137
|
+
lines.push(banner(`${topic.toUpperCase()} WORKFLOW`, width));
|
|
138
|
+
lines.push('');
|
|
123
139
|
|
|
124
140
|
steps.forEach((step, i) => {
|
|
125
|
-
|
|
126
|
-
diagram += `${' '.repeat(15)}${node(stepText, 45)}\n`;
|
|
141
|
+
lines.push(nodeLine(`Step ${i + 1}: ${step}`, width));
|
|
127
142
|
if (i < steps.length - 1) {
|
|
128
|
-
|
|
143
|
+
lines.push(arrow());
|
|
129
144
|
}
|
|
130
145
|
});
|
|
131
146
|
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push(nodeLine('✓ Complete', width));
|
|
149
|
+
|
|
150
|
+
return lines.join('\n');
|
|
134
151
|
}
|
|
135
152
|
|
|
136
153
|
// Generate network diagram
|
|
137
154
|
function generateNetworkDiagram(topic, data) {
|
|
138
|
-
const width =
|
|
139
|
-
const nodes = data.nodes
|
|
140
|
-
|
|
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('');
|
|
163
|
+
|
|
164
|
+
// Central node
|
|
165
|
+
lines.push(nodeLine(topic, width));
|
|
166
|
+
lines.push(arrow());
|
|
167
|
+
|
|
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());
|
|
141
175
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
diagram += `${' '.repeat(20)}┌────────┼────────┐\n`;
|
|
145
|
-
diagram += `${' '.repeat(20)}│ │ │\n`;
|
|
146
|
-
diagram += `${' '.repeat(20)}▼ ▼ ▼\n`;
|
|
147
|
-
diagram += `${node(nodes[0], 18)} ${node(nodes[1], 18)} ${node(nodes[2], 18)}\n`;
|
|
148
|
-
diagram += `${' '.repeat(9)}│ │ │\n`;
|
|
149
|
-
diagram += `${' '.repeat(9)}└────────┼────────┘\n`;
|
|
150
|
-
diagram += `${' '.repeat(18)}▼\n`;
|
|
151
|
-
diagram += `${' '.repeat(15)}${node('Integration', 25)}\n`;
|
|
176
|
+
// Integration
|
|
177
|
+
lines.push(nodeLine('Integration & Synthesis', width));
|
|
152
178
|
|
|
153
|
-
return
|
|
179
|
+
return lines.join('\n');
|
|
154
180
|
}
|
|
155
181
|
|
|
156
182
|
// Main diagram command
|
|
@@ -189,7 +215,7 @@ async function diagram(topic, options = {}) {
|
|
|
189
215
|
spinner.update('Analyzing topic with AI');
|
|
190
216
|
await sleep(500);
|
|
191
217
|
|
|
192
|
-
//
|
|
218
|
+
// Use DEEP_RESEARCH task type (already supported by backend)
|
|
193
219
|
const response = await fetch(BACKEND_URL, {
|
|
194
220
|
method: 'POST',
|
|
195
221
|
headers: {
|
|
@@ -197,15 +223,15 @@ async function diagram(topic, options = {}) {
|
|
|
197
223
|
'Authorization': `Bearer ${token}`
|
|
198
224
|
},
|
|
199
225
|
body: JSON.stringify({
|
|
200
|
-
taskType: 'DEEP_RESEARCH',
|
|
226
|
+
taskType: 'DEEP_RESEARCH',
|
|
201
227
|
message: `Generate a structured breakdown of "${topic}" for an ASCII diagram.
|
|
202
228
|
|
|
203
229
|
Return ONLY a valid JSON object with this exact structure (no other text):
|
|
204
230
|
{
|
|
205
|
-
"components": ["component1", "component2", "component3"
|
|
231
|
+
"components": ["component1", "component2", "component3"],
|
|
206
232
|
"methods": ["method1", "method2", "method3", "method4"],
|
|
207
233
|
"steps": ["step1", "step2", "step3", "step4", "step5"],
|
|
208
|
-
"nodes": ["node1", "node2", "node3"],
|
|
234
|
+
"nodes": ["node1", "node2", "node3", "node4", "node5"],
|
|
209
235
|
"outputs": ["output1", "output2", "output3"]
|
|
210
236
|
}
|
|
211
237
|
|
|
@@ -225,7 +251,7 @@ Return ONLY the JSON object, nothing else.`,
|
|
|
225
251
|
|
|
226
252
|
const data = await response.json();
|
|
227
253
|
|
|
228
|
-
// Parse AI response
|
|
254
|
+
// Parse AI response with safe defaults
|
|
229
255
|
let aiData = {
|
|
230
256
|
components: [],
|
|
231
257
|
methods: [],
|
|
@@ -235,12 +261,16 @@ Return ONLY the JSON object, nothing else.`,
|
|
|
235
261
|
};
|
|
236
262
|
|
|
237
263
|
try {
|
|
238
|
-
// Try to find JSON in the response
|
|
239
264
|
const responseText = data.response || '';
|
|
240
265
|
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
|
241
266
|
|
|
242
267
|
if (jsonMatch) {
|
|
243
|
-
|
|
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 : [];
|
|
244
274
|
}
|
|
245
275
|
} catch (e) {
|
|
246
276
|
console.log(chalk.yellow(' ⚠ Using default structure'));
|