@nexusbloom/cli 0.1.9 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +70 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusbloom/cli",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "NexusBloom CLI — run tools and workflows from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -252,6 +252,15 @@ program
252
252
  },
253
253
  body: JSON.stringify(body),
254
254
  });
255
+
256
+ if (!res.ok && !res.headers.get("content-type")?.includes("json")) {
257
+ const text = await res.text();
258
+ if (jsonMode) return console.log(JSON.stringify({ error: `API returned ${res.status}: ${text.slice(0, 200)}` }));
259
+ console.error(chalk.red(`API returned ${res.status} (non-JSON response). The endpoint may not be deployed.`));
260
+ console.error(chalk.dim(` Raw response: ${text.slice(0, 200)}`));
261
+ process.exit(1);
262
+ }
263
+
255
264
  const data = await res.json();
256
265
  if (data.success) {
257
266
  if (jsonMode) return console.log(JSON.stringify({ success: true, data: data.data }, null, 2));
@@ -290,34 +299,75 @@ async function executeLocal(slug, input, jsonMode) {
290
299
  // Fetch from API if not cached
291
300
  if (!manifest || !coreLogicSource) {
292
301
  if (!jsonMode) console.log(chalk.dim(` Fetching tool: ${slug}...`));
302
+
303
+ // Try API first
304
+ let apiSuccess = false;
293
305
  try {
294
306
  const res = await fetch(`${API_BASE}/api/run/${slug}`);
295
- if (!res.ok) {
296
- if (jsonMode) return console.log(JSON.stringify({ error: `Tool "${slug}" not found` }));
297
- console.error(chalk.red(`Tool "${slug}" not found.`));
298
- process.exit(1);
307
+ if (res.ok) {
308
+ const data = await res.json();
309
+ manifest = data.data?.manifest || data.manifest || data;
310
+
311
+ const sourceRes = await fetch(`${API_BASE}/api/run/${slug}?source=true`);
312
+ if (sourceRes.ok) {
313
+ const sourceData = await sourceRes.json();
314
+ coreLogicSource = sourceData.data?.v2_source;
315
+ }
316
+ apiSuccess = true;
299
317
  }
300
- const data = await res.json();
301
- manifest = data.data?.manifest || data.manifest || data;
318
+ } catch {
319
+ // API failed, try Supabase fallback
320
+ }
302
321
 
303
- // Fetch the v2 source separately
304
- const sourceRes = await fetch(`${API_BASE}/api/run/${slug}?source=true`);
305
- if (sourceRes.ok) {
306
- const sourceData = await sourceRes.json();
307
- coreLogicSource = sourceData.data?.v2_source;
308
- } else {
309
- coreLogicSource = null;
322
+ // Fallback: query Supabase directly for v2_source
323
+ if (!apiSuccess) {
324
+ try {
325
+ const supabaseUrl = process.env.NEXUSBLOOM_SUPABASE_URL || "https://dhxaqatmuprehrkszxzs.supabase.co";
326
+ const supabaseKey = process.env.NEXUSBLOOM_SUPABASE_ANON_KEY;
327
+ if (supabaseKey) {
328
+ // Get tool from tools table
329
+ const toolRes = await fetch(`${supabaseUrl}/rest/v1/tools?slug=eq.${slug}&select=id`, {
330
+ headers: { apikey: supabaseKey, Authorization: `Bearer ${supabaseKey}` }
331
+ });
332
+ const tools = await toolRes.json();
333
+ const toolId = tools?.[0]?.id;
334
+ if (toolId) {
335
+ // Get v2_source from tool_versions
336
+ const versionRes = await fetch(
337
+ `${supabaseUrl}/rest/v1/tool_versions?tool_id=eq.${toolId}&tool_type=eq.builtin&status=eq.published&select=v2_source&order=created_at.desc&limit=1`,
338
+ { headers: { apikey: supabaseKey, Authorization: `Bearer ${supabaseKey}` } }
339
+ );
340
+ const versions = await versionRes.json();
341
+ const v2Source = versions?.[0]?.v2_source;
342
+ if (v2Source) {
343
+ coreLogicSource = v2Source;
344
+ const manifestMatch = v2Source.match(/export\s+const\s+MANIFEST\s*=\s*({[\s\S]*?});\s*\n/);
345
+ if (manifestMatch) {
346
+ try {
347
+ manifest = JSON.parse(manifestMatch[1].replace(/(\w+):/g, '"$1":').replace(/'/g, '"'));
348
+ } catch {
349
+ manifest = eval("(" + manifestMatch[1] + ")");
350
+ }
351
+ }
352
+ apiSuccess = true;
353
+ }
354
+ }
355
+ }
356
+ } catch {
357
+ // Supabase fallback also failed
310
358
  }
359
+ }
311
360
 
312
- // Cache it
313
- if (manifest) {
314
- fs.writeFileSync(cacheFile, JSON.stringify({ manifest, coreLogicSource, cachedAt: new Date().toISOString() }), "utf-8");
315
- }
316
- } catch (err) {
317
- if (jsonMode) return console.log(JSON.stringify({ error: `Failed to fetch tool: ${err.message}` }));
318
- console.error(chalk.red(`Failed to fetch tool: ${err.message}`));
361
+ if (!apiSuccess) {
362
+ if (jsonMode) return console.log(JSON.stringify({ error: `Tool "${slug}" not found. Ensure API is deployed or set NEXUSBLOOM_SUPABASE_ANON_KEY for local mode.` }));
363
+ console.error(chalk.red(`Tool "${slug}" not found. Ensure API is deployed or set NEXUSBLOOM_SUPABASE_ANON_KEY for local mode.`));
319
364
  process.exit(1);
320
365
  }
366
+
367
+ // Cache it
368
+ if (manifest) {
369
+ fs.writeFileSync(cacheFile, JSON.stringify({ manifest, coreLogicSource, cachedAt: new Date().toISOString() }), "utf-8");
370
+ }
321
371
  }
322
372
 
323
373
  if (!coreLogicSource) {