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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnibiofex",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "OmniBioFex X - The Autonomous Research Operating System",
5
5
  "main": "bin/obx",
6
6
  "bin": {
@@ -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 top = `╔${''.repeat(width)}╗`;
27
- const bottom = `╚${'═'.repeat(width)}╝`;
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
- const content = `║ ${' '.repeat(leftPad)}${title}${' '.repeat(rightPad)} ║`;
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 box
36
- function node(text, width = 20) {
37
- const safeText = text.substring(0, width - 2);
38
- const padding = Math.max(0, width - safeText.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;
39
37
  const leftPad = Math.floor(padding / 2);
40
38
  const rightPad = padding - leftPad;
41
- const top = `┌${'─'.repeat(width)}┐`;
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(direction = 'down') {
49
- switch (direction) {
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 = 80;
61
- let diagram = banner(`${topic.toUpperCase()} RESEARCH ECOSYSTEM`, width) + '\n\n';
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
- // Problem identification
64
- diagram += `${' '.repeat(25)}${node('Research Problem', 25)}\n`;
65
- diagram += `${' '.repeat(37)}${arrow('down')}\n\n`;
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
- // Three input sources
68
- const sources = data.components?.slice(0, 3) || ['Literature', 'Data', 'Theory'];
69
- diagram += `${' '.repeat(5)}${node(sources[0] || 'Literature', 18)} ${node(sources[1] || 'Data', 18)} ${node(sources[2] || 'Theory', 18)}\n`;
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
- diagram += `${' '.repeat(20)}${node('Analysis Phase', 25)}\n`;
79
- diagram += `${' '.repeat(32)}${arrow('down')}\n\n`;
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
- // Four analysis types
82
- const methods = data.methods?.slice(0, 4) || ['Statistical', 'Qualitative', 'Comparative', 'Predictive'];
83
- diagram += `${node(methods[0], 14)} ${node(methods[1], 14)} ${node(methods[2], 14)} ${node(methods[3], 14)}\n`;
84
- diagram += `${' '.repeat(7)}\\ | | /\n`;
85
- diagram += `${' '.repeat(8)}\\ | | /\n`;
86
- diagram += `${' '.repeat(9)}\\ | | /\n`;
87
- diagram += `${' '.repeat(10)}▼ ▼ ▼ ▼\n`;
88
- diagram += `${' '.repeat(15)}${node('Synthesis & Insights', 35)}\n`;
89
- diagram += `${' '.repeat(32)}${arrow('down')}\n`;
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
- diagram += `${' '.repeat(20)}${node('Output Phase', 25)}\n`;
93
- diagram += `${' '.repeat(32)}${arrow('down')}\n\n`;
95
+ lines.push(nodeLine('Output Phase', width));
96
+ lines.push(arrow());
94
97
 
95
- // Three outputs
96
- const outputs = data.outputs?.slice(0, 3) || ['Publication', 'Implementation', 'Future Work'];
97
- diagram += `${node(outputs[0], 18)} ${node(outputs[1], 18)} ${node(outputs[2], 18)}\n`;
98
+ const outputs = (data.outputs && data.outputs.length > 0)
99
+ ? data.outputs.slice(0, 3)
100
+ : ['Publication', 'Implementation', 'Future Work'];
98
101
 
99
- return diagram;
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 = 60;
105
- let diagram = banner(topic.toUpperCase(), width) + '\n\n';
113
+ const width = 50;
114
+ let lines = [];
106
115
 
107
- diagram += `${' '.repeat(20)}${node('Problem', 20)}\n`;
108
- diagram += `${' '.repeat(29)}${arrow('down')}\n`;
109
- diagram += `${' '.repeat(10)}${node('Research', 20)}\n`;
110
- diagram += `${' '.repeat(19)}${arrow('down')}\n`;
111
- diagram += `${' '.repeat(10)}${node('Analysis', 20)}\n`;
112
- diagram += `${' '.repeat(19)}${arrow('down')}\n`;
113
- diagram += `${' '.repeat(10)}${node('Solution', 20)}\n`;
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 diagram;
126
+ return lines.join('\n');
116
127
  }
117
128
 
118
129
  // Generate flowchart diagram
119
130
  function generateFlowchartDiagram(topic, data) {
120
- const width = 60;
121
- const steps = data.steps?.length > 0 ? data.steps : ['Research', 'Analysis', 'Implementation'];
122
- let diagram = banner(`${topic.toUpperCase()} WORKFLOW`, width) + '\n\n';
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
- const stepText = `Step ${i + 1}: ${step}`;
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
- diagram += `${' '.repeat(37)}${arrow('down')}\n`;
143
+ lines.push(arrow());
129
144
  }
130
145
  });
131
146
 
132
- diagram += `\n${' '.repeat(25)}${node('✓ Complete', 20)}\n`;
133
- return diagram;
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 = 70;
139
- const nodes = data.nodes?.slice(0, 3) || ['Component A', 'Component B', 'Component C'];
140
- let diagram = banner(`${topic.toUpperCase()} NETWORK`, width) + '\n\n';
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
- diagram += `${' '.repeat(25)}${node(topic, 25)}\n`;
143
- diagram += `${' '.repeat(37)}|\n`;
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 diagram;
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
- // ✅ FIX: Use DEEP_RESEARCH task type (already supported by backend)
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', // ← Use existing task type
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", "component4"],
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 - extract JSON from the 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
- aiData = JSON.parse(jsonMatch[0]);
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'));