@tronsfey/ucli 0.4.3 → 0.5.1
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/dist/{client-3I7XBDJU.js → client-LCWUZRZX.js} +94 -4
- package/dist/client-LCWUZRZX.js.map +1 -0
- package/dist/index.js +657 -49
- package/dist/index.js.map +1 -1
- package/dist/{runner-GVYIJNHN.js → runner-HH357SRR.js} +33 -17
- package/dist/{runner-GVYIJNHN.js.map → runner-HH357SRR.js.map} +1 -1
- package/package.json +2 -2
- package/skill.md +92 -8
- package/dist/client-3I7XBDJU.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -154,23 +154,71 @@ var ServerClient = class {
|
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
+
// src/lib/exit-codes.ts
|
|
158
|
+
var ExitCode = {
|
|
159
|
+
SUCCESS: 0,
|
|
160
|
+
GENERAL_ERROR: 1,
|
|
161
|
+
USAGE_ERROR: 2,
|
|
162
|
+
CONFIG_ERROR: 3,
|
|
163
|
+
AUTH_ERROR: 4,
|
|
164
|
+
CONNECTIVITY_ERROR: 5,
|
|
165
|
+
NOT_FOUND: 6,
|
|
166
|
+
SERVER_ERROR: 7
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/lib/output.ts
|
|
170
|
+
var currentMode = "text";
|
|
171
|
+
function setOutputMode(mode) {
|
|
172
|
+
currentMode = mode;
|
|
173
|
+
}
|
|
174
|
+
function isJsonOutput() {
|
|
175
|
+
return currentMode === "json";
|
|
176
|
+
}
|
|
177
|
+
function outputSuccess(data) {
|
|
178
|
+
if (currentMode === "json") {
|
|
179
|
+
console.log(JSON.stringify({ success: true, data }, null, 2));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function outputError(code, message, hint) {
|
|
183
|
+
if (currentMode === "json") {
|
|
184
|
+
const envelope = {
|
|
185
|
+
success: false,
|
|
186
|
+
error: { code, message, ...hint ? { hint } : {} }
|
|
187
|
+
};
|
|
188
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
189
|
+
process.exit(code);
|
|
190
|
+
}
|
|
191
|
+
console.error(`
|
|
192
|
+
\u2716 Error: ${message}`);
|
|
193
|
+
if (hint) console.error(` Hint: ${hint}`);
|
|
194
|
+
process.exit(code);
|
|
195
|
+
}
|
|
196
|
+
|
|
157
197
|
// src/commands/configure.ts
|
|
158
198
|
function registerConfigure(program2) {
|
|
159
199
|
program2.command("configure").description("Configure the OAS Gateway server URL and authentication token").requiredOption("--server <url>", "OAS Gateway server URL (e.g. https://oas.example.com)").requiredOption("--token <jwt>", "Group JWT token issued by the server admin").action(async (opts) => {
|
|
160
200
|
const serverUrl = opts.server.replace(/\/$/, "");
|
|
161
201
|
const token = opts.token;
|
|
162
|
-
|
|
202
|
+
if (!isJsonOutput()) {
|
|
203
|
+
console.log(`Connecting to ${serverUrl}...`);
|
|
204
|
+
}
|
|
163
205
|
const client = new ServerClient({ serverUrl, token });
|
|
164
206
|
try {
|
|
165
207
|
await client.listOAS();
|
|
166
208
|
saveConfig({ serverUrl, token });
|
|
209
|
+
if (isJsonOutput()) {
|
|
210
|
+
outputSuccess({ serverUrl, configured: true });
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
167
213
|
console.log("\u2713 Configuration saved successfully.");
|
|
168
214
|
console.log(` Server: ${serverUrl}`);
|
|
169
215
|
console.log(` Token: ${token.slice(0, 20)}...`);
|
|
170
216
|
} catch (err) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
217
|
+
outputError(
|
|
218
|
+
ExitCode.CONNECTIVITY_ERROR,
|
|
219
|
+
`Connection failed: ${err.message}`,
|
|
220
|
+
"Check the server URL and token"
|
|
221
|
+
);
|
|
174
222
|
}
|
|
175
223
|
});
|
|
176
224
|
}
|
|
@@ -374,6 +422,68 @@ async function getServiceHelp(entry) {
|
|
|
374
422
|
});
|
|
375
423
|
}
|
|
376
424
|
|
|
425
|
+
// src/lib/yaml.ts
|
|
426
|
+
function toYaml(value, indent = 0) {
|
|
427
|
+
if (value === null || value === void 0) {
|
|
428
|
+
return "null";
|
|
429
|
+
}
|
|
430
|
+
if (typeof value === "boolean") {
|
|
431
|
+
return value ? "true" : "false";
|
|
432
|
+
}
|
|
433
|
+
if (typeof value === "number") {
|
|
434
|
+
return String(value);
|
|
435
|
+
}
|
|
436
|
+
if (typeof value === "string") {
|
|
437
|
+
if (needsQuoting(value)) {
|
|
438
|
+
return JSON.stringify(value);
|
|
439
|
+
}
|
|
440
|
+
return value;
|
|
441
|
+
}
|
|
442
|
+
if (Array.isArray(value)) {
|
|
443
|
+
if (value.length === 0) return "[]";
|
|
444
|
+
const prefix = " ".repeat(indent);
|
|
445
|
+
return value.map((item) => {
|
|
446
|
+
const serialised = toYaml(item, indent + 2);
|
|
447
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
448
|
+
const firstNewline = serialised.indexOf("\n");
|
|
449
|
+
if (firstNewline === -1) {
|
|
450
|
+
return `${prefix}- ${serialised.trimStart()}`;
|
|
451
|
+
}
|
|
452
|
+
const firstLine = serialised.slice(0, firstNewline);
|
|
453
|
+
const rest = serialised.slice(firstNewline + 1);
|
|
454
|
+
return `${prefix}- ${firstLine.trimStart()}
|
|
455
|
+
${rest}`;
|
|
456
|
+
}
|
|
457
|
+
return `${prefix}- ${serialised}`;
|
|
458
|
+
}).join("\n");
|
|
459
|
+
}
|
|
460
|
+
if (typeof value === "object") {
|
|
461
|
+
const entries = Object.entries(value);
|
|
462
|
+
if (entries.length === 0) return "{}";
|
|
463
|
+
const prefix = " ".repeat(indent);
|
|
464
|
+
return entries.map(([key, val]) => {
|
|
465
|
+
if (val === null || val === void 0) {
|
|
466
|
+
return `${prefix}${key}: null`;
|
|
467
|
+
}
|
|
468
|
+
if (typeof val === "object") {
|
|
469
|
+
const nested = toYaml(val, indent + 2);
|
|
470
|
+
return `${prefix}${key}:
|
|
471
|
+
${nested}`;
|
|
472
|
+
}
|
|
473
|
+
return `${prefix}${key}: ${toYaml(val, indent)}`;
|
|
474
|
+
}).join("\n");
|
|
475
|
+
}
|
|
476
|
+
return String(value);
|
|
477
|
+
}
|
|
478
|
+
function needsQuoting(s) {
|
|
479
|
+
if (s === "") return true;
|
|
480
|
+
if (s === "true" || s === "false" || s === "null") return true;
|
|
481
|
+
if (/^\d/.test(s)) return true;
|
|
482
|
+
if (/[:{}\[\],&*#?|<>=!%@`'"\\\n\r\t]/.test(s)) return true;
|
|
483
|
+
if (s.startsWith(" ") || s.endsWith(" ")) return true;
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
|
|
377
487
|
// src/commands/services.ts
|
|
378
488
|
function registerServices(program2) {
|
|
379
489
|
const services = program2.command("services").description("Manage and inspect available OAS services");
|
|
@@ -392,19 +502,27 @@ function registerServices(program2) {
|
|
|
392
502
|
await writeOASListCache(entries, maxTtl);
|
|
393
503
|
}
|
|
394
504
|
}
|
|
505
|
+
const safe = entries.map(({ authConfig, ...rest }) => ({
|
|
506
|
+
...rest,
|
|
507
|
+
authConfig: { type: authConfig["type"] ?? rest.authType }
|
|
508
|
+
}));
|
|
509
|
+
if (isJsonOutput()) {
|
|
510
|
+
outputSuccess(safe);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
395
513
|
const format = (opts.format ?? "table").toLowerCase();
|
|
396
514
|
if (entries.length === 0) {
|
|
397
515
|
console.log("No services registered in this group.");
|
|
398
516
|
return;
|
|
399
517
|
}
|
|
400
518
|
if (format === "json") {
|
|
401
|
-
const safe = entries.map(({ authConfig, ...rest }) => ({
|
|
402
|
-
...rest,
|
|
403
|
-
authConfig: { type: authConfig["type"] ?? rest.authType }
|
|
404
|
-
}));
|
|
405
519
|
console.log(JSON.stringify(safe, null, 2));
|
|
406
520
|
return;
|
|
407
521
|
}
|
|
522
|
+
if (format === "yaml") {
|
|
523
|
+
console.log(toYaml(safe));
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
408
526
|
const nameWidth = Math.max(10, ...entries.map((e) => e.name.length));
|
|
409
527
|
console.log(`
|
|
410
528
|
${"SERVICE".padEnd(nameWidth)} AUTH DESCRIPTION`);
|
|
@@ -422,23 +540,33 @@ ${"SERVICE".padEnd(nameWidth)} AUTH DESCRIPTION`);
|
|
|
422
540
|
let entry;
|
|
423
541
|
try {
|
|
424
542
|
entry = await client.getOAS(name);
|
|
425
|
-
} catch
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
543
|
+
} catch {
|
|
544
|
+
outputError(
|
|
545
|
+
ExitCode.NOT_FOUND,
|
|
546
|
+
`Service not found: ${name}`,
|
|
547
|
+
"Run: ucli services list to see available services"
|
|
548
|
+
);
|
|
429
549
|
}
|
|
430
550
|
const help = await getServiceHelp(entry);
|
|
551
|
+
const { authConfig, ...rest } = entry;
|
|
552
|
+
const safe = {
|
|
553
|
+
...rest,
|
|
554
|
+
authConfig: { type: authConfig["type"] ?? rest.authType },
|
|
555
|
+
operationsHelp: help
|
|
556
|
+
};
|
|
557
|
+
if (isJsonOutput()) {
|
|
558
|
+
outputSuccess(safe);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
431
561
|
const format = (opts.format ?? "table").toLowerCase();
|
|
432
562
|
if (format === "json") {
|
|
433
|
-
const { authConfig, ...rest } = entry;
|
|
434
|
-
const safe = {
|
|
435
|
-
...rest,
|
|
436
|
-
authConfig: { type: authConfig["type"] ?? rest.authType },
|
|
437
|
-
operationsHelp: help
|
|
438
|
-
};
|
|
439
563
|
console.log(JSON.stringify(safe, null, 2));
|
|
440
564
|
return;
|
|
441
565
|
}
|
|
566
|
+
if (format === "yaml") {
|
|
567
|
+
console.log(toYaml(safe));
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
442
570
|
console.log(`
|
|
443
571
|
Service: ${entry.name}`);
|
|
444
572
|
console.log(`Description: ${entry.description || "(none)"}`);
|
|
@@ -456,13 +584,18 @@ Service: ${entry.name}`);
|
|
|
456
584
|
function registerRun(program2) {
|
|
457
585
|
program2.command("run [service] [args...]").description("Execute an operation on a service").option("--service <name>", "Service name (from `services list`)").option("--operation <id>", "OperationId to execute").option("--params <json>", "JSON string of operation parameters").option("--format <fmt>", "Output format: json | table | yaml", "json").option("--query <jmespath>", "Filter response with JMESPath expression").option("--data <json>", "Request body (JSON string or @filename)").allowUnknownOption(true).action(async (serviceArg, args, opts) => {
|
|
458
586
|
if (serviceArg && opts.service && serviceArg !== opts.service) {
|
|
459
|
-
|
|
460
|
-
|
|
587
|
+
outputError(
|
|
588
|
+
ExitCode.USAGE_ERROR,
|
|
589
|
+
`Conflicting service values: positional "${serviceArg}" and --service "${opts.service}". Use either the positional argument or --service flag, not both.`
|
|
590
|
+
);
|
|
461
591
|
}
|
|
462
592
|
const service = opts.service ?? serviceArg;
|
|
463
593
|
if (!service) {
|
|
464
|
-
|
|
465
|
-
|
|
594
|
+
outputError(
|
|
595
|
+
ExitCode.USAGE_ERROR,
|
|
596
|
+
"Missing service name. Use positional <service> or --service <name>.",
|
|
597
|
+
"Run: ucli services list to see available services"
|
|
598
|
+
);
|
|
466
599
|
}
|
|
467
600
|
const cfg = getConfig();
|
|
468
601
|
const client = new ServerClient(cfg);
|
|
@@ -470,9 +603,11 @@ function registerRun(program2) {
|
|
|
470
603
|
try {
|
|
471
604
|
entry = await client.getOAS(service);
|
|
472
605
|
} catch {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
606
|
+
outputError(
|
|
607
|
+
ExitCode.NOT_FOUND,
|
|
608
|
+
`Unknown service: ${service}`,
|
|
609
|
+
"Run: ucli services list to see available services"
|
|
610
|
+
);
|
|
476
611
|
}
|
|
477
612
|
const extraArgs = opts.args ?? [];
|
|
478
613
|
const operationArgs = [...args, ...extraArgs];
|
|
@@ -484,8 +619,11 @@ function registerRun(program2) {
|
|
|
484
619
|
try {
|
|
485
620
|
parsed = JSON.parse(opts.params);
|
|
486
621
|
} catch {
|
|
487
|
-
|
|
488
|
-
|
|
622
|
+
outputError(
|
|
623
|
+
ExitCode.USAGE_ERROR,
|
|
624
|
+
"Invalid --params JSON.",
|
|
625
|
+
`Example: --params '{"petId": 1}'`
|
|
626
|
+
);
|
|
489
627
|
}
|
|
490
628
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
491
629
|
for (const [k, v] of Object.entries(parsed)) {
|
|
@@ -508,8 +646,10 @@ function registerRun(program2) {
|
|
|
508
646
|
...query !== void 0 ? { query } : {}
|
|
509
647
|
});
|
|
510
648
|
} catch (err) {
|
|
511
|
-
|
|
512
|
-
|
|
649
|
+
outputError(
|
|
650
|
+
ExitCode.GENERAL_ERROR,
|
|
651
|
+
`Operation failed: ${err.message}`
|
|
652
|
+
);
|
|
513
653
|
}
|
|
514
654
|
});
|
|
515
655
|
}
|
|
@@ -519,7 +659,9 @@ function registerRefresh(program2) {
|
|
|
519
659
|
program2.command("refresh").description("Force-refresh the local OAS cache from the server").option("--service <name>", "Refresh only a specific service").action(async (opts) => {
|
|
520
660
|
const cfg = getConfig();
|
|
521
661
|
const client = new ServerClient(cfg);
|
|
522
|
-
|
|
662
|
+
if (!isJsonOutput()) {
|
|
663
|
+
console.log("Refreshing OAS list from server...");
|
|
664
|
+
}
|
|
523
665
|
if (opts.service) {
|
|
524
666
|
await clearOASCache(opts.service);
|
|
525
667
|
} else {
|
|
@@ -530,6 +672,10 @@ function registerRefresh(program2) {
|
|
|
530
672
|
const maxTtl = Math.min(...entries.map((e) => e.cacheTtl));
|
|
531
673
|
await writeOASListCache(entries, maxTtl);
|
|
532
674
|
}
|
|
675
|
+
if (isJsonOutput()) {
|
|
676
|
+
outputSuccess({ refreshed: entries.length });
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
533
679
|
console.log(`\u2713 Refreshed ${entries.length} service(s).`);
|
|
534
680
|
});
|
|
535
681
|
}
|
|
@@ -570,7 +716,7 @@ function registerHelp(program2) {
|
|
|
570
716
|
} catch {
|
|
571
717
|
console.error(`Unknown service: ${service}`);
|
|
572
718
|
console.error("Run `ucli services list` to see available services.");
|
|
573
|
-
process.exit(
|
|
719
|
+
process.exit(ExitCode.NOT_FOUND);
|
|
574
720
|
}
|
|
575
721
|
console.log(`
|
|
576
722
|
=== ${entry.name} ===`);
|
|
@@ -604,6 +750,10 @@ DISCOVERY
|
|
|
604
750
|
ucli services info <service>
|
|
605
751
|
Show detailed service info and all available operations.
|
|
606
752
|
|
|
753
|
+
ucli introspect
|
|
754
|
+
Return complete capability manifest in a single call (JSON).
|
|
755
|
+
Ideal for AI agents: includes services, MCP servers, and command reference.
|
|
756
|
+
|
|
607
757
|
ucli help [service]
|
|
608
758
|
Show this guide, or service-specific operations.
|
|
609
759
|
|
|
@@ -616,15 +766,44 @@ EXECUTION
|
|
|
616
766
|
--query <jmespath> Filter response with JMESPath
|
|
617
767
|
--data <json|@file> Request body for POST/PUT/PATCH
|
|
618
768
|
|
|
769
|
+
MCP SERVERS
|
|
770
|
+
ucli mcp list
|
|
771
|
+
List all MCP servers in your group.
|
|
772
|
+
|
|
773
|
+
ucli mcp tools <server>
|
|
774
|
+
List tools available on a MCP server.
|
|
775
|
+
|
|
776
|
+
ucli mcp run <server> <tool> [key=value ...]
|
|
777
|
+
Call a tool on a MCP server.
|
|
778
|
+
|
|
619
779
|
MAINTENANCE
|
|
620
780
|
ucli refresh
|
|
621
781
|
Force-refresh the local OAS cache from the server.
|
|
622
782
|
|
|
783
|
+
ucli doctor
|
|
784
|
+
Check configuration, server connectivity, and token validity.
|
|
785
|
+
|
|
786
|
+
SHELL COMPLETIONS
|
|
787
|
+
eval "$(ucli completions bash)"
|
|
788
|
+
eval "$(ucli completions zsh)"
|
|
789
|
+
ucli completions fish | source
|
|
790
|
+
|
|
791
|
+
GLOBAL FLAGS
|
|
792
|
+
--debug Enable verbose debug logging
|
|
793
|
+
--output json Wrap ALL output in structured JSON envelopes
|
|
794
|
+
(for agent/automation consumption)
|
|
795
|
+
-v, --version Show version number
|
|
796
|
+
|
|
623
797
|
ERRORS
|
|
624
798
|
401 Unauthorized \u2192 Run: ucli configure --server <url> --token <jwt>
|
|
625
799
|
404 Not Found \u2192 Check service name: ucli services list
|
|
626
800
|
4xx Client Error \u2192 Check operation args: ucli services info <service>
|
|
627
801
|
5xx Server Error \u2192 Retry or run: ucli refresh
|
|
802
|
+
|
|
803
|
+
AI AGENT QUICK START
|
|
804
|
+
1. ucli introspect # discover everything in one call
|
|
805
|
+
2. ucli run <svc> <op> [args] # execute operations
|
|
806
|
+
3. Use --output json globally # get structured { success, data/error } envelopes
|
|
628
807
|
`);
|
|
629
808
|
}
|
|
630
809
|
|
|
@@ -635,8 +814,8 @@ function resolve(mod, name) {
|
|
|
635
814
|
throw new Error(`Cannot resolve export "${name}" from module`);
|
|
636
815
|
}
|
|
637
816
|
async function getMcp2cli() {
|
|
638
|
-
const clientMod = await import("./client-
|
|
639
|
-
const runnerMod = await import("./runner-
|
|
817
|
+
const clientMod = await import("./client-LCWUZRZX.js");
|
|
818
|
+
const runnerMod = await import("./runner-HH357SRR.js");
|
|
640
819
|
return {
|
|
641
820
|
createMcpClient: resolve(clientMod, "createMcpClient"),
|
|
642
821
|
getTools: resolve(runnerMod, "getTools"),
|
|
@@ -706,19 +885,27 @@ function registerMcp(program2) {
|
|
|
706
885
|
const cfg = getConfig();
|
|
707
886
|
const client = new ServerClient(cfg);
|
|
708
887
|
const entries = await client.listMCP();
|
|
888
|
+
const safe = entries.map(({ authConfig, ...rest }) => ({
|
|
889
|
+
...rest,
|
|
890
|
+
authConfig: { type: authConfig.type }
|
|
891
|
+
}));
|
|
892
|
+
if (isJsonOutput()) {
|
|
893
|
+
outputSuccess(safe);
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
709
896
|
if (entries.length === 0) {
|
|
710
897
|
console.log("No MCP servers registered in this group.");
|
|
711
898
|
return;
|
|
712
899
|
}
|
|
713
900
|
const format = (opts.format ?? "table").toLowerCase();
|
|
714
901
|
if (format === "json") {
|
|
715
|
-
const safe = entries.map(({ authConfig, ...rest }) => ({
|
|
716
|
-
...rest,
|
|
717
|
-
authConfig: { type: authConfig.type }
|
|
718
|
-
}));
|
|
719
902
|
console.log(JSON.stringify(safe, null, 2));
|
|
720
903
|
return;
|
|
721
904
|
}
|
|
905
|
+
if (format === "yaml") {
|
|
906
|
+
console.log(toYaml(safe));
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
722
909
|
const nameWidth = Math.max(10, ...entries.map((e) => e.name.length));
|
|
723
910
|
console.log(`
|
|
724
911
|
${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
|
|
@@ -729,23 +916,28 @@ ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
|
|
|
729
916
|
}
|
|
730
917
|
console.log();
|
|
731
918
|
});
|
|
732
|
-
mcp.command("tools <server>").description("List tools available on a MCP server").option("--format <fmt>", "Output format: table | json", "table").action(async (serverName, opts) => {
|
|
919
|
+
mcp.command("tools <server>").description("List tools available on a MCP server").option("--format <fmt>", "Output format: table | json | yaml", "table").action(async (serverName, opts) => {
|
|
733
920
|
const cfg = getConfig();
|
|
734
921
|
const client = new ServerClient(cfg);
|
|
735
922
|
let entry;
|
|
736
923
|
try {
|
|
737
924
|
entry = await client.getMCP(serverName);
|
|
738
925
|
} catch {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
926
|
+
outputError(
|
|
927
|
+
ExitCode.NOT_FOUND,
|
|
928
|
+
`Unknown MCP server: ${serverName}`,
|
|
929
|
+
"Run: ucli mcp list to see available servers"
|
|
930
|
+
);
|
|
742
931
|
}
|
|
743
932
|
let tools;
|
|
744
933
|
try {
|
|
745
934
|
tools = await listMcpTools(entry);
|
|
746
935
|
} catch (err) {
|
|
747
|
-
|
|
748
|
-
|
|
936
|
+
outputError(ExitCode.GENERAL_ERROR, `Failed to fetch tools: ${err.message}`);
|
|
937
|
+
}
|
|
938
|
+
if (isJsonOutput()) {
|
|
939
|
+
outputSuccess(tools);
|
|
940
|
+
return;
|
|
749
941
|
}
|
|
750
942
|
if (tools.length === 0) {
|
|
751
943
|
console.log(`No tools found on MCP server "${serverName}".`);
|
|
@@ -756,6 +948,10 @@ ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
|
|
|
756
948
|
console.log(JSON.stringify(tools, null, 2));
|
|
757
949
|
return;
|
|
758
950
|
}
|
|
951
|
+
if (format === "yaml") {
|
|
952
|
+
console.log(toYaml(tools));
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
759
955
|
console.log(`
|
|
760
956
|
Tools on "${serverName}":`);
|
|
761
957
|
console.log("\u2500".repeat(60));
|
|
@@ -772,29 +968,441 @@ Tools on "${serverName}":`);
|
|
|
772
968
|
try {
|
|
773
969
|
entry = await client.getMCP(serverName);
|
|
774
970
|
} catch {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
971
|
+
outputError(
|
|
972
|
+
ExitCode.NOT_FOUND,
|
|
973
|
+
`Unknown MCP server: ${serverName}`,
|
|
974
|
+
"Run: ucli mcp list to see available servers"
|
|
975
|
+
);
|
|
778
976
|
}
|
|
779
977
|
try {
|
|
780
978
|
await runMcpTool(entry, toolName, args);
|
|
781
979
|
} catch (err) {
|
|
782
|
-
|
|
783
|
-
process.exit(1);
|
|
980
|
+
outputError(ExitCode.GENERAL_ERROR, `Tool execution failed: ${err.message}`);
|
|
784
981
|
}
|
|
785
982
|
});
|
|
786
983
|
}
|
|
787
984
|
|
|
985
|
+
// src/lib/errors.ts
|
|
986
|
+
var debugEnabled = false;
|
|
987
|
+
function setDebugMode(enabled) {
|
|
988
|
+
debugEnabled = enabled;
|
|
989
|
+
}
|
|
990
|
+
function debug(message) {
|
|
991
|
+
if (debugEnabled) {
|
|
992
|
+
console.error(`[DEBUG] ${message}`);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
var HINT_MAP = {
|
|
996
|
+
[ExitCode.CONFIG_ERROR]: "Run: ucli configure --server <url> --token <jwt>",
|
|
997
|
+
[ExitCode.AUTH_ERROR]: "Your token may be expired or revoked. Run: ucli configure --server <url> --token <jwt>",
|
|
998
|
+
[ExitCode.CONNECTIVITY_ERROR]: "Check that the server URL is correct and the server is running. Run: ucli doctor",
|
|
999
|
+
[ExitCode.NOT_FOUND]: "Check the resource name. Run: ucli services list or ucli mcp list",
|
|
1000
|
+
[ExitCode.SERVER_ERROR]: "The server returned an unexpected error. Try again or run: ucli doctor"
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
// src/commands/doctor.ts
|
|
1004
|
+
import axios2 from "axios";
|
|
1005
|
+
function registerDoctor(program2) {
|
|
1006
|
+
program2.command("doctor").description("Check configuration, server connectivity, and token validity").action(async () => {
|
|
1007
|
+
const results = [];
|
|
1008
|
+
debug("Checking configuration...");
|
|
1009
|
+
if (!isConfigured()) {
|
|
1010
|
+
results.push({
|
|
1011
|
+
name: "Configuration",
|
|
1012
|
+
ok: false,
|
|
1013
|
+
detail: "Not configured. Run: ucli configure --server <url> --token <jwt>"
|
|
1014
|
+
});
|
|
1015
|
+
outputError(
|
|
1016
|
+
ExitCode.CONFIG_ERROR,
|
|
1017
|
+
"Not configured",
|
|
1018
|
+
"Run: ucli configure --server <url> --token <jwt>"
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
let cfg;
|
|
1022
|
+
try {
|
|
1023
|
+
cfg = getConfig();
|
|
1024
|
+
results.push({
|
|
1025
|
+
name: "Configuration",
|
|
1026
|
+
ok: true,
|
|
1027
|
+
detail: `Server: ${cfg.serverUrl}`
|
|
1028
|
+
});
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
results.push({
|
|
1031
|
+
name: "Configuration",
|
|
1032
|
+
ok: false,
|
|
1033
|
+
detail: `Failed to read config: ${err.message}`
|
|
1034
|
+
});
|
|
1035
|
+
outputError(
|
|
1036
|
+
ExitCode.CONFIG_ERROR,
|
|
1037
|
+
`Failed to read config: ${err.message}`,
|
|
1038
|
+
"Run: ucli configure --server <url> --token <jwt>"
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
debug(`Checking connectivity to ${cfg.serverUrl}...`);
|
|
1042
|
+
try {
|
|
1043
|
+
const healthUrl = `${cfg.serverUrl}/api/v1/health`;
|
|
1044
|
+
const resp = await axios2.get(healthUrl, { timeout: 1e4 });
|
|
1045
|
+
results.push({
|
|
1046
|
+
name: "Server connectivity",
|
|
1047
|
+
ok: resp.status === 200,
|
|
1048
|
+
detail: resp.status === 200 ? `Health endpoint OK (${cfg.serverUrl})` : `Unexpected status: ${resp.status}`
|
|
1049
|
+
});
|
|
1050
|
+
} catch (err) {
|
|
1051
|
+
const msg = axios2.isAxiosError(err) ? err.code ?? err.message : err.message;
|
|
1052
|
+
results.push({
|
|
1053
|
+
name: "Server connectivity",
|
|
1054
|
+
ok: false,
|
|
1055
|
+
detail: `Cannot reach server: ${msg}`
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
debug("Validating JWT token...");
|
|
1059
|
+
try {
|
|
1060
|
+
const client = new ServerClient(cfg);
|
|
1061
|
+
await client.listOAS();
|
|
1062
|
+
results.push({
|
|
1063
|
+
name: "Authentication",
|
|
1064
|
+
ok: true,
|
|
1065
|
+
detail: "Token accepted by server"
|
|
1066
|
+
});
|
|
1067
|
+
} catch (err) {
|
|
1068
|
+
const msg = err.message;
|
|
1069
|
+
results.push({
|
|
1070
|
+
name: "Authentication",
|
|
1071
|
+
ok: false,
|
|
1072
|
+
detail: `Token rejected: ${msg}`
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
const allOk = results.every((r) => r.ok);
|
|
1076
|
+
if (isJsonOutput()) {
|
|
1077
|
+
outputSuccess({
|
|
1078
|
+
healthy: allOk,
|
|
1079
|
+
checks: results
|
|
1080
|
+
});
|
|
1081
|
+
process.exit(allOk ? ExitCode.SUCCESS : ExitCode.GENERAL_ERROR);
|
|
1082
|
+
}
|
|
1083
|
+
printResults(results);
|
|
1084
|
+
process.exit(allOk ? ExitCode.SUCCESS : ExitCode.GENERAL_ERROR);
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
function printResults(results) {
|
|
1088
|
+
console.log("\nucli doctor\n" + "\u2550".repeat(40));
|
|
1089
|
+
for (const r of results) {
|
|
1090
|
+
const icon = r.ok ? "\u2713" : "\u2716";
|
|
1091
|
+
console.log(` ${icon} ${r.name}: ${r.detail}`);
|
|
1092
|
+
}
|
|
1093
|
+
console.log();
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// src/commands/completions.ts
|
|
1097
|
+
function registerCompletions(program2) {
|
|
1098
|
+
program2.command("completions <shell>").description("Generate shell completion script (bash | zsh | fish)").action((shell) => {
|
|
1099
|
+
const normalized = shell.toLowerCase().trim();
|
|
1100
|
+
switch (normalized) {
|
|
1101
|
+
case "bash":
|
|
1102
|
+
console.log(bashCompletions());
|
|
1103
|
+
break;
|
|
1104
|
+
case "zsh":
|
|
1105
|
+
console.log(zshCompletions());
|
|
1106
|
+
break;
|
|
1107
|
+
case "fish":
|
|
1108
|
+
console.log(fishCompletions());
|
|
1109
|
+
break;
|
|
1110
|
+
default:
|
|
1111
|
+
console.error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
|
|
1112
|
+
process.exit(ExitCode.USAGE_ERROR);
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
function bashCompletions() {
|
|
1117
|
+
return `# ucli bash completions \u2014 eval "$(ucli completions bash)"
|
|
1118
|
+
_ucli_completions() {
|
|
1119
|
+
local cur prev commands
|
|
1120
|
+
COMPREPLY=()
|
|
1121
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
1122
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
1123
|
+
commands="configure services run refresh help mcp doctor completions introspect"
|
|
1124
|
+
|
|
1125
|
+
case "\${COMP_WORDS[1]}" in
|
|
1126
|
+
services)
|
|
1127
|
+
COMPREPLY=( $(compgen -W "list info" -- "$cur") )
|
|
1128
|
+
return 0
|
|
1129
|
+
;;
|
|
1130
|
+
mcp)
|
|
1131
|
+
COMPREPLY=( $(compgen -W "list tools run" -- "$cur") )
|
|
1132
|
+
return 0
|
|
1133
|
+
;;
|
|
1134
|
+
completions)
|
|
1135
|
+
COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") )
|
|
1136
|
+
return 0
|
|
1137
|
+
;;
|
|
1138
|
+
run|help)
|
|
1139
|
+
# dynamic completions would require server calls; skip for now
|
|
1140
|
+
return 0
|
|
1141
|
+
;;
|
|
1142
|
+
esac
|
|
1143
|
+
|
|
1144
|
+
if [ "$COMP_CWORD" -eq 1 ]; then
|
|
1145
|
+
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
1146
|
+
fi
|
|
1147
|
+
|
|
1148
|
+
return 0
|
|
1149
|
+
}
|
|
1150
|
+
complete -F _ucli_completions ucli`;
|
|
1151
|
+
}
|
|
1152
|
+
function zshCompletions() {
|
|
1153
|
+
return `# ucli zsh completions \u2014 eval "$(ucli completions zsh)"
|
|
1154
|
+
#compdef ucli
|
|
1155
|
+
|
|
1156
|
+
_ucli() {
|
|
1157
|
+
local -a commands
|
|
1158
|
+
commands=(
|
|
1159
|
+
'configure:Configure server URL and authentication token'
|
|
1160
|
+
'services:Manage and inspect available OAS services'
|
|
1161
|
+
'run:Execute an operation on a service'
|
|
1162
|
+
'refresh:Force-refresh the local OAS cache'
|
|
1163
|
+
'help:Show usage guide'
|
|
1164
|
+
'mcp:Interact with MCP servers'
|
|
1165
|
+
'doctor:Check configuration and connectivity'
|
|
1166
|
+
'completions:Generate shell completion script'
|
|
1167
|
+
'introspect:Return complete capability manifest for AI agents'
|
|
1168
|
+
)
|
|
1169
|
+
|
|
1170
|
+
_arguments -C \\
|
|
1171
|
+
'1: :->command' \\
|
|
1172
|
+
'*::arg:->args'
|
|
1173
|
+
|
|
1174
|
+
case $state in
|
|
1175
|
+
command)
|
|
1176
|
+
_describe -t commands 'ucli commands' commands
|
|
1177
|
+
;;
|
|
1178
|
+
args)
|
|
1179
|
+
case $words[1] in
|
|
1180
|
+
services)
|
|
1181
|
+
_values 'subcommand' 'list[List all OAS services]' 'info[Show service details]'
|
|
1182
|
+
;;
|
|
1183
|
+
mcp)
|
|
1184
|
+
_values 'subcommand' 'list[List MCP servers]' 'tools[List tools]' 'run[Call a tool]'
|
|
1185
|
+
;;
|
|
1186
|
+
completions)
|
|
1187
|
+
_values 'shell' bash zsh fish
|
|
1188
|
+
;;
|
|
1189
|
+
esac
|
|
1190
|
+
;;
|
|
1191
|
+
esac
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
_ucli "$@"`;
|
|
1195
|
+
}
|
|
1196
|
+
function fishCompletions() {
|
|
1197
|
+
return `# ucli fish completions \u2014 ucli completions fish | source
|
|
1198
|
+
complete -c ucli -e
|
|
1199
|
+
|
|
1200
|
+
# Top-level commands
|
|
1201
|
+
complete -c ucli -n __fish_use_subcommand -a configure -d 'Configure server URL and token'
|
|
1202
|
+
complete -c ucli -n __fish_use_subcommand -a services -d 'Manage OAS services'
|
|
1203
|
+
complete -c ucli -n __fish_use_subcommand -a run -d 'Execute a service operation'
|
|
1204
|
+
complete -c ucli -n __fish_use_subcommand -a refresh -d 'Refresh local cache'
|
|
1205
|
+
complete -c ucli -n __fish_use_subcommand -a help -d 'Show usage guide'
|
|
1206
|
+
complete -c ucli -n __fish_use_subcommand -a mcp -d 'Interact with MCP servers'
|
|
1207
|
+
complete -c ucli -n __fish_use_subcommand -a doctor -d 'Check config and connectivity'
|
|
1208
|
+
complete -c ucli -n __fish_use_subcommand -a completions -d 'Generate shell completions'
|
|
1209
|
+
|
|
1210
|
+
complete -c ucli -n __fish_use_subcommand -a introspect -d 'Return capability manifest for AI agents'
|
|
1211
|
+
|
|
1212
|
+
# services subcommands
|
|
1213
|
+
complete -c ucli -n '__fish_seen_subcommand_from services' -a list -d 'List services'
|
|
1214
|
+
complete -c ucli -n '__fish_seen_subcommand_from services' -a info -d 'Show service details'
|
|
1215
|
+
|
|
1216
|
+
# mcp subcommands
|
|
1217
|
+
complete -c ucli -n '__fish_seen_subcommand_from mcp' -a list -d 'List MCP servers'
|
|
1218
|
+
complete -c ucli -n '__fish_seen_subcommand_from mcp' -a tools -d 'List tools'
|
|
1219
|
+
complete -c ucli -n '__fish_seen_subcommand_from mcp' -a run -d 'Call a tool'
|
|
1220
|
+
|
|
1221
|
+
# completions subcommands
|
|
1222
|
+
complete -c ucli -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish' -d 'Shell type'`;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
// src/commands/introspect.ts
|
|
1226
|
+
function registerIntrospect(program2) {
|
|
1227
|
+
program2.command("introspect").description("Return a complete capability manifest for AI agent discovery (services, MCP servers, commands)").option("--format <fmt>", "Output format: json | yaml", "json").action(async (opts) => {
|
|
1228
|
+
const cfg = getConfig();
|
|
1229
|
+
const client = new ServerClient(cfg);
|
|
1230
|
+
let oasEntries = [];
|
|
1231
|
+
let mcpEntries = [];
|
|
1232
|
+
try {
|
|
1233
|
+
;
|
|
1234
|
+
[oasEntries, mcpEntries] = await Promise.all([
|
|
1235
|
+
client.listOAS(),
|
|
1236
|
+
client.listMCP()
|
|
1237
|
+
]);
|
|
1238
|
+
} catch (err) {
|
|
1239
|
+
const message = err.message;
|
|
1240
|
+
outputError(
|
|
1241
|
+
ExitCode.CONNECTIVITY_ERROR,
|
|
1242
|
+
`Failed to fetch capabilities: ${message}`,
|
|
1243
|
+
"Check server connectivity with: ucli doctor"
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
const manifest = {
|
|
1247
|
+
version: "1",
|
|
1248
|
+
services: oasEntries.map(toIntrospectService),
|
|
1249
|
+
mcpServers: mcpEntries.map(toIntrospectMcpServer),
|
|
1250
|
+
commands: getCommandReference()
|
|
1251
|
+
};
|
|
1252
|
+
const format = (opts.format ?? "json").toLowerCase();
|
|
1253
|
+
if (isJsonOutput()) {
|
|
1254
|
+
outputSuccess(manifest);
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
if (format === "json") {
|
|
1258
|
+
console.log(JSON.stringify(manifest, null, 2));
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
if (format === "yaml") {
|
|
1262
|
+
console.log(toYaml(manifest));
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
console.log(JSON.stringify(manifest, null, 2));
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
function toIntrospectService(e) {
|
|
1269
|
+
return {
|
|
1270
|
+
name: e.name,
|
|
1271
|
+
description: e.description,
|
|
1272
|
+
authType: e.authType,
|
|
1273
|
+
remoteUrl: e.remoteUrl,
|
|
1274
|
+
baseEndpoint: e.baseEndpoint,
|
|
1275
|
+
cacheTtl: e.cacheTtl
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
function toIntrospectMcpServer(e) {
|
|
1279
|
+
return {
|
|
1280
|
+
name: e.name,
|
|
1281
|
+
description: e.description,
|
|
1282
|
+
transport: e.transport,
|
|
1283
|
+
enabled: e.enabled
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
function getCommandReference() {
|
|
1287
|
+
return [
|
|
1288
|
+
{
|
|
1289
|
+
name: "services list",
|
|
1290
|
+
description: "List all OAS services available in the current group",
|
|
1291
|
+
usage: "ucli services list [--format json|table|yaml] [--refresh]",
|
|
1292
|
+
examples: [
|
|
1293
|
+
"ucli services list",
|
|
1294
|
+
"ucli services list --format json",
|
|
1295
|
+
"ucli services list --refresh"
|
|
1296
|
+
]
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
name: "services info",
|
|
1300
|
+
description: "Show detailed information and available operations for a service",
|
|
1301
|
+
usage: "ucli services info <name> [--format json|table|yaml]",
|
|
1302
|
+
examples: [
|
|
1303
|
+
"ucli services info payments",
|
|
1304
|
+
"ucli services info payments --format json"
|
|
1305
|
+
]
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
name: "run",
|
|
1309
|
+
description: "Execute an operation on an OAS service",
|
|
1310
|
+
usage: "ucli run <service> <operation> [--format json|table|yaml] [--query <jmespath>] [--data <json|@file>] [--params <json>]",
|
|
1311
|
+
examples: [
|
|
1312
|
+
"ucli run payments listTransactions",
|
|
1313
|
+
"ucli run payments getTransaction --transactionId txn_123",
|
|
1314
|
+
`ucli run payments createCharge --data '{"amount": 5000, "currency": "USD"}'`,
|
|
1315
|
+
'ucli run inventory listProducts --query "items[?stock > `0`].name"'
|
|
1316
|
+
]
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
name: "mcp list",
|
|
1320
|
+
description: "List all MCP servers available in the current group",
|
|
1321
|
+
usage: "ucli mcp list [--format json|table|yaml]",
|
|
1322
|
+
examples: [
|
|
1323
|
+
"ucli mcp list",
|
|
1324
|
+
"ucli mcp list --format json"
|
|
1325
|
+
]
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
name: "mcp tools",
|
|
1329
|
+
description: "List tools available on a MCP server",
|
|
1330
|
+
usage: "ucli mcp tools <server> [--format json|table|yaml]",
|
|
1331
|
+
examples: [
|
|
1332
|
+
"ucli mcp tools weather",
|
|
1333
|
+
"ucli mcp tools weather --format json"
|
|
1334
|
+
]
|
|
1335
|
+
},
|
|
1336
|
+
{
|
|
1337
|
+
name: "mcp run",
|
|
1338
|
+
description: "Call a tool on a MCP server",
|
|
1339
|
+
usage: "ucli mcp run <server> <tool> [key=value ...]",
|
|
1340
|
+
examples: [
|
|
1341
|
+
'ucli mcp run weather get_forecast location="New York"',
|
|
1342
|
+
'ucli mcp run search web_search query="ucli docs" limit=5'
|
|
1343
|
+
]
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
name: "introspect",
|
|
1347
|
+
description: "Return complete capability manifest (this command)",
|
|
1348
|
+
usage: "ucli introspect [--format json|yaml]",
|
|
1349
|
+
examples: [
|
|
1350
|
+
"ucli introspect",
|
|
1351
|
+
"ucli introspect --format yaml"
|
|
1352
|
+
]
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
name: "refresh",
|
|
1356
|
+
description: "Force-refresh the local OAS cache from the server",
|
|
1357
|
+
usage: "ucli refresh [--service <name>]",
|
|
1358
|
+
examples: [
|
|
1359
|
+
"ucli refresh",
|
|
1360
|
+
"ucli refresh --service payments"
|
|
1361
|
+
]
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
name: "doctor",
|
|
1365
|
+
description: "Check configuration, server connectivity, and token validity",
|
|
1366
|
+
usage: "ucli doctor",
|
|
1367
|
+
examples: ["ucli doctor"]
|
|
1368
|
+
},
|
|
1369
|
+
{
|
|
1370
|
+
name: "configure",
|
|
1371
|
+
description: "Configure the server URL and authentication token",
|
|
1372
|
+
usage: "ucli configure --server <url> --token <jwt>",
|
|
1373
|
+
examples: ["ucli configure --server https://oas.example.com --token eyJ..."]
|
|
1374
|
+
}
|
|
1375
|
+
];
|
|
1376
|
+
}
|
|
1377
|
+
|
|
788
1378
|
// src/index.ts
|
|
789
1379
|
var require3 = createRequire2(import.meta.url);
|
|
790
1380
|
var pkg = require3("../package.json");
|
|
791
1381
|
var program = new Command();
|
|
792
|
-
program.name("ucli").description(pkg.description).version(pkg.version, "-v, --version").addHelpCommand(false)
|
|
1382
|
+
program.name("ucli").description(pkg.description).version(pkg.version, "-v, --version").option("--debug", "Enable verbose debug logging").option("--output <mode>", "Output mode: text | json (json wraps every result in a structured envelope for agent consumption)", "text").addHelpCommand(false).hook("preAction", (_thisCommand, actionCommand) => {
|
|
1383
|
+
let cmd = actionCommand;
|
|
1384
|
+
while (cmd) {
|
|
1385
|
+
const opts = cmd.opts();
|
|
1386
|
+
if (opts.debug) {
|
|
1387
|
+
setDebugMode(true);
|
|
1388
|
+
}
|
|
1389
|
+
if (opts.output && typeof opts.output === "string") {
|
|
1390
|
+
const mode = opts.output.toLowerCase();
|
|
1391
|
+
if (mode === "json" || mode === "text") {
|
|
1392
|
+
setOutputMode(mode);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
cmd = cmd.parent;
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
793
1398
|
registerConfigure(program);
|
|
794
1399
|
registerServices(program);
|
|
795
1400
|
registerRun(program);
|
|
796
1401
|
registerRefresh(program);
|
|
797
1402
|
registerMcp(program);
|
|
1403
|
+
registerDoctor(program);
|
|
1404
|
+
registerCompletions(program);
|
|
1405
|
+
registerIntrospect(program);
|
|
798
1406
|
registerHelp(program);
|
|
799
1407
|
program.parse(process.argv);
|
|
800
1408
|
//# sourceMappingURL=index.js.map
|