@nexusbloom/cli 0.1.5 → 0.1.7
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/index.js +129 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -165,6 +165,20 @@ program
|
|
|
165
165
|
.action(async (slug, args, opts, cmd) => {
|
|
166
166
|
const jsonMode = cmd.parent.opts().json;
|
|
167
167
|
|
|
168
|
+
// ── Resolve abbreviation ────────────────────────────────────────────
|
|
169
|
+
try {
|
|
170
|
+
const res = await fetch(`${API_BASE}/api/tools`);
|
|
171
|
+
const { tools } = await res.json();
|
|
172
|
+
const slugs = (tools || []).map((t) => t.slug);
|
|
173
|
+
const abbrMap = generateAbbreviations(slugs);
|
|
174
|
+
if (abbrMap[slug] && slugs.includes(abbrMap[slug])) {
|
|
175
|
+
if (!jsonMode) console.log(chalk.dim(` Resolved: ${slug} → ${abbrMap[slug]}`));
|
|
176
|
+
slug = abbrMap[slug];
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
// Silently ignore abbreviation resolution failures
|
|
180
|
+
}
|
|
181
|
+
|
|
168
182
|
// ── Build input body ────────────────────────────────────────────────
|
|
169
183
|
let body = {};
|
|
170
184
|
|
|
@@ -599,6 +613,121 @@ cacheCmd
|
|
|
599
613
|
|
|
600
614
|
program.parse(process.argv);
|
|
601
615
|
|
|
616
|
+
// ─── Abbreviation generator ──────────────────────────────────────────────────
|
|
617
|
+
|
|
618
|
+
function generateAbbreviations(slugs) {
|
|
619
|
+
const abbrMap = {};
|
|
620
|
+
const used = new Set();
|
|
621
|
+
|
|
622
|
+
for (const slug of slugs) {
|
|
623
|
+
// Try first letter of each word
|
|
624
|
+
const parts = slug.split("-");
|
|
625
|
+
let abbr = parts.map((p) => p[0]).join("").toLowerCase();
|
|
626
|
+
|
|
627
|
+
// If taken, try longer combinations
|
|
628
|
+
if (used.has(abbr) || abbr.length < 2) {
|
|
629
|
+
for (let len = 2; len <= slug.length; len++) {
|
|
630
|
+
abbr = slug.slice(0, len);
|
|
631
|
+
if (!used.has(abbr)) break;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
used.add(abbr);
|
|
636
|
+
abbrMap[slug] = abbr;
|
|
637
|
+
abbrMap[abbr] = slug;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return abbrMap;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// ─── `nxb abbr` — show tool abbreviations ────────────────────────────────────
|
|
644
|
+
|
|
645
|
+
program
|
|
646
|
+
.command("abbr")
|
|
647
|
+
.description("Show tool abbreviations")
|
|
648
|
+
.action(async () => {
|
|
649
|
+
try {
|
|
650
|
+
const res = await fetch(`${API_BASE}/api/tools`);
|
|
651
|
+
const { tools } = await res.json();
|
|
652
|
+
const slugs = (tools || []).map((t) => t.slug);
|
|
653
|
+
const abbrMap = generateAbbreviations(slugs);
|
|
654
|
+
|
|
655
|
+
console.log(chalk.bold("\n Tool Abbreviations:\n"));
|
|
656
|
+
slugs.forEach((slug) => {
|
|
657
|
+
console.log(` ${chalk.cyan(abbrMap[slug].padEnd(15))} → ${chalk.dim(slug)}`);
|
|
658
|
+
});
|
|
659
|
+
console.log();
|
|
660
|
+
} catch (err) {
|
|
661
|
+
console.error(chalk.red("Failed to fetch tools:"), err.message);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// ─── `nxb json` — create JSON input for tools ───────────────────────────────
|
|
666
|
+
|
|
667
|
+
program
|
|
668
|
+
.command("json")
|
|
669
|
+
.description("Create JSON input for tools (pipe into nxb run)")
|
|
670
|
+
.option("-t, --template <slug>", "Generate JSON template for a specific tool")
|
|
671
|
+
.option("-i, --interactive", "Interactive mode - prompts for each field")
|
|
672
|
+
.action(async (opts, cmd) => {
|
|
673
|
+
const jsonMode = cmd.parent.opts().json;
|
|
674
|
+
|
|
675
|
+
if (opts.template) {
|
|
676
|
+
// Fetch tool schema
|
|
677
|
+
const res = await fetch(`${API_BASE}/api/run/${opts.template}`);
|
|
678
|
+
if (!res.ok) {
|
|
679
|
+
console.error(chalk.red(`Tool "${opts.template}" not found`));
|
|
680
|
+
process.exit(1);
|
|
681
|
+
}
|
|
682
|
+
const data = await res.json();
|
|
683
|
+
const manifest = data.data?.manifest || data.manifest || data;
|
|
684
|
+
const schema = manifest.input_schema || {};
|
|
685
|
+
|
|
686
|
+
if (opts.interactive) {
|
|
687
|
+
// Interactive mode
|
|
688
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
689
|
+
const ask = (q) => new Promise((r) => rl.question(q, r));
|
|
690
|
+
const result = {};
|
|
691
|
+
|
|
692
|
+
if (schema.properties) {
|
|
693
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
694
|
+
const required = schema.required?.includes(key);
|
|
695
|
+
const hint = prop.description ? ` (${prop.description})` : "";
|
|
696
|
+
const def = prop.default ? ` [${prop.default}]` : "";
|
|
697
|
+
const answer = await ask(chalk.cyan(` ${key}${hint}${def}: `));
|
|
698
|
+
const val = answer || prop.default;
|
|
699
|
+
if (val) result[key] = prop.type === "number" ? Number(val) : val;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
rl.close();
|
|
703
|
+
if (jsonMode) return console.log(JSON.stringify(result, null, 2));
|
|
704
|
+
console.log(JSON.stringify(result));
|
|
705
|
+
} else {
|
|
706
|
+
// Generate template with defaults
|
|
707
|
+
const template = {};
|
|
708
|
+
if (schema.properties) {
|
|
709
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
710
|
+
if (prop.default !== undefined) {
|
|
711
|
+
template[key] = prop.default;
|
|
712
|
+
} else if (prop.type === "string") {
|
|
713
|
+
template[key] = prop.enum ? prop.enum[0] : "";
|
|
714
|
+
} else if (prop.type === "number" || prop.type === "integer") {
|
|
715
|
+
template[key] = 0;
|
|
716
|
+
} else if (prop.type === "boolean") {
|
|
717
|
+
template[key] = false;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
if (jsonMode) return console.log(JSON.stringify(template, null, 2));
|
|
722
|
+
console.log(JSON.stringify(template, null, 2));
|
|
723
|
+
}
|
|
724
|
+
} else {
|
|
725
|
+
console.log(chalk.yellow("Usage: nxb json --template <slug> [--interactive]"));
|
|
726
|
+
console.log(chalk.dim(" Generate JSON input for a tool that can be piped into nxb run"));
|
|
727
|
+
console.log(chalk.dim(" Example: nxb json --template summarize | nxb run summarize --input @-"));
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
|
|
602
731
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
603
732
|
|
|
604
733
|
function readStdin() {
|