@tronsfey/ucli 0.4.3 → 0.5.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/dist/index.js CHANGED
@@ -154,6 +154,18 @@ 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
+
157
169
  // src/commands/configure.ts
158
170
  function registerConfigure(program2) {
159
171
  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) => {
@@ -170,7 +182,7 @@ function registerConfigure(program2) {
170
182
  } catch (err) {
171
183
  console.error("Connection failed:", err.message);
172
184
  console.error("Please check the server URL and token.");
173
- process.exit(1);
185
+ process.exit(ExitCode.CONNECTIVITY_ERROR);
174
186
  }
175
187
  });
176
188
  }
@@ -374,6 +386,68 @@ async function getServiceHelp(entry) {
374
386
  });
375
387
  }
376
388
 
389
+ // src/lib/yaml.ts
390
+ function toYaml(value, indent = 0) {
391
+ if (value === null || value === void 0) {
392
+ return "null";
393
+ }
394
+ if (typeof value === "boolean") {
395
+ return value ? "true" : "false";
396
+ }
397
+ if (typeof value === "number") {
398
+ return String(value);
399
+ }
400
+ if (typeof value === "string") {
401
+ if (needsQuoting(value)) {
402
+ return JSON.stringify(value);
403
+ }
404
+ return value;
405
+ }
406
+ if (Array.isArray(value)) {
407
+ if (value.length === 0) return "[]";
408
+ const prefix = " ".repeat(indent);
409
+ return value.map((item) => {
410
+ const serialised = toYaml(item, indent + 2);
411
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
412
+ const firstNewline = serialised.indexOf("\n");
413
+ if (firstNewline === -1) {
414
+ return `${prefix}- ${serialised.trimStart()}`;
415
+ }
416
+ const firstLine = serialised.slice(0, firstNewline);
417
+ const rest = serialised.slice(firstNewline + 1);
418
+ return `${prefix}- ${firstLine.trimStart()}
419
+ ${rest}`;
420
+ }
421
+ return `${prefix}- ${serialised}`;
422
+ }).join("\n");
423
+ }
424
+ if (typeof value === "object") {
425
+ const entries = Object.entries(value);
426
+ if (entries.length === 0) return "{}";
427
+ const prefix = " ".repeat(indent);
428
+ return entries.map(([key, val]) => {
429
+ if (val === null || val === void 0) {
430
+ return `${prefix}${key}: null`;
431
+ }
432
+ if (typeof val === "object") {
433
+ const nested = toYaml(val, indent + 2);
434
+ return `${prefix}${key}:
435
+ ${nested}`;
436
+ }
437
+ return `${prefix}${key}: ${toYaml(val, indent)}`;
438
+ }).join("\n");
439
+ }
440
+ return String(value);
441
+ }
442
+ function needsQuoting(s) {
443
+ if (s === "") return true;
444
+ if (s === "true" || s === "false" || s === "null") return true;
445
+ if (/^\d/.test(s)) return true;
446
+ if (/[:{}\[\],&*#?|<>=!%@`'"\\\n\r\t]/.test(s)) return true;
447
+ if (s.startsWith(" ") || s.endsWith(" ")) return true;
448
+ return false;
449
+ }
450
+
377
451
  // src/commands/services.ts
378
452
  function registerServices(program2) {
379
453
  const services = program2.command("services").description("Manage and inspect available OAS services");
@@ -405,6 +479,14 @@ function registerServices(program2) {
405
479
  console.log(JSON.stringify(safe, null, 2));
406
480
  return;
407
481
  }
482
+ if (format === "yaml") {
483
+ const safe = entries.map(({ authConfig, ...rest }) => ({
484
+ ...rest,
485
+ authConfig: { type: authConfig["type"] ?? rest.authType }
486
+ }));
487
+ console.log(toYaml(safe));
488
+ return;
489
+ }
408
490
  const nameWidth = Math.max(10, ...entries.map((e) => e.name.length));
409
491
  console.log(`
410
492
  ${"SERVICE".padEnd(nameWidth)} AUTH DESCRIPTION`);
@@ -425,7 +507,7 @@ ${"SERVICE".padEnd(nameWidth)} AUTH DESCRIPTION`);
425
507
  } catch (err) {
426
508
  console.error(`Service not found: ${name}`);
427
509
  console.error("Run `ucli services list` to see available services.");
428
- process.exit(1);
510
+ process.exit(ExitCode.NOT_FOUND);
429
511
  }
430
512
  const help = await getServiceHelp(entry);
431
513
  const format = (opts.format ?? "table").toLowerCase();
@@ -439,6 +521,16 @@ ${"SERVICE".padEnd(nameWidth)} AUTH DESCRIPTION`);
439
521
  console.log(JSON.stringify(safe, null, 2));
440
522
  return;
441
523
  }
524
+ if (format === "yaml") {
525
+ const { authConfig, ...rest } = entry;
526
+ const safe = {
527
+ ...rest,
528
+ authConfig: { type: authConfig["type"] ?? rest.authType },
529
+ operationsHelp: help
530
+ };
531
+ console.log(toYaml(safe));
532
+ return;
533
+ }
442
534
  console.log(`
443
535
  Service: ${entry.name}`);
444
536
  console.log(`Description: ${entry.description || "(none)"}`);
@@ -457,12 +549,12 @@ function registerRun(program2) {
457
549
  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
550
  if (serviceArg && opts.service && serviceArg !== opts.service) {
459
551
  console.error(`Conflicting service values: positional "${serviceArg}" and --service "${opts.service}". Use either the positional argument or --service flag, not both.`);
460
- process.exit(1);
552
+ process.exit(ExitCode.USAGE_ERROR);
461
553
  }
462
554
  const service = opts.service ?? serviceArg;
463
555
  if (!service) {
464
556
  console.error("Missing service name. Use positional <service> or --service <name>.");
465
- process.exit(1);
557
+ process.exit(ExitCode.USAGE_ERROR);
466
558
  }
467
559
  const cfg = getConfig();
468
560
  const client = new ServerClient(cfg);
@@ -472,7 +564,7 @@ function registerRun(program2) {
472
564
  } catch {
473
565
  console.error(`Unknown service: ${service}`);
474
566
  console.error("Run `ucli services list` to see available services.");
475
- process.exit(1);
567
+ process.exit(ExitCode.NOT_FOUND);
476
568
  }
477
569
  const extraArgs = opts.args ?? [];
478
570
  const operationArgs = [...args, ...extraArgs];
@@ -485,7 +577,7 @@ function registerRun(program2) {
485
577
  parsed = JSON.parse(opts.params);
486
578
  } catch {
487
579
  console.error(`Invalid --params JSON. Example: --params '{"petId": 1}'`);
488
- process.exit(1);
580
+ process.exit(ExitCode.USAGE_ERROR);
489
581
  }
490
582
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
491
583
  for (const [k, v] of Object.entries(parsed)) {
@@ -509,7 +601,7 @@ function registerRun(program2) {
509
601
  });
510
602
  } catch (err) {
511
603
  console.error("Operation failed:", err.message);
512
- process.exit(1);
604
+ process.exit(ExitCode.GENERAL_ERROR);
513
605
  }
514
606
  });
515
607
  }
@@ -570,7 +662,7 @@ function registerHelp(program2) {
570
662
  } catch {
571
663
  console.error(`Unknown service: ${service}`);
572
664
  console.error("Run `ucli services list` to see available services.");
573
- process.exit(1);
665
+ process.exit(ExitCode.NOT_FOUND);
574
666
  }
575
667
  console.log(`
576
668
  === ${entry.name} ===`);
@@ -620,6 +712,18 @@ MAINTENANCE
620
712
  ucli refresh
621
713
  Force-refresh the local OAS cache from the server.
622
714
 
715
+ ucli doctor
716
+ Check configuration, server connectivity, and token validity.
717
+
718
+ SHELL COMPLETIONS
719
+ eval "$(ucli completions bash)"
720
+ eval "$(ucli completions zsh)"
721
+ ucli completions fish | source
722
+
723
+ GLOBAL FLAGS
724
+ --debug Enable verbose debug logging
725
+ -v, --version Show version number
726
+
623
727
  ERRORS
624
728
  401 Unauthorized \u2192 Run: ucli configure --server <url> --token <jwt>
625
729
  404 Not Found \u2192 Check service name: ucli services list
@@ -719,6 +823,14 @@ function registerMcp(program2) {
719
823
  console.log(JSON.stringify(safe, null, 2));
720
824
  return;
721
825
  }
826
+ if (format === "yaml") {
827
+ const safe = entries.map(({ authConfig, ...rest }) => ({
828
+ ...rest,
829
+ authConfig: { type: authConfig.type }
830
+ }));
831
+ console.log(toYaml(safe));
832
+ return;
833
+ }
722
834
  const nameWidth = Math.max(10, ...entries.map((e) => e.name.length));
723
835
  console.log(`
724
836
  ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
@@ -729,7 +841,7 @@ ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
729
841
  }
730
842
  console.log();
731
843
  });
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) => {
844
+ 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
845
  const cfg = getConfig();
734
846
  const client = new ServerClient(cfg);
735
847
  let entry;
@@ -738,14 +850,14 @@ ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
738
850
  } catch {
739
851
  console.error(`Unknown MCP server: ${serverName}`);
740
852
  console.error("Run `ucli mcp list` to see available servers.");
741
- process.exit(1);
853
+ process.exit(ExitCode.NOT_FOUND);
742
854
  }
743
855
  let tools;
744
856
  try {
745
857
  tools = await listMcpTools(entry);
746
858
  } catch (err) {
747
859
  console.error("Failed to fetch tools:", err.message);
748
- process.exit(1);
860
+ process.exit(ExitCode.GENERAL_ERROR);
749
861
  }
750
862
  if (tools.length === 0) {
751
863
  console.log(`No tools found on MCP server "${serverName}".`);
@@ -756,6 +868,10 @@ ${"SERVER".padEnd(nameWidth)} TRANSPORT DESCRIPTION`);
756
868
  console.log(JSON.stringify(tools, null, 2));
757
869
  return;
758
870
  }
871
+ if (format === "yaml") {
872
+ console.log(toYaml(tools));
873
+ return;
874
+ }
759
875
  console.log(`
760
876
  Tools on "${serverName}":`);
761
877
  console.log("\u2500".repeat(60));
@@ -774,27 +890,262 @@ Tools on "${serverName}":`);
774
890
  } catch {
775
891
  console.error(`Unknown MCP server: ${serverName}`);
776
892
  console.error("Run `ucli mcp list` to see available servers.");
777
- process.exit(1);
893
+ process.exit(ExitCode.NOT_FOUND);
778
894
  }
779
895
  try {
780
896
  await runMcpTool(entry, toolName, args);
781
897
  } catch (err) {
782
898
  console.error("Tool execution failed:", err.message);
783
- process.exit(1);
899
+ process.exit(ExitCode.GENERAL_ERROR);
900
+ }
901
+ });
902
+ }
903
+
904
+ // src/lib/errors.ts
905
+ var debugEnabled = false;
906
+ function setDebugMode(enabled) {
907
+ debugEnabled = enabled;
908
+ }
909
+ function debug(message) {
910
+ if (debugEnabled) {
911
+ console.error(`[DEBUG] ${message}`);
912
+ }
913
+ }
914
+ var HINT_MAP = {
915
+ [ExitCode.CONFIG_ERROR]: "Run: ucli configure --server <url> --token <jwt>",
916
+ [ExitCode.AUTH_ERROR]: "Your token may be expired or revoked. Run: ucli configure --server <url> --token <jwt>",
917
+ [ExitCode.CONNECTIVITY_ERROR]: "Check that the server URL is correct and the server is running. Run: ucli doctor",
918
+ [ExitCode.NOT_FOUND]: "Check the resource name. Run: ucli services list or ucli mcp list",
919
+ [ExitCode.SERVER_ERROR]: "The server returned an unexpected error. Try again or run: ucli doctor"
920
+ };
921
+
922
+ // src/commands/doctor.ts
923
+ import axios2 from "axios";
924
+ function registerDoctor(program2) {
925
+ program2.command("doctor").description("Check configuration, server connectivity, and token validity").action(async () => {
926
+ const results = [];
927
+ debug("Checking configuration...");
928
+ if (!isConfigured()) {
929
+ results.push({
930
+ name: "Configuration",
931
+ ok: false,
932
+ detail: "Not configured. Run: ucli configure --server <url> --token <jwt>"
933
+ });
934
+ printResults(results);
935
+ process.exit(ExitCode.CONFIG_ERROR);
936
+ }
937
+ let cfg;
938
+ try {
939
+ cfg = getConfig();
940
+ results.push({
941
+ name: "Configuration",
942
+ ok: true,
943
+ detail: `Server: ${cfg.serverUrl}`
944
+ });
945
+ } catch (err) {
946
+ results.push({
947
+ name: "Configuration",
948
+ ok: false,
949
+ detail: `Failed to read config: ${err.message}`
950
+ });
951
+ printResults(results);
952
+ process.exit(ExitCode.CONFIG_ERROR);
953
+ }
954
+ debug(`Checking connectivity to ${cfg.serverUrl}...`);
955
+ try {
956
+ const healthUrl = `${cfg.serverUrl}/api/v1/health`;
957
+ const resp = await axios2.get(healthUrl, { timeout: 1e4 });
958
+ results.push({
959
+ name: "Server connectivity",
960
+ ok: resp.status === 200,
961
+ detail: resp.status === 200 ? `Health endpoint OK (${cfg.serverUrl})` : `Unexpected status: ${resp.status}`
962
+ });
963
+ } catch (err) {
964
+ const msg = axios2.isAxiosError(err) ? err.code ?? err.message : err.message;
965
+ results.push({
966
+ name: "Server connectivity",
967
+ ok: false,
968
+ detail: `Cannot reach server: ${msg}`
969
+ });
970
+ }
971
+ debug("Validating JWT token...");
972
+ try {
973
+ const client = new ServerClient(cfg);
974
+ await client.listOAS();
975
+ results.push({
976
+ name: "Authentication",
977
+ ok: true,
978
+ detail: "Token accepted by server"
979
+ });
980
+ } catch (err) {
981
+ const msg = err.message;
982
+ results.push({
983
+ name: "Authentication",
984
+ ok: false,
985
+ detail: `Token rejected: ${msg}`
986
+ });
987
+ }
988
+ printResults(results);
989
+ const allOk = results.every((r) => r.ok);
990
+ process.exit(allOk ? ExitCode.SUCCESS : ExitCode.GENERAL_ERROR);
991
+ });
992
+ }
993
+ function printResults(results) {
994
+ console.log("\nucli doctor\n" + "\u2550".repeat(40));
995
+ for (const r of results) {
996
+ const icon = r.ok ? "\u2713" : "\u2716";
997
+ console.log(` ${icon} ${r.name}: ${r.detail}`);
998
+ }
999
+ console.log();
1000
+ }
1001
+
1002
+ // src/commands/completions.ts
1003
+ function registerCompletions(program2) {
1004
+ program2.command("completions <shell>").description("Generate shell completion script (bash | zsh | fish)").action((shell) => {
1005
+ const normalized = shell.toLowerCase().trim();
1006
+ switch (normalized) {
1007
+ case "bash":
1008
+ console.log(bashCompletions());
1009
+ break;
1010
+ case "zsh":
1011
+ console.log(zshCompletions());
1012
+ break;
1013
+ case "fish":
1014
+ console.log(fishCompletions());
1015
+ break;
1016
+ default:
1017
+ console.error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
1018
+ process.exit(ExitCode.USAGE_ERROR);
784
1019
  }
785
1020
  });
786
1021
  }
1022
+ function bashCompletions() {
1023
+ return `# ucli bash completions \u2014 eval "$(ucli completions bash)"
1024
+ _ucli_completions() {
1025
+ local cur prev commands
1026
+ COMPREPLY=()
1027
+ cur="\${COMP_WORDS[COMP_CWORD]}"
1028
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
1029
+ commands="configure services run refresh help mcp doctor completions"
1030
+
1031
+ case "\${COMP_WORDS[1]}" in
1032
+ services)
1033
+ COMPREPLY=( $(compgen -W "list info" -- "$cur") )
1034
+ return 0
1035
+ ;;
1036
+ mcp)
1037
+ COMPREPLY=( $(compgen -W "list tools run" -- "$cur") )
1038
+ return 0
1039
+ ;;
1040
+ completions)
1041
+ COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") )
1042
+ return 0
1043
+ ;;
1044
+ run|help)
1045
+ # dynamic completions would require server calls; skip for now
1046
+ return 0
1047
+ ;;
1048
+ esac
1049
+
1050
+ if [ "$COMP_CWORD" -eq 1 ]; then
1051
+ COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
1052
+ fi
1053
+
1054
+ return 0
1055
+ }
1056
+ complete -F _ucli_completions ucli`;
1057
+ }
1058
+ function zshCompletions() {
1059
+ return `# ucli zsh completions \u2014 eval "$(ucli completions zsh)"
1060
+ #compdef ucli
1061
+
1062
+ _ucli() {
1063
+ local -a commands
1064
+ commands=(
1065
+ 'configure:Configure server URL and authentication token'
1066
+ 'services:Manage and inspect available OAS services'
1067
+ 'run:Execute an operation on a service'
1068
+ 'refresh:Force-refresh the local OAS cache'
1069
+ 'help:Show usage guide'
1070
+ 'mcp:Interact with MCP servers'
1071
+ 'doctor:Check configuration and connectivity'
1072
+ 'completions:Generate shell completion script'
1073
+ )
1074
+
1075
+ _arguments -C \\
1076
+ '1: :->command' \\
1077
+ '*::arg:->args'
1078
+
1079
+ case $state in
1080
+ command)
1081
+ _describe -t commands 'ucli commands' commands
1082
+ ;;
1083
+ args)
1084
+ case $words[1] in
1085
+ services)
1086
+ _values 'subcommand' 'list[List all OAS services]' 'info[Show service details]'
1087
+ ;;
1088
+ mcp)
1089
+ _values 'subcommand' 'list[List MCP servers]' 'tools[List tools]' 'run[Call a tool]'
1090
+ ;;
1091
+ completions)
1092
+ _values 'shell' bash zsh fish
1093
+ ;;
1094
+ esac
1095
+ ;;
1096
+ esac
1097
+ }
1098
+
1099
+ _ucli "$@"`;
1100
+ }
1101
+ function fishCompletions() {
1102
+ return `# ucli fish completions \u2014 ucli completions fish | source
1103
+ complete -c ucli -e
1104
+
1105
+ # Top-level commands
1106
+ complete -c ucli -n __fish_use_subcommand -a configure -d 'Configure server URL and token'
1107
+ complete -c ucli -n __fish_use_subcommand -a services -d 'Manage OAS services'
1108
+ complete -c ucli -n __fish_use_subcommand -a run -d 'Execute a service operation'
1109
+ complete -c ucli -n __fish_use_subcommand -a refresh -d 'Refresh local cache'
1110
+ complete -c ucli -n __fish_use_subcommand -a help -d 'Show usage guide'
1111
+ complete -c ucli -n __fish_use_subcommand -a mcp -d 'Interact with MCP servers'
1112
+ complete -c ucli -n __fish_use_subcommand -a doctor -d 'Check config and connectivity'
1113
+ complete -c ucli -n __fish_use_subcommand -a completions -d 'Generate shell completions'
1114
+
1115
+ # services subcommands
1116
+ complete -c ucli -n '__fish_seen_subcommand_from services' -a list -d 'List services'
1117
+ complete -c ucli -n '__fish_seen_subcommand_from services' -a info -d 'Show service details'
1118
+
1119
+ # mcp subcommands
1120
+ complete -c ucli -n '__fish_seen_subcommand_from mcp' -a list -d 'List MCP servers'
1121
+ complete -c ucli -n '__fish_seen_subcommand_from mcp' -a tools -d 'List tools'
1122
+ complete -c ucli -n '__fish_seen_subcommand_from mcp' -a run -d 'Call a tool'
1123
+
1124
+ # completions subcommands
1125
+ complete -c ucli -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish' -d 'Shell type'`;
1126
+ }
787
1127
 
788
1128
  // src/index.ts
789
1129
  var require3 = createRequire2(import.meta.url);
790
1130
  var pkg = require3("../package.json");
791
1131
  var program = new Command();
792
- program.name("ucli").description(pkg.description).version(pkg.version, "-v, --version").addHelpCommand(false);
1132
+ program.name("ucli").description(pkg.description).version(pkg.version, "-v, --version").option("--debug", "Enable verbose debug logging").addHelpCommand(false).hook("preAction", (_thisCommand, actionCommand) => {
1133
+ let cmd = actionCommand;
1134
+ while (cmd) {
1135
+ if (cmd.opts().debug) {
1136
+ setDebugMode(true);
1137
+ break;
1138
+ }
1139
+ cmd = cmd.parent;
1140
+ }
1141
+ });
793
1142
  registerConfigure(program);
794
1143
  registerServices(program);
795
1144
  registerRun(program);
796
1145
  registerRefresh(program);
797
1146
  registerMcp(program);
1147
+ registerDoctor(program);
1148
+ registerCompletions(program);
798
1149
  registerHelp(program);
799
1150
  program.parse(process.argv);
800
1151
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/lib/config-encryption.ts","../src/lib/server-client.ts","../src/commands/configure.ts","../src/lib/cache.ts","../src/lib/oas-runner.ts","../src/commands/services.ts","../src/commands/run.ts","../src/commands/refresh.ts","../src/commands/help-cmd.ts","../src/lib/mcp-runner.ts","../src/commands/mcp.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { createRequire } from 'node:module'\nimport { registerConfigure } from './commands/configure.js'\nimport { registerServices } from './commands/services.js'\nimport { registerRun } from './commands/run.js'\nimport { registerRefresh } from './commands/refresh.js'\nimport { registerHelp } from './commands/help-cmd.js'\nimport { registerMcp } from './commands/mcp.js'\n\nconst require = createRequire(import.meta.url)\nconst pkg = require('../package.json') as { version: string; description: string }\n\nconst program = new Command()\n\nprogram\n .name('ucli')\n .description(pkg.description)\n .version(pkg.version, '-v, --version')\n .addHelpCommand(false) // we provide our own help command\n\nregisterConfigure(program)\nregisterServices(program)\nregisterRun(program)\nregisterRefresh(program)\nregisterMcp(program)\nregisterHelp(program)\n\nprogram.parse(process.argv)\n","import Conf from 'conf'\nimport { homedir } from 'node:os'\nimport { join, dirname } from 'node:path'\nimport { chmodSync, mkdirSync } from 'node:fs'\nimport { encryptValue, decryptValue, isEncrypted } from './lib/config-encryption.js'\n\nexport interface CLIConfig {\n serverUrl: string\n token: string\n}\n\nconst conf = new Conf<CLIConfig>({\n projectName: 'ucli',\n schema: {\n serverUrl: { type: 'string' },\n token: { type: 'string' },\n },\n})\n\nexport const cacheDir = join(homedir(), '.cache', 'ucli')\n\n/** Ensure the config file and its directory have restrictive permissions. */\nfunction hardenConfigPermissions(): void {\n try {\n const configPath = conf.path\n const configDir = dirname(configPath)\n mkdirSync(configDir, { recursive: true, mode: 0o700 })\n chmodSync(configDir, 0o700)\n chmodSync(configPath, 0o600)\n } catch {\n // Permission enforcement may fail on some platforms (e.g., Windows)\n console.warn('Warning: Could not enforce restrictive file permissions on config. Token is encrypted but file permissions may be permissive.')\n }\n}\n\nexport function getConfig(): CLIConfig {\n const serverUrl = conf.get('serverUrl')\n const rawToken = conf.get('token')\n\n if (!serverUrl || !rawToken) {\n console.error('ucli is not configured. Run: ucli configure --server <url> --token <jwt>')\n process.exit(1)\n }\n\n const token = decryptValue(rawToken)\n\n // Auto-migrate: re-encrypt legacy plaintext tokens on read\n if (!isEncrypted(rawToken)) {\n conf.set('token', encryptValue(token))\n hardenConfigPermissions()\n }\n\n return { serverUrl, token }\n}\n\nexport function saveConfig(cfg: CLIConfig): void {\n conf.set('serverUrl', cfg.serverUrl)\n conf.set('token', encryptValue(cfg.token))\n hardenConfigPermissions()\n}\n\nexport function isConfigured(): boolean {\n return Boolean(conf.get('serverUrl') && conf.get('token'))\n}\n","/**\n * Config value encryption utilities.\n *\n * Encrypts sensitive config values (e.g., JWT tokens) at rest using AES-256-GCM\n * with a machine-specific derived key. This ensures credentials are never stored\n * in plaintext on disk.\n *\n * Key derivation: PBKDF2(username + hostname, random-salt, 100k iterations, SHA-512)\n * Format: \"enc:v1:<base64(salt + iv + authTag + ciphertext)>\"\n */\nimport {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n pbkdf2Sync,\n} from 'node:crypto'\nimport { hostname, userInfo } from 'node:os'\n\nconst ENC_PREFIX = 'enc:v1:'\nconst ALGORITHM = 'aes-256-gcm'\nconst SALT_LEN = 32\nconst IV_LEN = 12\nconst TAG_LEN = 16\nconst PBKDF2_ITERATIONS = 100_000\n\n/** Derive a 256-bit key from machine-specific identity + per-value random salt. */\nfunction deriveKey(salt: Buffer): Buffer {\n let user = 'default'\n try {\n user = userInfo().username\n } catch {\n // userInfo() may throw on some platforms (e.g., certain containers)\n }\n const material = `ucli:${user}@${hostname()}`\n return pbkdf2Sync(material, salt, PBKDF2_ITERATIONS, 32, 'sha512')\n}\n\n/** Encrypt a plaintext string. Returns prefixed ciphertext string. */\nexport function encryptValue(plaintext: string): string {\n const salt = randomBytes(SALT_LEN)\n const key = deriveKey(salt)\n const iv = randomBytes(IV_LEN)\n const cipher = createCipheriv(ALGORITHM, key, iv)\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n const tag = cipher.getAuthTag()\n const packed = Buffer.concat([salt, iv, tag, encrypted])\n return ENC_PREFIX + packed.toString('base64')\n}\n\n/**\n * Decrypt a stored value. If the value has the encryption prefix, it is\n * decrypted; otherwise it is returned as-is for backward compatibility\n * with legacy plaintext configs.\n */\nexport function decryptValue(stored: string): string {\n if (!stored.startsWith(ENC_PREFIX)) {\n return stored\n }\n const packed = Buffer.from(stored.slice(ENC_PREFIX.length), 'base64')\n const salt = packed.subarray(0, SALT_LEN)\n const iv = packed.subarray(SALT_LEN, SALT_LEN + IV_LEN)\n const tag = packed.subarray(SALT_LEN + IV_LEN, SALT_LEN + IV_LEN + TAG_LEN)\n const encrypted = packed.subarray(SALT_LEN + IV_LEN + TAG_LEN)\n const key = deriveKey(salt)\n const decipher = createDecipheriv(ALGORITHM, key, iv)\n decipher.setAuthTag(tag)\n return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString('utf8')\n}\n\n/** Check whether a stored value is encrypted (has the encryption prefix). */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(ENC_PREFIX)\n}\n","/**\n * HTTP client for the ucli-server API.\n * Attaches group JWT and handles common error cases.\n */\nimport axios, { type AxiosInstance } from 'axios'\nimport type { CLIConfig } from '../config.js'\n\nexport interface OASEntryPublic {\n id: string\n name: string\n description: string\n remoteUrl: string\n baseEndpoint: string | null\n authType: 'bearer' | 'api_key' | 'basic' | 'oauth2_cc' | 'none'\n authConfig: Record<string, unknown>\n cacheTtl: number\n}\n\nexport type McpAuthConfig =\n | { type: 'none' }\n | { type: 'http_headers'; headers: Record<string, string> }\n | { type: 'env'; env: Record<string, string> }\n\nexport interface McpEntryPublic {\n id: string\n groupId: string\n name: string\n description: string\n transport: 'http' | 'stdio'\n serverUrl: string | null\n command: string | null\n authConfig: McpAuthConfig\n enabled: boolean\n}\n\nexport class ServerClient {\n private http: AxiosInstance\n\n constructor(cfg: CLIConfig) {\n this.http = axios.create({\n baseURL: cfg.serverUrl.replace(/\\/$/, ''),\n headers: {\n Authorization: `Bearer ${cfg.token}`,\n 'Content-Type': 'application/json',\n },\n timeout: 15_000,\n })\n\n this.http.interceptors.response.use(\n (r) => r,\n (err: unknown) => {\n if (axios.isAxiosError(err)) {\n const status = err.response?.status\n const message = (err.response?.data as { message?: string })?.message ?? err.message\n\n if (status === 401) {\n console.error('Authentication failed. Run: ucli configure --server <url> --token <jwt>')\n process.exit(1)\n }\n\n throw new Error(`Server error ${status ?? 'unknown'}: ${message}`)\n }\n throw err\n },\n )\n }\n\n async listOAS(): Promise<OASEntryPublic[]> {\n const { data } = await this.http.get<OASEntryPublic[]>('/api/v1/oas')\n return data\n }\n\n async getOAS(name: string): Promise<OASEntryPublic> {\n const { data } = await this.http.get<OASEntryPublic>(`/api/v1/oas/${encodeURIComponent(name)}`)\n return data\n }\n\n async listMCP(): Promise<McpEntryPublic[]> {\n const { data } = await this.http.get<McpEntryPublic[]>('/api/v1/mcp')\n return data\n }\n\n async getMCP(name: string): Promise<McpEntryPublic> {\n const { data } = await this.http.get<McpEntryPublic>(`/api/v1/mcp/${encodeURIComponent(name)}`)\n return data\n }\n}\n","import type { Command } from 'commander'\nimport { saveConfig, isConfigured } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\n\nexport function registerConfigure(program: Command): void {\n program\n .command('configure')\n .description('Configure the OAS Gateway server URL and authentication token')\n .requiredOption('--server <url>', 'OAS Gateway server URL (e.g. https://oas.example.com)')\n .requiredOption('--token <jwt>', 'Group JWT token issued by the server admin')\n .action(async (opts: { server: string; token: string }) => {\n const serverUrl = opts.server.replace(/\\/$/, '')\n const token = opts.token\n\n // Validate connectivity before saving\n console.log(`Connecting to ${serverUrl}...`)\n const client = new ServerClient({ serverUrl, token })\n\n try {\n await client.listOAS()\n saveConfig({ serverUrl, token })\n console.log('✓ Configuration saved successfully.')\n console.log(` Server: ${serverUrl}`)\n console.log(` Token: ${token.slice(0, 20)}...`)\n } catch (err) {\n console.error('Connection failed:', (err as Error).message)\n console.error('Please check the server URL and token.')\n process.exit(1)\n }\n })\n}\n","/**\n * Local file cache for OAS entries.\n * Stored at ~/.cache/oas-cli/<name>.json with TTL metadata.\n *\n * Security: authConfig credential values are stripped before writing.\n * Only { type } is persisted — full secrets are never written to disk.\n */\nimport { readFile, writeFile, mkdir, unlink, chmod } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { cacheDir } from '../config.js'\nimport type { OASEntryPublic } from './server-client.js'\n\ninterface CacheFile {\n entries: OASEntryPublic[]\n fetchedAt: number // ms timestamp\n ttlSec: number // cache duration\n}\n\nconst LIST_CACHE_FILE = join(cacheDir, 'oas-list.json')\n\nasync function ensureCacheDir(): Promise<void> {\n await mkdir(cacheDir, { recursive: true, mode: 0o700 })\n}\n\n/** Strip credential secrets from authConfig — only persist { type }. */\nfunction redactEntries(entries: OASEntryPublic[]): OASEntryPublic[] {\n return entries.map((e) => ({\n ...e,\n authConfig: { type: (e.authConfig as Record<string, unknown>)['type'] ?? e.authType },\n }))\n}\n\nexport async function readOASListCache(): Promise<OASEntryPublic[] | null> {\n try {\n const raw = await readFile(LIST_CACHE_FILE, 'utf8')\n const cached: CacheFile = JSON.parse(raw)\n const age = (Date.now() - cached.fetchedAt) / 1000\n if (cached.ttlSec === 0 || age > cached.ttlSec) return null // expired\n return cached.entries\n } catch {\n return null // not found or parse error\n }\n}\n\nexport async function writeOASListCache(entries: OASEntryPublic[], ttlSec: number): Promise<void> {\n await ensureCacheDir()\n const cached: CacheFile = { entries: redactEntries(entries), fetchedAt: Date.now(), ttlSec }\n await writeFile(LIST_CACHE_FILE, JSON.stringify(cached, null, 2), { encoding: 'utf8', mode: 0o600 })\n await chmod(LIST_CACHE_FILE, 0o600)\n}\n\nexport async function clearOASListCache(): Promise<void> {\n try {\n await unlink(LIST_CACHE_FILE)\n } catch {\n // ignore if not found\n }\n}\n\nexport async function clearOASCache(name: string): Promise<void> {\n try {\n const raw = await readFile(LIST_CACHE_FILE, 'utf8')\n const cached: CacheFile = JSON.parse(raw)\n const entries = Array.isArray(cached.entries) ? cached.entries.filter((e) => e.name !== name) : []\n if (entries.length === 0) {\n await clearOASListCache()\n return\n }\n const next: CacheFile = {\n entries,\n fetchedAt: cached.fetchedAt ?? Date.now(),\n ttlSec: cached.ttlSec ?? 0,\n }\n await writeFile(LIST_CACHE_FILE, JSON.stringify(next, null, 2), { encoding: 'utf8', mode: 0o600 })\n } catch {\n await clearOASListCache()\n }\n}\n","/**\n * Bridge between oas-cli and @tronsfey/openapi2cli run mode.\n *\n * Spawns openapi2cli as a child process, injecting auth config\n * as environment variables (never exposed to the agent's shell).\n */\nimport { spawn } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport { join, dirname } from 'node:path'\nimport type { OASEntryPublic } from './server-client.js'\n\nconst require = createRequire(import.meta.url)\n\nfunction resolveOpenapi2CliBin(): string {\n try {\n const pkgPath = require.resolve('@tronsfey/openapi2cli/package.json')\n const pkgDir = dirname(pkgPath)\n // @tronsfey/openapi2cli exposes its binary; find it\n const pkg = require('@tronsfey/openapi2cli/package.json') as { bin?: Record<string, string> }\n const binEntry = pkg.bin?.['openapi2cli'] ?? 'bin/openapi2cli.js'\n return join(pkgDir, binEntry)\n } catch {\n throw new Error(\n '@tronsfey/openapi2cli is not installed. Run: pnpm add @tronsfey/openapi2cli in packages/cli',\n )\n }\n}\n\nexport interface RunOptions {\n entry: OASEntryPublic\n /** Operation command args (e.g. ['listPets', '--limit', '10']) */\n operationArgs: string[]\n format?: 'json' | 'table' | 'yaml'\n query?: string\n}\n\n/**\n * Build auth environment variables for injection into child process.\n * The calling shell (and thus the AI agent) never sees these values.\n */\nfunction buildAuthEnv(entry: OASEntryPublic): Record<string, string> {\n const cfg = entry.authConfig\n const prefix = entry.name.toUpperCase().replace(/[^A-Z0-9]/g, '_')\n\n switch (cfg['type']) {\n case 'bearer':\n return { [`${prefix}_TOKEN`]: cfg['token'] as string }\n\n case 'api_key':\n return { [`${prefix}_API_KEY`]: cfg['key'] as string }\n\n case 'basic':\n return { [`${prefix}_CREDENTIALS`]: `${cfg['username']}:${cfg['password']}` }\n\n case 'oauth2_cc':\n return {\n [`${prefix}_CLIENT_ID`]: cfg['clientId'] as string,\n [`${prefix}_CLIENT_SECRET`]: cfg['clientSecret'] as string,\n [`${prefix}_SCOPES`]: (cfg['scopes'] as string[]).join(' '),\n }\n\n default:\n return {}\n }\n}\n\n/**\n * Environment variable allowlist for subprocess execution.\n * Only these variables (when present in the parent) are forwarded to the\n * child process. This prevents leakage of secrets such as cloud credentials,\n * encryption keys, or database passwords that may be in the parent env.\n */\nconst SAFE_ENV_KEYS: readonly string[] = [\n // System essentials\n 'PATH', 'HOME', 'USER', 'LOGNAME', 'SHELL', 'TMPDIR', 'TMP', 'TEMP',\n // Terminal / display\n 'TERM', 'COLORTERM', 'NO_COLOR', 'FORCE_COLOR', 'LANG', 'LC_ALL',\n 'LC_CTYPE', 'LC_MESSAGES', 'LC_COLLATE',\n // Node.js\n 'NODE_ENV', 'NODE_PATH', 'NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS',\n // Network proxy (required for tools behind corporate proxies)\n 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY',\n 'http_proxy', 'https_proxy', 'no_proxy',\n // OS-specific\n 'SYSTEMROOT', 'COMSPEC', 'APPDATA', 'LOCALAPPDATA', 'PROGRAMFILES',\n 'XDG_RUNTIME_DIR', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME',\n]\n\nfunction buildSafeEnv(authEnv: Record<string, string>): Record<string, string> {\n const safe: Record<string, string> = {}\n for (const key of SAFE_ENV_KEYS) {\n if (process.env[key] !== undefined) {\n safe[key] = process.env[key]!\n }\n }\n return { ...safe, ...authEnv }\n}\n\nexport async function runOperation(opts: RunOptions): Promise<void> {\n const bin = resolveOpenapi2CliBin()\n const { entry, operationArgs, format, query } = opts\n\n const args = [\n 'run',\n '--oas', entry.remoteUrl,\n '--cache-ttl', String(entry.cacheTtl),\n ...(entry.baseEndpoint ? ['--endpoint', entry.baseEndpoint] : []),\n ...(format ? ['--format', format] : []),\n ...(query ? ['--query', query] : []),\n ...operationArgs,\n ]\n\n const authEnv = buildAuthEnv(entry)\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(process.execPath, [bin, ...args], {\n stdio: 'inherit',\n env: buildSafeEnv(authEnv),\n })\n\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`openapi2cli exited with code ${code}`))\n })\n child.on('error', reject)\n })\n}\n\n/**\n * Get list of available operations for a service by running `--help`.\n * Returns the raw help text from openapi2cli.\n */\nexport async function getServiceHelp(entry: OASEntryPublic): Promise<string> {\n const bin = resolveOpenapi2CliBin()\n const args = [\n 'run',\n '--oas', entry.remoteUrl,\n '--cache-ttl', String(entry.cacheTtl),\n '--help',\n ]\n\n return new Promise<string>((resolve, reject) => {\n let output = ''\n const child = spawn(process.execPath, [bin, ...args], {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n child.stdout?.on('data', (d: Buffer) => { output += d.toString() })\n child.stderr?.on('data', (d: Buffer) => { output += d.toString() })\n child.on('close', () => resolve(output))\n child.on('error', reject)\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { readOASListCache, writeOASListCache } from '../lib/cache.js'\nimport { getServiceHelp } from '../lib/oas-runner.js'\n\nexport function registerServices(program: Command): void {\n const services = program\n .command('services')\n .description('Manage and inspect available OAS services')\n\n // services list\n services\n .command('list')\n .description('List all OAS services available in the current group')\n .option('--refresh', 'Bypass local cache and fetch fresh from server')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .option('--no-cache', 'Bypass local cache and fetch fresh from server')\n .action(async (opts: { cache: boolean; refresh?: boolean; format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n if (!opts.cache) {\n process.emitWarning('The --no-cache flag is deprecated. Please use --refresh instead.')\n }\n\n const useCache = opts.cache && !opts.refresh\n let entries = useCache ? await readOASListCache() : null\n\n if (!entries) {\n entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n\n if (entries.length === 0) {\n console.log('No services registered in this group.')\n return\n }\n\n if (format === 'json') {\n // Strip authConfig secrets from JSON output — only expose { type }\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n }))\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n const nameWidth = Math.max(10, ...entries.map((e) => e.name.length))\n console.log(`\\n${'SERVICE'.padEnd(nameWidth)} AUTH DESCRIPTION`)\n console.log(`${'-'.repeat(nameWidth)} -------- ${'-'.repeat(40)}`)\n for (const e of entries) {\n const auth = e.authType.padEnd(8)\n const desc = e.description.length > 60 ? e.description.slice(0, 57) + '...' : e.description\n console.log(`${e.name.padEnd(nameWidth)} ${auth} ${desc}`)\n }\n console.log()\n })\n\n // services info <name>\n services\n .command('info <name>')\n .description('Show detailed information and available operations for a service')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .action(async (name: string, opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(name)\n } catch (err) {\n console.error(`Service not found: ${name}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(1)\n }\n\n const help = await getServiceHelp(entry)\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n // Strip authConfig secrets from JSON output\n const { authConfig, ...rest } = entry\n const safe = {\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n operationsHelp: help,\n }\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n console.log(`\\nService: ${entry.name}`)\n console.log(`Description: ${entry.description || '(none)'}`)\n console.log(`OAS URL: ${entry.remoteUrl}`)\n if (entry.baseEndpoint) console.log(`Base endpoint: ${entry.baseEndpoint}`)\n console.log(`Auth type: ${entry.authType}`)\n console.log(`Cache TTL: ${entry.cacheTtl}s`)\n console.log('\\nAvailable operations:')\n console.log('─'.repeat(60))\n console.log(help)\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { runOperation } from '../lib/oas-runner.js'\n\nexport function registerRun(program: Command): void {\n program\n .command('run [service] [args...]')\n .description('Execute an operation on a service')\n .option('--service <name>', 'Service name (from `services list`)')\n .option('--operation <id>', 'OperationId to execute')\n .option('--params <json>', 'JSON string of operation parameters')\n .option('--format <fmt>', 'Output format: json | table | yaml', 'json')\n .option('--query <jmespath>', 'Filter response with JMESPath expression')\n .option('--data <json>', 'Request body (JSON string or @filename)')\n .allowUnknownOption(true)\n .action(async (\n serviceArg: string | undefined,\n args: string[],\n opts: { service?: string; operation?: string; params?: string; format?: string; query?: string; data?: string; args?: string[] },\n ) => {\n if (serviceArg && opts.service && serviceArg !== opts.service) {\n console.error(`Conflicting service values: positional \"${serviceArg}\" and --service \"${opts.service}\". Use either the positional argument or --service flag, not both.`)\n process.exit(1)\n }\n\n const service = opts.service ?? serviceArg\n if (!service) {\n console.error('Missing service name. Use positional <service> or --service <name>.')\n process.exit(1)\n }\n\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(service)\n } catch {\n console.error(`Unknown service: ${service}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(1)\n }\n\n // Collect extra args (pass-through to openapi2cli)\n const extraArgs = opts.args ?? []\n const operationArgs = [...args, ...extraArgs]\n\n if (opts.operation) {\n operationArgs.unshift(opts.operation)\n }\n\n if (opts.params) {\n let parsed: unknown\n try {\n parsed = JSON.parse(opts.params)\n } catch {\n console.error('Invalid --params JSON. Example: --params \\'{\"petId\": 1}\\'')\n process.exit(1)\n }\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {\n if (v === undefined || v === null) continue\n const strVal = typeof v === 'object' ? JSON.stringify(v) : String(v)\n operationArgs.push(`--${k}`, strVal)\n }\n }\n }\n\n if (opts.data) {\n operationArgs.push('--data', opts.data)\n }\n\n const format = opts.format as 'json' | 'table' | 'yaml' | undefined\n const query = opts.query as string | undefined\n\n try {\n await runOperation({\n entry,\n operationArgs,\n ...(format !== undefined ? { format } : {}),\n ...(query !== undefined ? { query } : {}),\n })\n } catch (err) {\n console.error('Operation failed:', (err as Error).message)\n process.exit(1)\n }\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { writeOASListCache, clearOASListCache, clearOASCache } from '../lib/cache.js'\n\nexport function registerRefresh(program: Command): void {\n program\n .command('refresh')\n .description('Force-refresh the local OAS cache from the server')\n .option('--service <name>', 'Refresh only a specific service')\n .action(async (opts: { service?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n console.log('Refreshing OAS list from server...')\n if (opts.service) {\n await clearOASCache(opts.service)\n } else {\n await clearOASListCache()\n }\n\n const entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n\n console.log(`✓ Refreshed ${entries.length} service(s).`)\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig, isConfigured } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { readOASListCache, writeOASListCache } from '../lib/cache.js'\nimport { getServiceHelp } from '../lib/oas-runner.js'\n\nexport function registerHelp(program: Command): void {\n program\n .command('help [service]')\n .description('Show usage guide. Pass a service name for service-specific operations.')\n .action(async (service?: string) => {\n if (!service) {\n printGeneralHelp()\n if (isConfigured()) {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n let entries = await readOASListCache()\n if (!entries) {\n entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n }\n if (entries.length > 0) {\n console.log('\\nAvailable services:')\n for (const e of entries) {\n console.log(` ${e.name.padEnd(20)} ${e.description}`)\n }\n console.log('\\nTip: Run `ucli help <service>` for service-specific operations.')\n }\n } else {\n console.log('\\nRun `ucli configure --server <url> --token <jwt>` to get started.')\n }\n return\n }\n\n // Service-specific help\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(service)\n } catch {\n console.error(`Unknown service: ${service}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(1)\n }\n\n console.log(`\\n=== ${entry.name} ===`)\n console.log(`${entry.description}`)\n console.log(`\\nOAS spec: ${entry.remoteUrl}`)\n console.log('\\nOperations:')\n console.log('─'.repeat(60))\n\n const help = await getServiceHelp(entry)\n console.log(help)\n\n console.log('\\nExamples:')\n console.log(` ucli run ${entry.name} <operation>`)\n console.log(` ucli run ${entry.name} <operation> --format table`)\n console.log(` ucli run ${entry.name} <operation> --query \"results[*].id\"`)\n console.log(` ucli run ${entry.name} <operation> --data '{\"key\":\"value\"}'`)\n })\n}\n\nfunction printGeneralHelp(): void {\n console.log(`\nucli — OpenAPI & MCP Gateway for AI Agents\n════════════════════════════════════════\n\nSETUP\n ucli configure --server <url> --token <jwt>\n Configure server connection and authentication.\n\nDISCOVERY\n ucli services list\n List all OAS services available in your group.\n\n ucli services info <service>\n Show detailed service info and all available operations.\n\n ucli help [service]\n Show this guide, or service-specific operations.\n\nEXECUTION\n ucli run <service> <operation> [options]\n Execute a service operation.\n\n Options:\n --format json|table|yaml Output format (default: json)\n --query <jmespath> Filter response with JMESPath\n --data <json|@file> Request body for POST/PUT/PATCH\n\nMAINTENANCE\n ucli refresh\n Force-refresh the local OAS cache from the server.\n\nERRORS\n 401 Unauthorized → Run: ucli configure --server <url> --token <jwt>\n 404 Not Found → Check service name: ucli services list\n 4xx Client Error → Check operation args: ucli services info <service>\n 5xx Server Error → Retry or run: ucli refresh\n`)\n}\n","/**\n * MCP tool runner using @tronsfey/mcp2cli programmatic API.\n *\n * Auth credentials are injected via McpServerConfig (headers or env) —\n * never passed as CLI arguments (which would be visible in `ps`).\n */\nimport type { McpEntryPublic } from './server-client.js'\n\n/**\n * Resolve a named export from a module that may be CJS-wrapped (exports live\n * under `module.default`) or a plain ESM module (named exports at top level).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction resolve(mod: any, name: string): unknown {\n if (typeof mod[name] === 'function') return mod[name]\n if (mod.default && typeof mod.default[name] === 'function') return mod.default[name]\n throw new Error(`Cannot resolve export \"${name}\" from module`)\n}\n\nasync function getMcp2cli() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const clientMod = await import('@tronsfey/mcp2cli/dist/client/index.js') as any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const runnerMod = await import('@tronsfey/mcp2cli/dist/runner/index.js') as any\n return {\n createMcpClient: resolve(clientMod, 'createMcpClient') as (...args: unknown[]) => Promise<unknown>,\n getTools: resolve(runnerMod, 'getTools') as (...args: unknown[]) => Promise<{ name: string; description?: string }[]>,\n runTool: resolve(runnerMod, 'runTool') as (...args: unknown[]) => Promise<void>,\n }\n}\n\nasync function closeClient(client: unknown): Promise<void> {\n if (typeof (client as { close?: unknown }).close === 'function') {\n await (client as { close: () => Promise<void> }).close()\n }\n}\n\nfunction buildMcpConfig(entry: McpEntryPublic): Record<string, unknown> {\n const base: Record<string, unknown> = { type: entry.transport }\n if (entry.transport === 'http') {\n base.url = entry.serverUrl\n } else {\n base.command = entry.command\n }\n const auth = entry.authConfig\n if (auth.type === 'http_headers') {\n base.headers = auth.headers\n } else if (auth.type === 'env') {\n base.env = auth.env\n }\n return base\n}\n\nexport async function listMcpTools(entry: McpEntryPublic): Promise<{ name: string; description?: string }[]> {\n const { createMcpClient, getTools } = await getMcp2cli()\n const config = buildMcpConfig(entry)\n const client = await createMcpClient(config)\n try {\n const tools = await getTools(client, config, { noCache: true })\n return tools\n } finally {\n await closeClient(client)\n }\n}\n\nexport async function runMcpTool(entry: McpEntryPublic, toolName: string, rawArgs: string[]): Promise<void> {\n const { createMcpClient, getTools, runTool } = await getMcp2cli()\n const config = buildMcpConfig(entry)\n const client = await createMcpClient(config)\n try {\n const tools = await getTools(client, config, { noCache: false, cacheTtl: 3600 })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tool = tools.find((t: any) => t.name === toolName)\n if (!tool) throw new Error(`Tool \"${toolName}\" not found on MCP server \"${entry.name}\"`)\n const normalizedArgs: string[] = []\n for (const arg of rawArgs) {\n if (arg.includes('=') && !arg.startsWith('--')) {\n const idx = arg.indexOf('=')\n const key = arg.slice(0, idx)\n const value = arg.slice(idx + 1)\n normalizedArgs.push(`--${key}`, value)\n } else {\n normalizedArgs.push(arg)\n }\n }\n await runTool(client, tool, normalizedArgs, {})\n } finally {\n await closeClient(client)\n }\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { listMcpTools, runMcpTool } from '../lib/mcp-runner.js'\n\nexport function registerMcp(program: Command): void {\n const mcp = program\n .command('mcp')\n .description('Interact with MCP servers registered in your group')\n\n // mcp list\n mcp\n .command('list')\n .description('List all MCP servers available in the current group')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .action(async (opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n const entries = await client.listMCP()\n\n if (entries.length === 0) {\n console.log('No MCP servers registered in this group.')\n return\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n // Strip authConfig secrets from JSON output — only expose { type }\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: authConfig.type },\n }))\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n const nameWidth = Math.max(10, ...entries.map(e => e.name.length))\n console.log(`\\n${'SERVER'.padEnd(nameWidth)} TRANSPORT DESCRIPTION`)\n console.log(`${'-'.repeat(nameWidth)} --------- ${'-'.repeat(40)}`)\n for (const e of entries) {\n const desc = e.description.length > 60 ? e.description.slice(0, 57) + '...' : e.description\n console.log(`${e.name.padEnd(nameWidth)} ${e.transport.padEnd(9)} ${desc}`)\n }\n console.log()\n })\n\n // mcp tools <server>\n mcp\n .command('tools <server>')\n .description('List tools available on a MCP server')\n .option('--format <fmt>', 'Output format: table | json', 'table')\n .action(async (serverName: string, opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getMCP(serverName)\n } catch {\n console.error(`Unknown MCP server: ${serverName}`)\n console.error('Run `ucli mcp list` to see available servers.')\n process.exit(1)\n }\n\n let tools\n try {\n tools = await listMcpTools(entry)\n } catch (err) {\n console.error('Failed to fetch tools:', (err as Error).message)\n process.exit(1)\n }\n\n if (tools.length === 0) {\n console.log(`No tools found on MCP server \"${serverName}\".`)\n return\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n console.log(JSON.stringify(tools, null, 2))\n return\n }\n\n console.log(`\\nTools on \"${serverName}\":`)\n console.log('─'.repeat(60))\n for (const t of tools) {\n console.log(` ${t.name}`)\n if (t.description) console.log(` ${t.description}`)\n }\n console.log()\n })\n\n // mcp run <server> <tool> [args...]\n mcp\n .command('run <server> <tool> [args...]')\n .description('Call a tool on a MCP server')\n .action(async (serverName: string, toolName: string, args: string[]) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getMCP(serverName)\n } catch {\n console.error(`Unknown MCP server: ${serverName}`)\n console.error('Run `ucli mcp list` to see available servers.')\n process.exit(1)\n }\n\n try {\n await runMcpTool(entry, toolName, args)\n } catch (err) {\n console.error('Tool execution failed:', (err as Error).message)\n process.exit(1)\n }\n })\n}\n"],"mappings":"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","names":["createRequire","program","join","join","join","dirname","require","pkg","resolve","program","program","program","program","cfg","client","program","require","createRequire"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/lib/config-encryption.ts","../src/lib/server-client.ts","../src/lib/exit-codes.ts","../src/commands/configure.ts","../src/lib/cache.ts","../src/lib/oas-runner.ts","../src/lib/yaml.ts","../src/commands/services.ts","../src/commands/run.ts","../src/commands/refresh.ts","../src/commands/help-cmd.ts","../src/lib/mcp-runner.ts","../src/commands/mcp.ts","../src/lib/errors.ts","../src/commands/doctor.ts","../src/commands/completions.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { createRequire } from 'node:module'\nimport { registerConfigure } from './commands/configure.js'\nimport { registerServices } from './commands/services.js'\nimport { registerRun } from './commands/run.js'\nimport { registerRefresh } from './commands/refresh.js'\nimport { registerHelp } from './commands/help-cmd.js'\nimport { registerMcp } from './commands/mcp.js'\nimport { registerDoctor } from './commands/doctor.js'\nimport { registerCompletions } from './commands/completions.js'\nimport { setDebugMode } from './lib/errors.js'\n\nconst require = createRequire(import.meta.url)\nconst pkg = require('../package.json') as { version: string; description: string }\n\nconst program = new Command()\n\nprogram\n .name('ucli')\n .description(pkg.description)\n .version(pkg.version, '-v, --version')\n .option('--debug', 'Enable verbose debug logging')\n .addHelpCommand(false) // we provide our own help command\n .hook('preAction', (_thisCommand, actionCommand) => {\n // Walk up to root to find the --debug flag\n let cmd = actionCommand\n while (cmd) {\n if ((cmd.opts() as Record<string, unknown>).debug) {\n setDebugMode(true)\n break\n }\n cmd = cmd.parent as Command\n }\n })\n\nregisterConfigure(program)\nregisterServices(program)\nregisterRun(program)\nregisterRefresh(program)\nregisterMcp(program)\nregisterDoctor(program)\nregisterCompletions(program)\nregisterHelp(program)\n\nprogram.parse(process.argv)\n","import Conf from 'conf'\nimport { homedir } from 'node:os'\nimport { join, dirname } from 'node:path'\nimport { chmodSync, mkdirSync } from 'node:fs'\nimport { encryptValue, decryptValue, isEncrypted } from './lib/config-encryption.js'\n\nexport interface CLIConfig {\n serverUrl: string\n token: string\n}\n\nconst conf = new Conf<CLIConfig>({\n projectName: 'ucli',\n schema: {\n serverUrl: { type: 'string' },\n token: { type: 'string' },\n },\n})\n\nexport const cacheDir = join(homedir(), '.cache', 'ucli')\n\n/** Ensure the config file and its directory have restrictive permissions. */\nfunction hardenConfigPermissions(): void {\n try {\n const configPath = conf.path\n const configDir = dirname(configPath)\n mkdirSync(configDir, { recursive: true, mode: 0o700 })\n chmodSync(configDir, 0o700)\n chmodSync(configPath, 0o600)\n } catch {\n // Permission enforcement may fail on some platforms (e.g., Windows)\n console.warn('Warning: Could not enforce restrictive file permissions on config. Token is encrypted but file permissions may be permissive.')\n }\n}\n\nexport function getConfig(): CLIConfig {\n const serverUrl = conf.get('serverUrl')\n const rawToken = conf.get('token')\n\n if (!serverUrl || !rawToken) {\n console.error('ucli is not configured. Run: ucli configure --server <url> --token <jwt>')\n process.exit(1)\n }\n\n const token = decryptValue(rawToken)\n\n // Auto-migrate: re-encrypt legacy plaintext tokens on read\n if (!isEncrypted(rawToken)) {\n conf.set('token', encryptValue(token))\n hardenConfigPermissions()\n }\n\n return { serverUrl, token }\n}\n\nexport function saveConfig(cfg: CLIConfig): void {\n conf.set('serverUrl', cfg.serverUrl)\n conf.set('token', encryptValue(cfg.token))\n hardenConfigPermissions()\n}\n\nexport function isConfigured(): boolean {\n return Boolean(conf.get('serverUrl') && conf.get('token'))\n}\n","/**\n * Config value encryption utilities.\n *\n * Encrypts sensitive config values (e.g., JWT tokens) at rest using AES-256-GCM\n * with a machine-specific derived key. This ensures credentials are never stored\n * in plaintext on disk.\n *\n * Key derivation: PBKDF2(username + hostname, random-salt, 100k iterations, SHA-512)\n * Format: \"enc:v1:<base64(salt + iv + authTag + ciphertext)>\"\n */\nimport {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n pbkdf2Sync,\n} from 'node:crypto'\nimport { hostname, userInfo } from 'node:os'\n\nconst ENC_PREFIX = 'enc:v1:'\nconst ALGORITHM = 'aes-256-gcm'\nconst SALT_LEN = 32\nconst IV_LEN = 12\nconst TAG_LEN = 16\nconst PBKDF2_ITERATIONS = 100_000\n\n/** Derive a 256-bit key from machine-specific identity + per-value random salt. */\nfunction deriveKey(salt: Buffer): Buffer {\n let user = 'default'\n try {\n user = userInfo().username\n } catch {\n // userInfo() may throw on some platforms (e.g., certain containers)\n }\n const material = `ucli:${user}@${hostname()}`\n return pbkdf2Sync(material, salt, PBKDF2_ITERATIONS, 32, 'sha512')\n}\n\n/** Encrypt a plaintext string. Returns prefixed ciphertext string. */\nexport function encryptValue(plaintext: string): string {\n const salt = randomBytes(SALT_LEN)\n const key = deriveKey(salt)\n const iv = randomBytes(IV_LEN)\n const cipher = createCipheriv(ALGORITHM, key, iv)\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n const tag = cipher.getAuthTag()\n const packed = Buffer.concat([salt, iv, tag, encrypted])\n return ENC_PREFIX + packed.toString('base64')\n}\n\n/**\n * Decrypt a stored value. If the value has the encryption prefix, it is\n * decrypted; otherwise it is returned as-is for backward compatibility\n * with legacy plaintext configs.\n */\nexport function decryptValue(stored: string): string {\n if (!stored.startsWith(ENC_PREFIX)) {\n return stored\n }\n const packed = Buffer.from(stored.slice(ENC_PREFIX.length), 'base64')\n const salt = packed.subarray(0, SALT_LEN)\n const iv = packed.subarray(SALT_LEN, SALT_LEN + IV_LEN)\n const tag = packed.subarray(SALT_LEN + IV_LEN, SALT_LEN + IV_LEN + TAG_LEN)\n const encrypted = packed.subarray(SALT_LEN + IV_LEN + TAG_LEN)\n const key = deriveKey(salt)\n const decipher = createDecipheriv(ALGORITHM, key, iv)\n decipher.setAuthTag(tag)\n return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString('utf8')\n}\n\n/** Check whether a stored value is encrypted (has the encryption prefix). */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(ENC_PREFIX)\n}\n","/**\n * HTTP client for the ucli-server API.\n * Attaches group JWT and handles common error cases.\n */\nimport axios, { type AxiosInstance } from 'axios'\nimport type { CLIConfig } from '../config.js'\n\nexport interface OASEntryPublic {\n id: string\n name: string\n description: string\n remoteUrl: string\n baseEndpoint: string | null\n authType: 'bearer' | 'api_key' | 'basic' | 'oauth2_cc' | 'none'\n authConfig: Record<string, unknown>\n cacheTtl: number\n}\n\nexport type McpAuthConfig =\n | { type: 'none' }\n | { type: 'http_headers'; headers: Record<string, string> }\n | { type: 'env'; env: Record<string, string> }\n\nexport interface McpEntryPublic {\n id: string\n groupId: string\n name: string\n description: string\n transport: 'http' | 'stdio'\n serverUrl: string | null\n command: string | null\n authConfig: McpAuthConfig\n enabled: boolean\n}\n\nexport class ServerClient {\n private http: AxiosInstance\n\n constructor(cfg: CLIConfig) {\n this.http = axios.create({\n baseURL: cfg.serverUrl.replace(/\\/$/, ''),\n headers: {\n Authorization: `Bearer ${cfg.token}`,\n 'Content-Type': 'application/json',\n },\n timeout: 15_000,\n })\n\n this.http.interceptors.response.use(\n (r) => r,\n (err: unknown) => {\n if (axios.isAxiosError(err)) {\n const status = err.response?.status\n const message = (err.response?.data as { message?: string })?.message ?? err.message\n\n if (status === 401) {\n console.error('Authentication failed. Run: ucli configure --server <url> --token <jwt>')\n process.exit(1)\n }\n\n throw new Error(`Server error ${status ?? 'unknown'}: ${message}`)\n }\n throw err\n },\n )\n }\n\n async listOAS(): Promise<OASEntryPublic[]> {\n const { data } = await this.http.get<OASEntryPublic[]>('/api/v1/oas')\n return data\n }\n\n async getOAS(name: string): Promise<OASEntryPublic> {\n const { data } = await this.http.get<OASEntryPublic>(`/api/v1/oas/${encodeURIComponent(name)}`)\n return data\n }\n\n async listMCP(): Promise<McpEntryPublic[]> {\n const { data } = await this.http.get<McpEntryPublic[]>('/api/v1/mcp')\n return data\n }\n\n async getMCP(name: string): Promise<McpEntryPublic> {\n const { data } = await this.http.get<McpEntryPublic>(`/api/v1/mcp/${encodeURIComponent(name)}`)\n return data\n }\n}\n","/**\n * Structured exit codes for automation and scripting.\n *\n * Convention:\n * 0 — success\n * 1 — general / unknown error\n * 2 — usage / argument error\n * 3 — configuration error (missing or invalid config)\n * 4 — authentication error (invalid / expired token)\n * 5 — connectivity error (server unreachable)\n * 6 — not-found error (service / resource doesn't exist)\n * 7 — server error (5xx from upstream)\n */\n\nexport const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n CONFIG_ERROR: 3,\n AUTH_ERROR: 4,\n CONNECTIVITY_ERROR: 5,\n NOT_FOUND: 6,\n SERVER_ERROR: 7,\n} as const\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode]\n","import type { Command } from 'commander'\nimport { saveConfig, isConfigured } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerConfigure(program: Command): void {\n program\n .command('configure')\n .description('Configure the OAS Gateway server URL and authentication token')\n .requiredOption('--server <url>', 'OAS Gateway server URL (e.g. https://oas.example.com)')\n .requiredOption('--token <jwt>', 'Group JWT token issued by the server admin')\n .action(async (opts: { server: string; token: string }) => {\n const serverUrl = opts.server.replace(/\\/$/, '')\n const token = opts.token\n\n // Validate connectivity before saving\n console.log(`Connecting to ${serverUrl}...`)\n const client = new ServerClient({ serverUrl, token })\n\n try {\n await client.listOAS()\n saveConfig({ serverUrl, token })\n console.log('✓ Configuration saved successfully.')\n console.log(` Server: ${serverUrl}`)\n console.log(` Token: ${token.slice(0, 20)}...`)\n } catch (err) {\n console.error('Connection failed:', (err as Error).message)\n console.error('Please check the server URL and token.')\n process.exit(ExitCode.CONNECTIVITY_ERROR)\n }\n })\n}\n","/**\n * Local file cache for OAS entries.\n * Stored at ~/.cache/oas-cli/<name>.json with TTL metadata.\n *\n * Security: authConfig credential values are stripped before writing.\n * Only { type } is persisted — full secrets are never written to disk.\n */\nimport { readFile, writeFile, mkdir, unlink, chmod } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { cacheDir } from '../config.js'\nimport type { OASEntryPublic } from './server-client.js'\n\ninterface CacheFile {\n entries: OASEntryPublic[]\n fetchedAt: number // ms timestamp\n ttlSec: number // cache duration\n}\n\nconst LIST_CACHE_FILE = join(cacheDir, 'oas-list.json')\n\nasync function ensureCacheDir(): Promise<void> {\n await mkdir(cacheDir, { recursive: true, mode: 0o700 })\n}\n\n/** Strip credential secrets from authConfig — only persist { type }. */\nfunction redactEntries(entries: OASEntryPublic[]): OASEntryPublic[] {\n return entries.map((e) => ({\n ...e,\n authConfig: { type: (e.authConfig as Record<string, unknown>)['type'] ?? e.authType },\n }))\n}\n\nexport async function readOASListCache(): Promise<OASEntryPublic[] | null> {\n try {\n const raw = await readFile(LIST_CACHE_FILE, 'utf8')\n const cached: CacheFile = JSON.parse(raw)\n const age = (Date.now() - cached.fetchedAt) / 1000\n if (cached.ttlSec === 0 || age > cached.ttlSec) return null // expired\n return cached.entries\n } catch {\n return null // not found or parse error\n }\n}\n\nexport async function writeOASListCache(entries: OASEntryPublic[], ttlSec: number): Promise<void> {\n await ensureCacheDir()\n const cached: CacheFile = { entries: redactEntries(entries), fetchedAt: Date.now(), ttlSec }\n await writeFile(LIST_CACHE_FILE, JSON.stringify(cached, null, 2), { encoding: 'utf8', mode: 0o600 })\n await chmod(LIST_CACHE_FILE, 0o600)\n}\n\nexport async function clearOASListCache(): Promise<void> {\n try {\n await unlink(LIST_CACHE_FILE)\n } catch {\n // ignore if not found\n }\n}\n\nexport async function clearOASCache(name: string): Promise<void> {\n try {\n const raw = await readFile(LIST_CACHE_FILE, 'utf8')\n const cached: CacheFile = JSON.parse(raw)\n const entries = Array.isArray(cached.entries) ? cached.entries.filter((e) => e.name !== name) : []\n if (entries.length === 0) {\n await clearOASListCache()\n return\n }\n const next: CacheFile = {\n entries,\n fetchedAt: cached.fetchedAt ?? Date.now(),\n ttlSec: cached.ttlSec ?? 0,\n }\n await writeFile(LIST_CACHE_FILE, JSON.stringify(next, null, 2), { encoding: 'utf8', mode: 0o600 })\n } catch {\n await clearOASListCache()\n }\n}\n","/**\n * Bridge between oas-cli and @tronsfey/openapi2cli run mode.\n *\n * Spawns openapi2cli as a child process, injecting auth config\n * as environment variables (never exposed to the agent's shell).\n */\nimport { spawn } from 'node:child_process'\nimport { createRequire } from 'node:module'\nimport { join, dirname } from 'node:path'\nimport type { OASEntryPublic } from './server-client.js'\n\nconst require = createRequire(import.meta.url)\n\nfunction resolveOpenapi2CliBin(): string {\n try {\n const pkgPath = require.resolve('@tronsfey/openapi2cli/package.json')\n const pkgDir = dirname(pkgPath)\n // @tronsfey/openapi2cli exposes its binary; find it\n const pkg = require('@tronsfey/openapi2cli/package.json') as { bin?: Record<string, string> }\n const binEntry = pkg.bin?.['openapi2cli'] ?? 'bin/openapi2cli.js'\n return join(pkgDir, binEntry)\n } catch {\n throw new Error(\n '@tronsfey/openapi2cli is not installed. Run: pnpm add @tronsfey/openapi2cli in packages/cli',\n )\n }\n}\n\nexport interface RunOptions {\n entry: OASEntryPublic\n /** Operation command args (e.g. ['listPets', '--limit', '10']) */\n operationArgs: string[]\n format?: 'json' | 'table' | 'yaml'\n query?: string\n}\n\n/**\n * Build auth environment variables for injection into child process.\n * The calling shell (and thus the AI agent) never sees these values.\n */\nfunction buildAuthEnv(entry: OASEntryPublic): Record<string, string> {\n const cfg = entry.authConfig\n const prefix = entry.name.toUpperCase().replace(/[^A-Z0-9]/g, '_')\n\n switch (cfg['type']) {\n case 'bearer':\n return { [`${prefix}_TOKEN`]: cfg['token'] as string }\n\n case 'api_key':\n return { [`${prefix}_API_KEY`]: cfg['key'] as string }\n\n case 'basic':\n return { [`${prefix}_CREDENTIALS`]: `${cfg['username']}:${cfg['password']}` }\n\n case 'oauth2_cc':\n return {\n [`${prefix}_CLIENT_ID`]: cfg['clientId'] as string,\n [`${prefix}_CLIENT_SECRET`]: cfg['clientSecret'] as string,\n [`${prefix}_SCOPES`]: (cfg['scopes'] as string[]).join(' '),\n }\n\n default:\n return {}\n }\n}\n\n/**\n * Environment variable allowlist for subprocess execution.\n * Only these variables (when present in the parent) are forwarded to the\n * child process. This prevents leakage of secrets such as cloud credentials,\n * encryption keys, or database passwords that may be in the parent env.\n */\nconst SAFE_ENV_KEYS: readonly string[] = [\n // System essentials\n 'PATH', 'HOME', 'USER', 'LOGNAME', 'SHELL', 'TMPDIR', 'TMP', 'TEMP',\n // Terminal / display\n 'TERM', 'COLORTERM', 'NO_COLOR', 'FORCE_COLOR', 'LANG', 'LC_ALL',\n 'LC_CTYPE', 'LC_MESSAGES', 'LC_COLLATE',\n // Node.js\n 'NODE_ENV', 'NODE_PATH', 'NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS',\n // Network proxy (required for tools behind corporate proxies)\n 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY',\n 'http_proxy', 'https_proxy', 'no_proxy',\n // OS-specific\n 'SYSTEMROOT', 'COMSPEC', 'APPDATA', 'LOCALAPPDATA', 'PROGRAMFILES',\n 'XDG_RUNTIME_DIR', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME',\n]\n\nfunction buildSafeEnv(authEnv: Record<string, string>): Record<string, string> {\n const safe: Record<string, string> = {}\n for (const key of SAFE_ENV_KEYS) {\n if (process.env[key] !== undefined) {\n safe[key] = process.env[key]!\n }\n }\n return { ...safe, ...authEnv }\n}\n\nexport async function runOperation(opts: RunOptions): Promise<void> {\n const bin = resolveOpenapi2CliBin()\n const { entry, operationArgs, format, query } = opts\n\n const args = [\n 'run',\n '--oas', entry.remoteUrl,\n '--cache-ttl', String(entry.cacheTtl),\n ...(entry.baseEndpoint ? ['--endpoint', entry.baseEndpoint] : []),\n ...(format ? ['--format', format] : []),\n ...(query ? ['--query', query] : []),\n ...operationArgs,\n ]\n\n const authEnv = buildAuthEnv(entry)\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(process.execPath, [bin, ...args], {\n stdio: 'inherit',\n env: buildSafeEnv(authEnv),\n })\n\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`openapi2cli exited with code ${code}`))\n })\n child.on('error', reject)\n })\n}\n\n/**\n * Get list of available operations for a service by running `--help`.\n * Returns the raw help text from openapi2cli.\n */\nexport async function getServiceHelp(entry: OASEntryPublic): Promise<string> {\n const bin = resolveOpenapi2CliBin()\n const args = [\n 'run',\n '--oas', entry.remoteUrl,\n '--cache-ttl', String(entry.cacheTtl),\n '--help',\n ]\n\n return new Promise<string>((resolve, reject) => {\n let output = ''\n const child = spawn(process.execPath, [bin, ...args], {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n child.stdout?.on('data', (d: Buffer) => { output += d.toString() })\n child.stderr?.on('data', (d: Buffer) => { output += d.toString() })\n child.on('close', () => resolve(output))\n child.on('error', reject)\n })\n}\n","/**\n * YAML output format support.\n *\n * A lightweight YAML serialiser that covers the data shapes produced by\n * ucli commands (plain objects, arrays, strings, numbers, booleans, null).\n * No external dependencies — we don't need a full YAML parser, only output.\n */\n\n/** Convert a JSON-serialisable value to a YAML string. */\nexport function toYaml(value: unknown, indent = 0): string {\n if (value === null || value === undefined) {\n return 'null'\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n\n if (typeof value === 'number') {\n return String(value)\n }\n\n if (typeof value === 'string') {\n // Use quotes if the string contains special YAML characters\n if (needsQuoting(value)) {\n return JSON.stringify(value)\n }\n return value\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]'\n const prefix = ' '.repeat(indent)\n return value\n .map((item) => {\n const serialised = toYaml(item, indent + 2)\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n // Object items: put the first key on the same line as the dash\n const firstNewline = serialised.indexOf('\\n')\n if (firstNewline === -1) {\n return `${prefix}- ${serialised.trimStart()}`\n }\n const firstLine = serialised.slice(0, firstNewline)\n const rest = serialised.slice(firstNewline + 1)\n return `${prefix}- ${firstLine.trimStart()}\\n${rest}`\n }\n return `${prefix}- ${serialised}`\n })\n .join('\\n')\n }\n\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.length === 0) return '{}'\n const prefix = ' '.repeat(indent)\n return entries\n .map(([key, val]) => {\n if (val === null || val === undefined) {\n return `${prefix}${key}: null`\n }\n if (typeof val === 'object') {\n const nested = toYaml(val, indent + 2)\n return `${prefix}${key}:\\n${nested}`\n }\n return `${prefix}${key}: ${toYaml(val, indent)}`\n })\n .join('\\n')\n }\n\n return String(value)\n}\n\nfunction needsQuoting(s: string): boolean {\n if (s === '') return true\n if (s === 'true' || s === 'false' || s === 'null') return true\n if (/^\\d/.test(s)) return true\n if (/[:{}\\[\\],&*#?|<>=!%@`'\"\\\\\\n\\r\\t]/.test(s)) return true\n if (s.startsWith(' ') || s.endsWith(' ')) return true\n return false\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { readOASListCache, writeOASListCache } from '../lib/cache.js'\nimport { getServiceHelp } from '../lib/oas-runner.js'\nimport { toYaml } from '../lib/yaml.js'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerServices(program: Command): void {\n const services = program\n .command('services')\n .description('Manage and inspect available OAS services')\n\n // services list\n services\n .command('list')\n .description('List all OAS services available in the current group')\n .option('--refresh', 'Bypass local cache and fetch fresh from server')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .option('--no-cache', 'Bypass local cache and fetch fresh from server')\n .action(async (opts: { cache: boolean; refresh?: boolean; format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n if (!opts.cache) {\n process.emitWarning('The --no-cache flag is deprecated. Please use --refresh instead.')\n }\n\n const useCache = opts.cache && !opts.refresh\n let entries = useCache ? await readOASListCache() : null\n\n if (!entries) {\n entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n\n if (entries.length === 0) {\n console.log('No services registered in this group.')\n return\n }\n\n if (format === 'json') {\n // Strip authConfig secrets from JSON output — only expose { type }\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n }))\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n if (format === 'yaml') {\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n }))\n console.log(toYaml(safe))\n return\n }\n\n const nameWidth = Math.max(10, ...entries.map((e) => e.name.length))\n console.log(`\\n${'SERVICE'.padEnd(nameWidth)} AUTH DESCRIPTION`)\n console.log(`${'-'.repeat(nameWidth)} -------- ${'-'.repeat(40)}`)\n for (const e of entries) {\n const auth = e.authType.padEnd(8)\n const desc = e.description.length > 60 ? e.description.slice(0, 57) + '...' : e.description\n console.log(`${e.name.padEnd(nameWidth)} ${auth} ${desc}`)\n }\n console.log()\n })\n\n // services info <name>\n services\n .command('info <name>')\n .description('Show detailed information and available operations for a service')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .action(async (name: string, opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(name)\n } catch (err) {\n console.error(`Service not found: ${name}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(ExitCode.NOT_FOUND)\n }\n\n const help = await getServiceHelp(entry)\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n // Strip authConfig secrets from JSON output\n const { authConfig, ...rest } = entry\n const safe = {\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n operationsHelp: help,\n }\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n if (format === 'yaml') {\n const { authConfig, ...rest } = entry\n const safe = {\n ...rest,\n authConfig: { type: (authConfig as Record<string, unknown>)['type'] ?? rest.authType },\n operationsHelp: help,\n }\n console.log(toYaml(safe))\n return\n }\n\n console.log(`\\nService: ${entry.name}`)\n console.log(`Description: ${entry.description || '(none)'}`)\n console.log(`OAS URL: ${entry.remoteUrl}`)\n if (entry.baseEndpoint) console.log(`Base endpoint: ${entry.baseEndpoint}`)\n console.log(`Auth type: ${entry.authType}`)\n console.log(`Cache TTL: ${entry.cacheTtl}s`)\n console.log('\\nAvailable operations:')\n console.log('─'.repeat(60))\n console.log(help)\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { runOperation } from '../lib/oas-runner.js'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerRun(program: Command): void {\n program\n .command('run [service] [args...]')\n .description('Execute an operation on a service')\n .option('--service <name>', 'Service name (from `services list`)')\n .option('--operation <id>', 'OperationId to execute')\n .option('--params <json>', 'JSON string of operation parameters')\n .option('--format <fmt>', 'Output format: json | table | yaml', 'json')\n .option('--query <jmespath>', 'Filter response with JMESPath expression')\n .option('--data <json>', 'Request body (JSON string or @filename)')\n .allowUnknownOption(true)\n .action(async (\n serviceArg: string | undefined,\n args: string[],\n opts: { service?: string; operation?: string; params?: string; format?: string; query?: string; data?: string; args?: string[] },\n ) => {\n if (serviceArg && opts.service && serviceArg !== opts.service) {\n console.error(`Conflicting service values: positional \"${serviceArg}\" and --service \"${opts.service}\". Use either the positional argument or --service flag, not both.`)\n process.exit(ExitCode.USAGE_ERROR)\n }\n\n const service = opts.service ?? serviceArg\n if (!service) {\n console.error('Missing service name. Use positional <service> or --service <name>.')\n process.exit(ExitCode.USAGE_ERROR)\n }\n\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(service)\n } catch {\n console.error(`Unknown service: ${service}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(ExitCode.NOT_FOUND)\n }\n\n // Collect extra args (pass-through to openapi2cli)\n const extraArgs = opts.args ?? []\n const operationArgs = [...args, ...extraArgs]\n\n if (opts.operation) {\n operationArgs.unshift(opts.operation)\n }\n\n if (opts.params) {\n let parsed: unknown\n try {\n parsed = JSON.parse(opts.params)\n } catch {\n console.error('Invalid --params JSON. Example: --params \\'{\"petId\": 1}\\'')\n process.exit(ExitCode.USAGE_ERROR)\n }\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {\n if (v === undefined || v === null) continue\n const strVal = typeof v === 'object' ? JSON.stringify(v) : String(v)\n operationArgs.push(`--${k}`, strVal)\n }\n }\n }\n\n if (opts.data) {\n operationArgs.push('--data', opts.data)\n }\n\n const format = opts.format as 'json' | 'table' | 'yaml' | undefined\n const query = opts.query as string | undefined\n\n try {\n await runOperation({\n entry,\n operationArgs,\n ...(format !== undefined ? { format } : {}),\n ...(query !== undefined ? { query } : {}),\n })\n } catch (err) {\n console.error('Operation failed:', (err as Error).message)\n process.exit(ExitCode.GENERAL_ERROR)\n }\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { writeOASListCache, clearOASListCache, clearOASCache } from '../lib/cache.js'\n\nexport function registerRefresh(program: Command): void {\n program\n .command('refresh')\n .description('Force-refresh the local OAS cache from the server')\n .option('--service <name>', 'Refresh only a specific service')\n .action(async (opts: { service?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n console.log('Refreshing OAS list from server...')\n if (opts.service) {\n await clearOASCache(opts.service)\n } else {\n await clearOASListCache()\n }\n\n const entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n\n console.log(`✓ Refreshed ${entries.length} service(s).`)\n })\n}\n","import type { Command } from 'commander'\nimport { getConfig, isConfigured } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { readOASListCache, writeOASListCache } from '../lib/cache.js'\nimport { getServiceHelp } from '../lib/oas-runner.js'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerHelp(program: Command): void {\n program\n .command('help [service]')\n .description('Show usage guide. Pass a service name for service-specific operations.')\n .action(async (service?: string) => {\n if (!service) {\n printGeneralHelp()\n if (isConfigured()) {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n let entries = await readOASListCache()\n if (!entries) {\n entries = await client.listOAS()\n if (entries.length > 0) {\n const maxTtl = Math.min(...entries.map((e) => e.cacheTtl))\n await writeOASListCache(entries, maxTtl)\n }\n }\n if (entries.length > 0) {\n console.log('\\nAvailable services:')\n for (const e of entries) {\n console.log(` ${e.name.padEnd(20)} ${e.description}`)\n }\n console.log('\\nTip: Run `ucli help <service>` for service-specific operations.')\n }\n } else {\n console.log('\\nRun `ucli configure --server <url> --token <jwt>` to get started.')\n }\n return\n }\n\n // Service-specific help\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getOAS(service)\n } catch {\n console.error(`Unknown service: ${service}`)\n console.error('Run `ucli services list` to see available services.')\n process.exit(ExitCode.NOT_FOUND)\n }\n\n console.log(`\\n=== ${entry.name} ===`)\n console.log(`${entry.description}`)\n console.log(`\\nOAS spec: ${entry.remoteUrl}`)\n console.log('\\nOperations:')\n console.log('─'.repeat(60))\n\n const help = await getServiceHelp(entry)\n console.log(help)\n\n console.log('\\nExamples:')\n console.log(` ucli run ${entry.name} <operation>`)\n console.log(` ucli run ${entry.name} <operation> --format table`)\n console.log(` ucli run ${entry.name} <operation> --query \"results[*].id\"`)\n console.log(` ucli run ${entry.name} <operation> --data '{\"key\":\"value\"}'`)\n })\n}\n\nfunction printGeneralHelp(): void {\n console.log(`\nucli — OpenAPI & MCP Gateway for AI Agents\n════════════════════════════════════════\n\nSETUP\n ucli configure --server <url> --token <jwt>\n Configure server connection and authentication.\n\nDISCOVERY\n ucli services list\n List all OAS services available in your group.\n\n ucli services info <service>\n Show detailed service info and all available operations.\n\n ucli help [service]\n Show this guide, or service-specific operations.\n\nEXECUTION\n ucli run <service> <operation> [options]\n Execute a service operation.\n\n Options:\n --format json|table|yaml Output format (default: json)\n --query <jmespath> Filter response with JMESPath\n --data <json|@file> Request body for POST/PUT/PATCH\n\nMAINTENANCE\n ucli refresh\n Force-refresh the local OAS cache from the server.\n\n ucli doctor\n Check configuration, server connectivity, and token validity.\n\nSHELL COMPLETIONS\n eval \"$(ucli completions bash)\"\n eval \"$(ucli completions zsh)\"\n ucli completions fish | source\n\nGLOBAL FLAGS\n --debug Enable verbose debug logging\n -v, --version Show version number\n\nERRORS\n 401 Unauthorized → Run: ucli configure --server <url> --token <jwt>\n 404 Not Found → Check service name: ucli services list\n 4xx Client Error → Check operation args: ucli services info <service>\n 5xx Server Error → Retry or run: ucli refresh\n`)\n}\n","/**\n * MCP tool runner using @tronsfey/mcp2cli programmatic API.\n *\n * Auth credentials are injected via McpServerConfig (headers or env) —\n * never passed as CLI arguments (which would be visible in `ps`).\n */\nimport type { McpEntryPublic } from './server-client.js'\n\n/**\n * Resolve a named export from a module that may be CJS-wrapped (exports live\n * under `module.default`) or a plain ESM module (named exports at top level).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction resolve(mod: any, name: string): unknown {\n if (typeof mod[name] === 'function') return mod[name]\n if (mod.default && typeof mod.default[name] === 'function') return mod.default[name]\n throw new Error(`Cannot resolve export \"${name}\" from module`)\n}\n\nasync function getMcp2cli() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const clientMod = await import('@tronsfey/mcp2cli/dist/client/index.js') as any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const runnerMod = await import('@tronsfey/mcp2cli/dist/runner/index.js') as any\n return {\n createMcpClient: resolve(clientMod, 'createMcpClient') as (...args: unknown[]) => Promise<unknown>,\n getTools: resolve(runnerMod, 'getTools') as (...args: unknown[]) => Promise<{ name: string; description?: string }[]>,\n runTool: resolve(runnerMod, 'runTool') as (...args: unknown[]) => Promise<void>,\n }\n}\n\nasync function closeClient(client: unknown): Promise<void> {\n if (typeof (client as { close?: unknown }).close === 'function') {\n await (client as { close: () => Promise<void> }).close()\n }\n}\n\nfunction buildMcpConfig(entry: McpEntryPublic): Record<string, unknown> {\n const base: Record<string, unknown> = { type: entry.transport }\n if (entry.transport === 'http') {\n base.url = entry.serverUrl\n } else {\n base.command = entry.command\n }\n const auth = entry.authConfig\n if (auth.type === 'http_headers') {\n base.headers = auth.headers\n } else if (auth.type === 'env') {\n base.env = auth.env\n }\n return base\n}\n\nexport async function listMcpTools(entry: McpEntryPublic): Promise<{ name: string; description?: string }[]> {\n const { createMcpClient, getTools } = await getMcp2cli()\n const config = buildMcpConfig(entry)\n const client = await createMcpClient(config)\n try {\n const tools = await getTools(client, config, { noCache: true })\n return tools\n } finally {\n await closeClient(client)\n }\n}\n\nexport async function runMcpTool(entry: McpEntryPublic, toolName: string, rawArgs: string[]): Promise<void> {\n const { createMcpClient, getTools, runTool } = await getMcp2cli()\n const config = buildMcpConfig(entry)\n const client = await createMcpClient(config)\n try {\n const tools = await getTools(client, config, { noCache: false, cacheTtl: 3600 })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tool = tools.find((t: any) => t.name === toolName)\n if (!tool) throw new Error(`Tool \"${toolName}\" not found on MCP server \"${entry.name}\"`)\n const normalizedArgs: string[] = []\n for (const arg of rawArgs) {\n if (arg.includes('=') && !arg.startsWith('--')) {\n const idx = arg.indexOf('=')\n const key = arg.slice(0, idx)\n const value = arg.slice(idx + 1)\n normalizedArgs.push(`--${key}`, value)\n } else {\n normalizedArgs.push(arg)\n }\n }\n await runTool(client, tool, normalizedArgs, {})\n } finally {\n await closeClient(client)\n }\n}\n","import type { Command } from 'commander'\nimport { getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { listMcpTools, runMcpTool } from '../lib/mcp-runner.js'\nimport { toYaml } from '../lib/yaml.js'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerMcp(program: Command): void {\n const mcp = program\n .command('mcp')\n .description('Interact with MCP servers registered in your group')\n\n // mcp list\n mcp\n .command('list')\n .description('List all MCP servers available in the current group')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .action(async (opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n const entries = await client.listMCP()\n\n if (entries.length === 0) {\n console.log('No MCP servers registered in this group.')\n return\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n // Strip authConfig secrets from JSON output — only expose { type }\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: authConfig.type },\n }))\n console.log(JSON.stringify(safe, null, 2))\n return\n }\n\n if (format === 'yaml') {\n const safe = entries.map(({ authConfig, ...rest }) => ({\n ...rest,\n authConfig: { type: authConfig.type },\n }))\n console.log(toYaml(safe))\n return\n }\n\n const nameWidth = Math.max(10, ...entries.map(e => e.name.length))\n console.log(`\\n${'SERVER'.padEnd(nameWidth)} TRANSPORT DESCRIPTION`)\n console.log(`${'-'.repeat(nameWidth)} --------- ${'-'.repeat(40)}`)\n for (const e of entries) {\n const desc = e.description.length > 60 ? e.description.slice(0, 57) + '...' : e.description\n console.log(`${e.name.padEnd(nameWidth)} ${e.transport.padEnd(9)} ${desc}`)\n }\n console.log()\n })\n\n // mcp tools <server>\n mcp\n .command('tools <server>')\n .description('List tools available on a MCP server')\n .option('--format <fmt>', 'Output format: table | json | yaml', 'table')\n .action(async (serverName: string, opts: { format?: string }) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getMCP(serverName)\n } catch {\n console.error(`Unknown MCP server: ${serverName}`)\n console.error('Run `ucli mcp list` to see available servers.')\n process.exit(ExitCode.NOT_FOUND)\n }\n\n let tools\n try {\n tools = await listMcpTools(entry)\n } catch (err) {\n console.error('Failed to fetch tools:', (err as Error).message)\n process.exit(ExitCode.GENERAL_ERROR)\n }\n\n if (tools.length === 0) {\n console.log(`No tools found on MCP server \"${serverName}\".`)\n return\n }\n\n const format = (opts.format ?? 'table').toLowerCase()\n if (format === 'json') {\n console.log(JSON.stringify(tools, null, 2))\n return\n }\n\n if (format === 'yaml') {\n console.log(toYaml(tools))\n return\n }\n\n console.log(`\\nTools on \"${serverName}\":`)\n console.log('─'.repeat(60))\n for (const t of tools) {\n console.log(` ${t.name}`)\n if (t.description) console.log(` ${t.description}`)\n }\n console.log()\n })\n\n // mcp run <server> <tool> [args...]\n mcp\n .command('run <server> <tool> [args...]')\n .description('Call a tool on a MCP server')\n .action(async (serverName: string, toolName: string, args: string[]) => {\n const cfg = getConfig()\n const client = new ServerClient(cfg)\n\n let entry\n try {\n entry = await client.getMCP(serverName)\n } catch {\n console.error(`Unknown MCP server: ${serverName}`)\n console.error('Run `ucli mcp list` to see available servers.')\n process.exit(ExitCode.NOT_FOUND)\n }\n\n try {\n await runMcpTool(entry, toolName, args)\n } catch (err) {\n console.error('Tool execution failed:', (err as Error).message)\n process.exit(ExitCode.GENERAL_ERROR)\n }\n })\n}\n","/**\n * Consistent error formatting utility.\n *\n * Provides a unified error output with actionable hints so that both\n * humans and AI agents can quickly understand what went wrong and how\n * to fix it.\n */\nimport { ExitCode, type ExitCodeValue } from './exit-codes.js'\n\nlet debugEnabled = false\n\nexport function setDebugMode(enabled: boolean): void {\n debugEnabled = enabled\n}\n\nexport function isDebugMode(): boolean {\n return debugEnabled\n}\n\n/** Log a debug message (only when --debug is active). */\nexport function debug(message: string): void {\n if (debugEnabled) {\n console.error(`[DEBUG] ${message}`)\n }\n}\n\nexport interface FormattedError {\n code: ExitCodeValue\n message: string\n hint?: string\n}\n\nconst HINT_MAP: Record<number, string> = {\n [ExitCode.CONFIG_ERROR]:\n 'Run: ucli configure --server <url> --token <jwt>',\n [ExitCode.AUTH_ERROR]:\n 'Your token may be expired or revoked. Run: ucli configure --server <url> --token <jwt>',\n [ExitCode.CONNECTIVITY_ERROR]:\n 'Check that the server URL is correct and the server is running. Run: ucli doctor',\n [ExitCode.NOT_FOUND]:\n 'Check the resource name. Run: ucli services list or ucli mcp list',\n [ExitCode.SERVER_ERROR]:\n 'The server returned an unexpected error. Try again or run: ucli doctor',\n}\n\n/**\n * Print a formatted error to stderr and exit with the given code.\n * When --debug is active, the full stack trace is also printed.\n */\nexport function formatError(err: unknown, code?: ExitCodeValue): never {\n const exitCode = code ?? classifyError(err)\n const message = err instanceof Error ? err.message : String(err)\n const hint = HINT_MAP[exitCode]\n\n console.error(`\\n✖ Error: ${message}`)\n if (hint) {\n console.error(` Hint: ${hint}`)\n }\n\n if (debugEnabled && err instanceof Error && err.stack) {\n console.error(`\\n${err.stack}`)\n }\n\n process.exit(exitCode)\n}\n\n/** Classify an error into an exit code based on common patterns. */\nfunction classifyError(err: unknown): ExitCodeValue {\n if (!(err instanceof Error)) return ExitCode.GENERAL_ERROR\n\n const msg = err.message.toLowerCase()\n\n if (msg.includes('not configured') || msg.includes('missing')) {\n return ExitCode.CONFIG_ERROR\n }\n if (msg.includes('401') || msg.includes('unauthorized') || msg.includes('authentication')) {\n return ExitCode.AUTH_ERROR\n }\n if (msg.includes('econnrefused') || msg.includes('enotfound') || msg.includes('timeout') || msg.includes('network')) {\n return ExitCode.CONNECTIVITY_ERROR\n }\n if (msg.includes('404') || msg.includes('not found')) {\n return ExitCode.NOT_FOUND\n }\n if (msg.includes('5') && msg.includes('server error')) {\n return ExitCode.SERVER_ERROR\n }\n\n return ExitCode.GENERAL_ERROR\n}\n","/**\n * `ucli doctor` — diagnostic tool for configuration, connectivity, and token validation.\n *\n * Checks:\n * 1. Configuration file exists and is readable\n * 2. Server URL is reachable (GET /api/v1/health)\n * 3. JWT token is accepted (GET /api/v1/oas — expects 200 or empty list)\n */\nimport type { Command } from 'commander'\nimport { isConfigured, getConfig } from '../config.js'\nimport { ServerClient } from '../lib/server-client.js'\nimport { ExitCode } from '../lib/exit-codes.js'\nimport { debug } from '../lib/errors.js'\nimport axios from 'axios'\n\ninterface CheckResult {\n name: string\n ok: boolean\n detail: string\n}\n\nexport function registerDoctor(program: Command): void {\n program\n .command('doctor')\n .description('Check configuration, server connectivity, and token validity')\n .action(async () => {\n const results: CheckResult[] = []\n\n // ── Check 1: Configuration ──────────────────────────────────────\n debug('Checking configuration...')\n if (!isConfigured()) {\n results.push({\n name: 'Configuration',\n ok: false,\n detail: 'Not configured. Run: ucli configure --server <url> --token <jwt>',\n })\n printResults(results)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n let cfg: { serverUrl: string; token: string }\n try {\n cfg = getConfig()\n results.push({\n name: 'Configuration',\n ok: true,\n detail: `Server: ${cfg.serverUrl}`,\n })\n } catch (err) {\n results.push({\n name: 'Configuration',\n ok: false,\n detail: `Failed to read config: ${(err as Error).message}`,\n })\n printResults(results)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // ── Check 2: Connectivity (health endpoint, no auth required) ──\n debug(`Checking connectivity to ${cfg.serverUrl}...`)\n try {\n const healthUrl = `${cfg.serverUrl}/api/v1/health`\n const resp = await axios.get(healthUrl, { timeout: 10_000 })\n results.push({\n name: 'Server connectivity',\n ok: resp.status === 200,\n detail: resp.status === 200\n ? `Health endpoint OK (${cfg.serverUrl})`\n : `Unexpected status: ${resp.status}`,\n })\n } catch (err) {\n const msg = axios.isAxiosError(err)\n ? err.code ?? err.message\n : (err as Error).message\n results.push({\n name: 'Server connectivity',\n ok: false,\n detail: `Cannot reach server: ${msg}`,\n })\n }\n\n // ── Check 3: Token validity (authenticated request) ────────────\n debug('Validating JWT token...')\n try {\n const client = new ServerClient(cfg)\n await client.listOAS()\n results.push({\n name: 'Authentication',\n ok: true,\n detail: 'Token accepted by server',\n })\n } catch (err) {\n const msg = (err as Error).message\n results.push({\n name: 'Authentication',\n ok: false,\n detail: `Token rejected: ${msg}`,\n })\n }\n\n printResults(results)\n\n const allOk = results.every((r) => r.ok)\n process.exit(allOk ? ExitCode.SUCCESS : ExitCode.GENERAL_ERROR)\n })\n}\n\nfunction printResults(results: CheckResult[]): void {\n console.log('\\nucli doctor\\n' + '═'.repeat(40))\n for (const r of results) {\n const icon = r.ok ? '✓' : '✖'\n console.log(` ${icon} ${r.name}: ${r.detail}`)\n }\n console.log()\n}\n","/**\n * `ucli completions` — generate shell completion scripts for bash/zsh/fish.\n *\n * Usage:\n * eval \"$(ucli completions bash)\"\n * eval \"$(ucli completions zsh)\"\n * ucli completions fish | source\n */\nimport type { Command } from 'commander'\nimport { ExitCode } from '../lib/exit-codes.js'\n\nexport function registerCompletions(program: Command): void {\n program\n .command('completions <shell>')\n .description('Generate shell completion script (bash | zsh | fish)')\n .action((shell: string) => {\n const normalized = shell.toLowerCase().trim()\n\n switch (normalized) {\n case 'bash':\n console.log(bashCompletions())\n break\n case 'zsh':\n console.log(zshCompletions())\n break\n case 'fish':\n console.log(fishCompletions())\n break\n default:\n console.error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`)\n process.exit(ExitCode.USAGE_ERROR)\n }\n })\n}\n\nfunction bashCompletions(): string {\n return `# ucli bash completions — eval \"$(ucli completions bash)\"\n_ucli_completions() {\n local cur prev commands\n COMPREPLY=()\n cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n prev=\"\\${COMP_WORDS[COMP_CWORD-1]}\"\n commands=\"configure services run refresh help mcp doctor completions\"\n\n case \"\\${COMP_WORDS[1]}\" in\n services)\n COMPREPLY=( $(compgen -W \"list info\" -- \"$cur\") )\n return 0\n ;;\n mcp)\n COMPREPLY=( $(compgen -W \"list tools run\" -- \"$cur\") )\n return 0\n ;;\n completions)\n COMPREPLY=( $(compgen -W \"bash zsh fish\" -- \"$cur\") )\n return 0\n ;;\n run|help)\n # dynamic completions would require server calls; skip for now\n return 0\n ;;\n esac\n\n if [ \"$COMP_CWORD\" -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"$commands\" -- \"$cur\") )\n fi\n\n return 0\n}\ncomplete -F _ucli_completions ucli`\n}\n\nfunction zshCompletions(): string {\n return `# ucli zsh completions — eval \"$(ucli completions zsh)\"\n#compdef ucli\n\n_ucli() {\n local -a commands\n commands=(\n 'configure:Configure server URL and authentication token'\n 'services:Manage and inspect available OAS services'\n 'run:Execute an operation on a service'\n 'refresh:Force-refresh the local OAS cache'\n 'help:Show usage guide'\n 'mcp:Interact with MCP servers'\n 'doctor:Check configuration and connectivity'\n 'completions:Generate shell completion script'\n )\n\n _arguments -C \\\\\n '1: :->command' \\\\\n '*::arg:->args'\n\n case $state in\n command)\n _describe -t commands 'ucli commands' commands\n ;;\n args)\n case $words[1] in\n services)\n _values 'subcommand' 'list[List all OAS services]' 'info[Show service details]'\n ;;\n mcp)\n _values 'subcommand' 'list[List MCP servers]' 'tools[List tools]' 'run[Call a tool]'\n ;;\n completions)\n _values 'shell' bash zsh fish\n ;;\n esac\n ;;\n esac\n}\n\n_ucli \"$@\"`\n}\n\nfunction fishCompletions(): string {\n return `# ucli fish completions — ucli completions fish | source\ncomplete -c ucli -e\n\n# Top-level commands\ncomplete -c ucli -n __fish_use_subcommand -a configure -d 'Configure server URL and token'\ncomplete -c ucli -n __fish_use_subcommand -a services -d 'Manage OAS services'\ncomplete -c ucli -n __fish_use_subcommand -a run -d 'Execute a service operation'\ncomplete -c ucli -n __fish_use_subcommand -a refresh -d 'Refresh local cache'\ncomplete -c ucli -n __fish_use_subcommand -a help -d 'Show usage guide'\ncomplete -c ucli -n __fish_use_subcommand -a mcp -d 'Interact with MCP servers'\ncomplete -c ucli -n __fish_use_subcommand -a doctor -d 'Check config and connectivity'\ncomplete -c ucli -n __fish_use_subcommand -a completions -d 'Generate shell completions'\n\n# services subcommands\ncomplete -c ucli -n '__fish_seen_subcommand_from services' -a list -d 'List services'\ncomplete -c ucli -n '__fish_seen_subcommand_from services' -a info -d 'Show service details'\n\n# mcp subcommands\ncomplete -c ucli -n '__fish_seen_subcommand_from mcp' -a list -d 'List MCP servers'\ncomplete -c ucli -n '__fish_seen_subcommand_from mcp' -a tools -d 'List tools'\ncomplete -c ucli -n '__fish_seen_subcommand_from mcp' -a run -d 'Call a tool'\n\n# completions subcommands\ncomplete -c ucli -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish' -d 'Shell type'`\n}\n"],"mappings":"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","names":["createRequire","program","join","join","join","dirname","require","pkg","resolve","program","program","program","program","cfg","client","program","axios","program","program","require","createRequire"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tronsfey/ucli",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "ucli — proxy OpenAPI and MCP services for AI agents",
5
5
  "keywords": [
6
6
  "openapi",