@nexusbloom/cli 0.1.3 → 0.1.5

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 +2 -3
  2. package/src/index.js +68 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusbloom/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "NexusBloom CLI — run tools and workflows from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,6 @@
20
20
  "dependencies": {
21
21
  "commander": "^12.0.0",
22
22
  "chalk": "^5.3.0",
23
- "ora": "^8.0.0",
24
- "conf": "^12.0.0"
23
+ "ora": "^8.0.0"
25
24
  }
26
25
  }
package/src/index.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * nxb chat <message> — Natural language routing
14
14
  * nxb info <slug> — Show tool schema
15
15
  * nxb transform <slug> — Pipe stdin through a tool
16
- * nxb config set <key> <value> — Set config
16
+ * nxb config set <key> [value] — Set config (interactive if value omitted)
17
17
  * nxb config get [key] — Get config
18
18
  * nxb cache clear — Clear local tool cache
19
19
  */
@@ -21,16 +21,61 @@
21
21
  import { program } from "commander";
22
22
  import chalk from "chalk";
23
23
  import { createRequire } from "module";
24
- import Conf from "conf";
25
24
  import fs from "fs";
26
25
  import path from "path";
27
26
  import { fileURLToPath } from "url";
27
+ import readline from "readline";
28
28
 
29
29
  const require = createRequire(import.meta.url);
30
30
  const { version } = require("../package.json");
31
31
 
32
32
  const API_BASE = process.env.NEXUSBLOOM_API_URL || "https://www.nexusbloom.dev";
33
- const config = new Conf({ projectName: "nexusbloom" });
33
+
34
+ // ─── Simple file-based config (avoids `conf` dependency issues) ───────────
35
+ const CONFIG_DIR = path.join(process.env.XDG_CONFIG_HOME || path.join(require("os").homedir(), ".config"), "nexusbloom");
36
+ const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
37
+
38
+ function ensureConfigDir() {
39
+ if (!fs.existsSync(CONFIG_DIR)) {
40
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
41
+ }
42
+ }
43
+
44
+ function loadConfig() {
45
+ try {
46
+ if (fs.existsSync(CONFIG_PATH)) {
47
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
48
+ }
49
+ } catch { /* ignore corrupt config */ }
50
+ return {};
51
+ }
52
+
53
+ function saveConfig(store) {
54
+ ensureConfigDir();
55
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(store, null, 2), "utf-8");
56
+ }
57
+
58
+ function configGet(key) {
59
+ const store = loadConfig();
60
+ if (key) return store[key];
61
+ return store;
62
+ }
63
+
64
+ function configSet(key, value) {
65
+ const store = loadConfig();
66
+ store[key] = value;
67
+ saveConfig(store);
68
+ }
69
+
70
+ function promptValue(key) {
71
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
72
+ return new Promise((resolve) => {
73
+ rl.question(chalk.cyan(` Enter value for "${key}": `), (answer) => {
74
+ rl.close();
75
+ resolve(answer.trim());
76
+ });
77
+ });
78
+ }
34
79
 
35
80
  // ─── Cache directory for local tool execution ────────────────────────────────
36
81
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -162,7 +207,7 @@ program
162
207
  }
163
208
 
164
209
  // ── Remote API execution ────────────────────────────────────────────
165
- const apiKey = opts.key || process.env.NEXUSBLOOM_API_KEY || config.get("apiKey");
210
+ const apiKey = opts.key || process.env.NEXUSBLOOM_API_KEY || configGet("apiKey") || configGet("key");
166
211
  if (!apiKey) {
167
212
  if (jsonMode) return console.log(JSON.stringify({ error: "API key required. Set NEXUSBLOOM_API_KEY, pass --key, or run `nxb config set key <your-key>`." }));
168
213
  console.error(chalk.red("API key required. Set NEXUSBLOOM_API_KEY, pass --key, or run `nxb config set key <your-key>`."));
@@ -224,7 +269,7 @@ async function executeLocal(slug, input, jsonMode) {
224
269
  process.exit(1);
225
270
  }
226
271
  const data = await res.json();
227
- manifest = data.manifest || data;
272
+ manifest = data.data?.manifest || data.manifest || data;
228
273
 
229
274
  // Fetch the v2 source separately
230
275
  const sourceRes = await fetch(`${API_BASE}/api/run/${slug}?source=true`);
@@ -361,9 +406,10 @@ program
361
406
  return;
362
407
  }
363
408
  const data = await res.json();
364
- const manifest = data.manifest || data;
409
+ const manifest = data.data?.manifest || data.manifest || data;
365
410
  if (jsonMode) return console.log(JSON.stringify(manifest, null, 2));
366
- console.log(chalk.bold(`\n ${manifest.name}`));
411
+ const toolName = manifest.name || manifest.slug || slug;
412
+ console.log(chalk.bold(`\n ${toolName}`));
367
413
  console.log(` ${chalk.dim(manifest.short_description || "")}`);
368
414
  console.log(` Version: ${chalk.cyan(manifest.version || "1.0.0")}`);
369
415
  console.log(` Runtime: ${chalk.cyan(manifest.runtime || "browser")}`);
@@ -400,7 +446,7 @@ program
400
446
  .option("--local", "Execute locally (faster for repeated use)")
401
447
  .action(async (slug, opts, cmd) => {
402
448
  const jsonMode = cmd.parent.opts().json;
403
- const apiKey = opts.key || process.env.NEXUSBLOOM_API_KEY || config.get("apiKey");
449
+ const apiKey = opts.key || process.env.NEXUSBLOOM_API_KEY || configGet("apiKey") || configGet("key");
404
450
 
405
451
  const input = await readStdin();
406
452
  if (!input) {
@@ -459,11 +505,18 @@ const configCmd = program
459
505
 
460
506
  configCmd
461
507
  .command("set")
462
- .description("Set a config value")
508
+ .description("Set a config value (prompts for value if omitted)")
463
509
  .argument("<key>", "Config key (key, default-tool)")
464
- .argument("<value>", "Config value")
465
- .action((key, value) => {
466
- config.set(key, value);
510
+ .argument("[value]", "Config value (prompted if not provided)")
511
+ .action(async (key, value) => {
512
+ if (!value) {
513
+ value = await promptValue(key);
514
+ }
515
+ if (!value) {
516
+ console.log(chalk.yellow(" No value provided. Aborted."));
517
+ return;
518
+ }
519
+ configSet(key, value);
467
520
  console.log(chalk.green(` Set ${key} to "${value}"`));
468
521
  });
469
522
 
@@ -472,15 +525,15 @@ configCmd
472
525
  .description("Get a config value")
473
526
  .argument("[key]", "Config key (omit to show all)")
474
527
  .action((key) => {
528
+ const store = loadConfig();
475
529
  if (key) {
476
- const value = config.get(key);
530
+ const value = store[key];
477
531
  if (value === undefined) {
478
532
  console.log(chalk.yellow(` ${key} is not set`));
479
533
  } else {
480
534
  console.log(` ${key}: ${value}`);
481
535
  }
482
536
  } else {
483
- const store = config.store;
484
537
  if (Object.keys(store).length === 0) {
485
538
  console.log(chalk.yellow(" No config values set."));
486
539
  } else {
@@ -495,7 +548,7 @@ configCmd
495
548
  .command("list")
496
549
  .description("List all config values (alias for config get)")
497
550
  .action(() => {
498
- const store = config.store;
551
+ const store = loadConfig();
499
552
  if (Object.keys(store).length === 0) {
500
553
  console.log(chalk.yellow(" No config values set."));
501
554
  } else {