@robinmordasiewicz/f5xc-xcsh 2.0.21-2601142039 → 2.0.21-2601142307

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +519 -50
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -41228,8 +41228,8 @@ var init_logo_renderer = __esm({
41228
41228
 
41229
41229
  // src/branding/index.ts
41230
41230
  function getVersion() {
41231
- if ("v2.0.21-2601142039") {
41232
- return "v2.0.21-2601142039";
41231
+ if ("v2.0.21-2601142307") {
41232
+ return "v2.0.21-2601142307";
41233
41233
  }
41234
41234
  if (process.env.XCSH_VERSION) {
41235
41235
  return process.env.XCSH_VERSION;
@@ -77869,6 +77869,132 @@ var init_response_renderer = __esm({
77869
77869
  }
77870
77870
  });
77871
77871
 
77872
+ // src/utils/usage-parser.ts
77873
+ function parseUsage(usageString) {
77874
+ if (!usageString) {
77875
+ return { positional: [], flags: [], raw: "" };
77876
+ }
77877
+ const positional = [];
77878
+ const flags = [];
77879
+ const tokens = tokenizeUsage(usageString);
77880
+ for (let i = 0; i < tokens.length; i++) {
77881
+ const token = tokens[i];
77882
+ if (!token) continue;
77883
+ if (token.startsWith("--")) {
77884
+ const flagName = token;
77885
+ const nextToken = tokens[i + 1];
77886
+ let valueType;
77887
+ let valueName;
77888
+ let required = true;
77889
+ if (nextToken && isValuePlaceholder(nextToken)) {
77890
+ valueName = stripBrackets(nextToken);
77891
+ valueType = "string";
77892
+ i++;
77893
+ required = !token.match(/^\[--/) && !nextToken.match(/^\[/);
77894
+ } else {
77895
+ required = !token.match(/^\[--/);
77896
+ }
77897
+ const cleanName = flagName.replace(/[[\]]/g, "");
77898
+ if (cleanName) {
77899
+ const flag = {
77900
+ name: cleanName,
77901
+ required,
77902
+ ...valueType && { valueType },
77903
+ ...valueName && { valueName }
77904
+ };
77905
+ flags.push(flag);
77906
+ }
77907
+ } else if (isValuePlaceholder(token)) {
77908
+ const name = stripBrackets(token);
77909
+ const required = isRequired(token);
77910
+ if (name) {
77911
+ positional.push({
77912
+ name,
77913
+ required
77914
+ });
77915
+ }
77916
+ }
77917
+ }
77918
+ return {
77919
+ positional,
77920
+ flags,
77921
+ raw: usageString
77922
+ };
77923
+ }
77924
+ function tokenizeUsage(usageString) {
77925
+ const tokens = [];
77926
+ let current = "";
77927
+ let bracketDepth = 0;
77928
+ for (let i = 0; i < usageString.length; i++) {
77929
+ const char = usageString[i];
77930
+ if (char === "[") {
77931
+ bracketDepth++;
77932
+ current += char;
77933
+ } else if (char === "]") {
77934
+ bracketDepth--;
77935
+ current += char;
77936
+ if (bracketDepth === 0 && current.trim()) {
77937
+ tokens.push(current.trim());
77938
+ current = "";
77939
+ }
77940
+ } else if (char === " " && bracketDepth === 0) {
77941
+ if (current.trim()) {
77942
+ tokens.push(current.trim());
77943
+ current = "";
77944
+ }
77945
+ } else if (char === "<") {
77946
+ if (current.trim() && !current.includes("<")) {
77947
+ tokens.push(current.trim());
77948
+ current = "";
77949
+ }
77950
+ current += char;
77951
+ } else if (char === ">") {
77952
+ current += char;
77953
+ if (bracketDepth === 0) {
77954
+ tokens.push(current.trim());
77955
+ current = "";
77956
+ }
77957
+ } else {
77958
+ current += char;
77959
+ }
77960
+ }
77961
+ if (current.trim()) {
77962
+ tokens.push(current.trim());
77963
+ }
77964
+ return tokens;
77965
+ }
77966
+ function isValuePlaceholder(token) {
77967
+ return /^[<[][\w-]+[\]>]$/.test(token) || /^<[\w-]+>$/.test(token);
77968
+ }
77969
+ function isRequired(token) {
77970
+ return token.startsWith("<") && token.endsWith(">");
77971
+ }
77972
+ function stripBrackets(token) {
77973
+ return token.replace(/^[<[]/, "").replace(/[>\]]$/, "");
77974
+ }
77975
+ function generateSmartCompletions(usage, args, flags) {
77976
+ if (!usage) {
77977
+ return flags;
77978
+ }
77979
+ const requirements = parseUsage(usage);
77980
+ const positionalArgsProvided = args.filter(
77981
+ (arg) => !arg.startsWith("--")
77982
+ ).length;
77983
+ const requiredPositional = requirements.positional.filter(
77984
+ (p) => p.required
77985
+ );
77986
+ if (positionalArgsProvided < requiredPositional.length) {
77987
+ const placeholders = requiredPositional.slice(positionalArgsProvided).map((p) => `<${p.name}>`);
77988
+ return [...placeholders, ...flags];
77989
+ }
77990
+ return flags;
77991
+ }
77992
+ var init_usage_parser = __esm({
77993
+ "src/utils/usage-parser.ts"() {
77994
+ "use strict";
77995
+ }
77996
+ });
77997
+
77872
77998
  // src/domains/ai_services/query.ts
77873
77999
  function getLastQueryState() {
77874
78000
  return lastQueryState;
@@ -77925,6 +78051,7 @@ var init_query = __esm({
77925
78051
  init_domain_formatter();
77926
78052
  init_client();
77927
78053
  init_response_renderer();
78054
+ init_usage_parser();
77928
78055
  lastQueryState = {
77929
78056
  namespace: "",
77930
78057
  lastQueryId: null,
@@ -77937,8 +78064,26 @@ var init_query = __esm({
77937
78064
  description: "Send a natural language query to the F5 Distributed Cloud AI assistant. Ask about load balancers, WAF configurations, site status, security events, or any platform topic. Returns AI-generated responses with optional follow-up suggestions. Use --namespace to specify the context for namespace-scoped resources.",
77938
78065
  descriptionShort: "Query the AI assistant",
77939
78066
  descriptionMedium: "Send natural language queries to the AI assistant for help with F5 XC platform operations, configurations, and troubleshooting.",
77940
- usage: "<question> [--namespace <ns>]",
78067
+ usage: "<question> [--namespace <ns>] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
77941
78068
  aliases: ["ask", "q"],
78069
+ async completion(_partial, args, session) {
78070
+ const flags = [
78071
+ "--namespace",
78072
+ "-ns",
78073
+ "--format",
78074
+ "--spec",
78075
+ "--no-color",
78076
+ "json",
78077
+ "table",
78078
+ "yaml",
78079
+ "tsv"
78080
+ ];
78081
+ const namespaces = session.getNamespaceCache();
78082
+ return generateSmartCompletions(this.usage, args, [
78083
+ ...flags,
78084
+ ...namespaces
78085
+ ]);
78086
+ },
77942
78087
  async execute(args, session) {
77943
78088
  const { format, noColor, spec, namespace, question } = parseQueryArgs(
77944
78089
  args,
@@ -78161,6 +78306,7 @@ var init_list = __esm({
78161
78306
  description: "Display all saved connection profiles with their tenant URLs and authentication types. Highlights the currently active profile for easy identification when managing multiple tenants.",
78162
78307
  descriptionShort: "List all saved profiles",
78163
78308
  descriptionMedium: "Show all profiles with tenant URLs, auth types, and active status indicator.",
78309
+ usage: "[--format <json|table|yaml>]",
78164
78310
  async execute(args, session) {
78165
78311
  const { options } = parseDomainOutputFlags(
78166
78312
  args,
@@ -78237,7 +78383,7 @@ var init_show = __esm({
78237
78383
  const manager = getProfileManager();
78238
78384
  const name = remainingArgs[0];
78239
78385
  if (!name) {
78240
- return errorResult("Usage: login profile show <name>");
78386
+ return errorResult("Usage: login show profile <name>");
78241
78387
  }
78242
78388
  try {
78243
78389
  const profile = await manager.get(name);
@@ -78725,6 +78871,33 @@ var init_validation = __esm({
78725
78871
  }
78726
78872
  });
78727
78873
 
78874
+ // src/domains/error-messages.ts
78875
+ function generateUsageError(commandPath, usageField, additionalHelp) {
78876
+ const lines = [];
78877
+ lines.push(`Usage: ${commandPath} ${usageField}`);
78878
+ lines.push("");
78879
+ if (additionalHelp?.options && additionalHelp.options.length > 0) {
78880
+ lines.push("Options:");
78881
+ for (const opt of additionalHelp.options) {
78882
+ lines.push(` ${opt.flag.padEnd(12)} ${opt.description}`);
78883
+ }
78884
+ lines.push("");
78885
+ }
78886
+ if (additionalHelp?.examples && additionalHelp.examples.length > 0) {
78887
+ lines.push("Example:");
78888
+ for (const example of additionalHelp.examples) {
78889
+ lines.push(` ${example}`);
78890
+ }
78891
+ }
78892
+ return lines.join("\n");
78893
+ }
78894
+ var init_error_messages = __esm({
78895
+ "src/domains/error-messages.ts"() {
78896
+ "use strict";
78897
+ init_usage_parser();
78898
+ }
78899
+ });
78900
+
78728
78901
  // src/domains/login/profile/create.ts
78729
78902
  var createCommand2;
78730
78903
  var init_create = __esm({
@@ -78734,6 +78907,8 @@ var init_create = __esm({
78734
78907
  init_profile();
78735
78908
  init_connection_table();
78736
78909
  init_validation();
78910
+ init_error_messages();
78911
+ init_usage_parser();
78737
78912
  createCommand2 = {
78738
78913
  name: "create",
78739
78914
  description: "Create a new connection profile with tenant URL and authentication credentials. Profiles store all settings needed to connect to a tenant, including optional default namespace for scoped operations.",
@@ -78741,25 +78916,44 @@ var init_create = __esm({
78741
78916
  descriptionMedium: "Create a profile with tenant URL, authentication token, and optional default namespace.",
78742
78917
  usage: "<name> --url <api-url> --token <api-token> [--namespace <ns>]",
78743
78918
  aliases: ["add", "new"],
78744
- completion: async (_currentWord, _args) => {
78745
- return ["--url", "--token", "--namespace"];
78919
+ completion: async (_currentWord, args) => {
78920
+ return generateSmartCompletions(createCommand2.usage, args, [
78921
+ "--url",
78922
+ "--token",
78923
+ "--namespace"
78924
+ ]);
78746
78925
  },
78747
78926
  async execute(args, session) {
78748
78927
  const manager = getProfileManager();
78749
78928
  const name = args[0];
78750
78929
  if (!name || name.startsWith("-")) {
78751
78930
  return errorResult(
78752
- [
78753
- "Usage: login profile create <name> --url <api-url> --token <api-token>",
78754
- "",
78755
- "Options:",
78756
- " --url F5 XC API URL (e.g., https://tenant.console.ves.volterra.io)",
78757
- " --token API token for authentication",
78758
- " --namespace Default namespace (optional)",
78759
- "",
78760
- "Example:",
78761
- " login profile create myprofile --url https://tenant.console.ves.volterra.io --token abc123"
78762
- ].join("\n")
78931
+ generateUsageError(
78932
+ "login create profile",
78933
+ // FIXED: Correct registry path (verb-first)
78934
+ createCommand2.usage,
78935
+ // Single source of truth
78936
+ {
78937
+ options: [
78938
+ {
78939
+ flag: "--url",
78940
+ description: "F5 XC API URL (e.g., https://tenant.console.ves.volterra.io)"
78941
+ },
78942
+ {
78943
+ flag: "--token",
78944
+ description: "API token for authentication"
78945
+ },
78946
+ {
78947
+ flag: "--namespace",
78948
+ description: "Default namespace (optional)"
78949
+ }
78950
+ ],
78951
+ examples: [
78952
+ "login create profile myprofile --url https://tenant.console.ves.volterra.io --token abc123",
78953
+ "login create profile prod --url https://prod.console.ves.volterra.io --token xyz789 --namespace production"
78954
+ ]
78955
+ }
78956
+ )
78763
78957
  );
78764
78958
  }
78765
78959
  const nameValidation = validateResourceName(name, {
@@ -78858,7 +79052,7 @@ var init_use = __esm({
78858
79052
  async execute(args, session) {
78859
79053
  const name = args[0];
78860
79054
  if (!name) {
78861
- return errorResult("Usage: login profile use <name>");
79055
+ return errorResult("Usage: login use profile <name>");
78862
79056
  }
78863
79057
  try {
78864
79058
  const success = await session.switchProfile(name);
@@ -78918,7 +79112,7 @@ var init_delete = __esm({
78918
79112
  const manager = getProfileManager();
78919
79113
  const name = args.find((arg) => !arg.startsWith("-"));
78920
79114
  if (!name) {
78921
- return errorResult("Usage: login profile delete <name>");
79115
+ return errorResult("Usage: login delete profile <name>");
78922
79116
  }
78923
79117
  try {
78924
79118
  const profile = await manager.get(name);
@@ -79074,7 +79268,8 @@ var init_edit = __esm({
79074
79268
  const active = await manager.getActive();
79075
79269
  if (!active) {
79076
79270
  return errorResult(
79077
- "No profile specified and no active profile set.\nUsage: login profile edit <name>"
79271
+ "No profile specified and no active profile set.\nUsage: login edit profile <name>"
79272
+ // FIXED: Correct registry path
79078
79273
  );
79079
79274
  }
79080
79275
  profileName = active;
@@ -79186,7 +79381,7 @@ var init_context = __esm({
79186
79381
  description: "Display the currently active namespace context used for scoping operations. Shows both the namespace value and its source (environment variable, profile default, or session configuration).",
79187
79382
  descriptionShort: "Show current default namespace",
79188
79383
  descriptionMedium: "Display active namespace context and its configuration source.",
79189
- usage: "",
79384
+ usage: "[--format <json|table|yaml|tsv>]",
79190
79385
  aliases: ["current", "get"],
79191
79386
  async execute(args, session) {
79192
79387
  const { options } = parseDomainOutputFlags(
@@ -79275,7 +79470,7 @@ var init_context = __esm({
79275
79470
  description: "Fetch and display all available namespaces from the tenant. Requires authenticated connection. Shows current namespace indicator and provides switch command guidance.",
79276
79471
  descriptionShort: "List available namespaces",
79277
79472
  descriptionMedium: "Query tenant for available namespaces with current context indicator.",
79278
- usage: "",
79473
+ usage: "[--format <json|table|yaml|tsv>]",
79279
79474
  aliases: ["ls"],
79280
79475
  async execute(args, session) {
79281
79476
  const { options } = parseDomainOutputFlags(
@@ -80417,13 +80612,28 @@ var init_cloudstatus2 = __esm({
80417
80612
  init_cloudstatus();
80418
80613
  init_output();
80419
80614
  init_domain_formatter();
80615
+ init_usage_parser();
80420
80616
  cloudstatusClient = null;
80421
80617
  statusCommand = {
80422
80618
  name: "status",
80423
80619
  description: "Retrieve the current overall health indicator for F5 Distributed Cloud services. Returns status level (operational, degraded, major outage) with description. Use --quiet for script-friendly exit code output.",
80424
80620
  descriptionShort: "Get overall cloud status indicator",
80425
80621
  descriptionMedium: "Check overall service health status. Use --quiet for exit code suitable for scripts.",
80426
- usage: "[--quiet]",
80622
+ usage: "[--quiet] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
80623
+ async completion(_partial, args) {
80624
+ const flags = [
80625
+ "--quiet",
80626
+ "-q",
80627
+ "--format",
80628
+ "--spec",
80629
+ "--no-color",
80630
+ "json",
80631
+ "table",
80632
+ "yaml",
80633
+ "tsv"
80634
+ ];
80635
+ return generateSmartCompletions(this.usage, args, flags);
80636
+ },
80427
80637
  async execute(args, session) {
80428
80638
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
80429
80639
  args,
@@ -80474,7 +80684,21 @@ var init_cloudstatus2 = __esm({
80474
80684
  description: "Display comprehensive status overview combining overall health, component statuses, active incidents, and scheduled maintenance in a single report. Use --brief for condensed statistics output.",
80475
80685
  descriptionShort: "Get complete status summary",
80476
80686
  descriptionMedium: "Show combined overview of health, components, incidents, and maintenance windows.",
80477
- usage: "[--brief]",
80687
+ usage: "[--brief] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
80688
+ async completion(_partial, args) {
80689
+ const flags = [
80690
+ "--brief",
80691
+ "-b",
80692
+ "--format",
80693
+ "--spec",
80694
+ "--no-color",
80695
+ "json",
80696
+ "table",
80697
+ "yaml",
80698
+ "tsv"
80699
+ ];
80700
+ return generateSmartCompletions(this.usage, args, flags);
80701
+ },
80478
80702
  async execute(args, session) {
80479
80703
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
80480
80704
  args,
@@ -80513,7 +80737,21 @@ var init_cloudstatus2 = __esm({
80513
80737
  description: "List all service components with their current operational status. Shows each component's health level. Use --degraded-only to filter for components experiencing issues.",
80514
80738
  descriptionShort: "List all components and status",
80515
80739
  descriptionMedium: "Display service component health. Use --degraded-only to show only affected components.",
80516
- usage: "[--degraded-only]",
80740
+ usage: "[--degraded-only] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
80741
+ async completion(_partial, args) {
80742
+ const flags = [
80743
+ "--degraded-only",
80744
+ "-d",
80745
+ "--format",
80746
+ "--spec",
80747
+ "--no-color",
80748
+ "json",
80749
+ "table",
80750
+ "yaml",
80751
+ "tsv"
80752
+ ];
80753
+ return generateSmartCompletions(this.usage, args, flags);
80754
+ },
80517
80755
  async execute(args, session) {
80518
80756
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
80519
80757
  args,
@@ -80569,7 +80807,21 @@ var init_cloudstatus2 = __esm({
80569
80807
  description: "Track service incidents with their impact levels, status, and latest updates. Shows both active and recently resolved incidents. Use --active-only to filter for ongoing issues requiring attention.",
80570
80808
  descriptionShort: "List active and recent incidents",
80571
80809
  descriptionMedium: "Display incidents with impact levels and updates. Use --active-only for ongoing issues.",
80572
- usage: "[--active-only]",
80810
+ usage: "[--active-only] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
80811
+ async completion(_partial, args) {
80812
+ const flags = [
80813
+ "--active-only",
80814
+ "-a",
80815
+ "--format",
80816
+ "--spec",
80817
+ "--no-color",
80818
+ "json",
80819
+ "table",
80820
+ "yaml",
80821
+ "tsv"
80822
+ ];
80823
+ return generateSmartCompletions(this.usage, args, flags);
80824
+ },
80573
80825
  async execute(args, session) {
80574
80826
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
80575
80827
  args,
@@ -80621,7 +80873,21 @@ var init_cloudstatus2 = __esm({
80621
80873
  description: "View scheduled and in-progress maintenance windows with their timing and affected services. Plan around downtime windows. Use --upcoming to filter for future maintenance only.",
80622
80874
  descriptionShort: "List scheduled maintenance windows",
80623
80875
  descriptionMedium: "Show maintenance schedules and timing. Use --upcoming for future windows only.",
80624
- usage: "[--upcoming]",
80876
+ usage: "[--upcoming] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
80877
+ async completion(_partial, args) {
80878
+ const flags = [
80879
+ "--upcoming",
80880
+ "-u",
80881
+ "--format",
80882
+ "--spec",
80883
+ "--no-color",
80884
+ "json",
80885
+ "table",
80886
+ "yaml",
80887
+ "tsv"
80888
+ ];
80889
+ return generateSmartCompletions(this.usage, args, flags);
80890
+ },
80625
80891
  async execute(args, session) {
80626
80892
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
80627
80893
  args,
@@ -81323,6 +81589,7 @@ var init_completion2 = __esm({
81323
81589
  description: "Generate a bash shell completion script for xcsh. Output the script to stdout for manual installation or pipe to a file. Enables tab-completion for commands, domains, actions, and option flags.",
81324
81590
  descriptionShort: "Generate bash completion script",
81325
81591
  descriptionMedium: "Output bash completion script for tab-completion of commands, domains, and flags.",
81592
+ usage: "(no arguments)",
81326
81593
  async execute() {
81327
81594
  try {
81328
81595
  const script = generateBashCompletion();
@@ -81339,6 +81606,7 @@ var init_completion2 = __esm({
81339
81606
  description: "Generate a zsh shell completion script for xcsh. Output the script to stdout for manual installation or add to your fpath. Provides rich tab-completion with descriptions for commands, domains, and options.",
81340
81607
  descriptionShort: "Generate zsh completion script",
81341
81608
  descriptionMedium: "Output zsh completion script with rich descriptions for commands and options.",
81609
+ usage: "(no arguments)",
81342
81610
  async execute() {
81343
81611
  try {
81344
81612
  const script = generateZshCompletion();
@@ -81355,6 +81623,7 @@ var init_completion2 = __esm({
81355
81623
  description: "Generate a fish shell completion script for xcsh. Output the script to stdout for manual installation or save to your fish completions directory. Enables intelligent tab-completion with inline descriptions.",
81356
81624
  descriptionShort: "Generate fish completion script",
81357
81625
  descriptionMedium: "Output fish completion script with inline descriptions for commands and options.",
81626
+ usage: "(no arguments)",
81358
81627
  async execute() {
81359
81628
  try {
81360
81629
  const script = generateFishCompletion();
@@ -81536,13 +81805,36 @@ var init_feedback = __esm({
81536
81805
  init_client();
81537
81806
  init_query();
81538
81807
  init_types3();
81808
+ init_usage_parser();
81539
81809
  feedbackCommand = {
81540
81810
  name: "feedback",
81541
81811
  description: "Submit feedback on AI assistant responses to help improve future answers. Provide positive feedback when responses are helpful, or negative feedback with a reason type when improvements are needed. Feedback is associated with the most recent query unless a specific query ID is provided. Negative feedback types include: inaccurate (wrong information), irrelevant (off-topic), poor_format (hard to read), slow (response time), or other.",
81542
81812
  descriptionShort: "Submit feedback for AI responses",
81543
81813
  descriptionMedium: "Provide positive or negative feedback for AI assistant responses. Use --negative with a type: inaccurate, irrelevant, poor_format, slow, or other.",
81544
- usage: "--positive | --negative <type> [--comment <text>] [--query-id <id>]",
81814
+ usage: "--positive | --negative <type> [--comment <text>] [--query-id <id>] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
81545
81815
  aliases: ["fb", "rate"],
81816
+ async completion(_partial, args) {
81817
+ const feedbackTypes = getValidFeedbackTypes();
81818
+ const flags = [
81819
+ "--positive",
81820
+ "-p",
81821
+ "--negative",
81822
+ "-n",
81823
+ "--comment",
81824
+ "-c",
81825
+ "--query-id",
81826
+ "-q",
81827
+ "--format",
81828
+ "--spec",
81829
+ "--no-color",
81830
+ "json",
81831
+ "table",
81832
+ "yaml",
81833
+ "tsv",
81834
+ ...feedbackTypes
81835
+ ];
81836
+ return generateSmartCompletions(this.usage, args, flags);
81837
+ },
81546
81838
  async execute(args, session) {
81547
81839
  const {
81548
81840
  format,
@@ -81760,13 +82052,32 @@ var init_eval = __esm({
81760
82052
  init_response_renderer();
81761
82053
  init_query();
81762
82054
  init_types3();
82055
+ init_usage_parser();
81763
82056
  evalQueryCommand = {
81764
82057
  name: "query",
81765
82058
  description: "Send a query to the AI assistant using the eval endpoint. This endpoint is used for RBAC testing and validation purposes, allowing administrators to test permission scenarios without affecting production query analytics.",
81766
82059
  descriptionShort: "Eval mode AI query",
81767
82060
  descriptionMedium: "Query the AI assistant in eval mode for RBAC testing and permission validation.",
81768
- usage: "<question> [--namespace <ns>]",
82061
+ usage: "<question> [--namespace <ns>] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
81769
82062
  aliases: ["q"],
82063
+ async completion(_partial, args, session) {
82064
+ const flags = [
82065
+ "--namespace",
82066
+ "-ns",
82067
+ "--format",
82068
+ "--spec",
82069
+ "--no-color",
82070
+ "json",
82071
+ "table",
82072
+ "yaml",
82073
+ "tsv"
82074
+ ];
82075
+ const namespaces = session.getNamespaceCache();
82076
+ return generateSmartCompletions(this.usage, args, [
82077
+ ...flags,
82078
+ ...namespaces
82079
+ ]);
82080
+ },
81770
82081
  async execute(args, session) {
81771
82082
  const { format, noColor, spec, namespace, question } = parseEvalQueryArgs(args, session);
81772
82083
  if (spec) {
@@ -81822,8 +82133,30 @@ var init_eval = __esm({
81822
82133
  description: "Submit feedback for an eval mode query. Use this endpoint when providing feedback for queries made through the eval endpoint, ensuring proper RBAC testing analytics separation.",
81823
82134
  descriptionShort: "Eval mode feedback submission",
81824
82135
  descriptionMedium: "Submit feedback for eval mode AI queries, keeping RBAC testing analytics separate.",
81825
- usage: "--positive | --negative <type> [--comment <text>] [--query-id <id>]",
82136
+ usage: "--positive | --negative <type> [--comment <text>] [--query-id <id>] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
81826
82137
  aliases: ["fb"],
82138
+ async completion(_partial, args) {
82139
+ const feedbackTypes = getValidFeedbackTypes();
82140
+ const flags = [
82141
+ "--positive",
82142
+ "-p",
82143
+ "--negative",
82144
+ "-n",
82145
+ "--comment",
82146
+ "-c",
82147
+ "--query-id",
82148
+ "-q",
82149
+ "--format",
82150
+ "--spec",
82151
+ "--no-color",
82152
+ "json",
82153
+ "table",
82154
+ "yaml",
82155
+ "tsv",
82156
+ ...feedbackTypes
82157
+ ];
82158
+ return generateSmartCompletions(this.usage, args, flags);
82159
+ },
81827
82160
  async execute(args, session) {
81828
82161
  const { spec, namespace, positive, negativeType, comment, queryId } = parseEvalFeedbackArgs(args, session);
81829
82162
  if (spec) {
@@ -82511,12 +82844,25 @@ var init_subscription = __esm({
82511
82844
  init_output();
82512
82845
  init_domain_formatter();
82513
82846
  init_client3();
82847
+ init_usage_parser();
82514
82848
  showCommand3 = {
82515
82849
  name: "show",
82516
82850
  description: "Display comprehensive subscription overview including plan tier, addon summary, quota utilization, and current billing period usage. Provides a quick snapshot of your F5 XC subscription status.",
82517
82851
  descriptionShort: "Display subscription overview",
82518
82852
  descriptionMedium: "Show subscription tier, active addons, quota usage summary, and current billing status.",
82519
- usage: "",
82853
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
82854
+ async completion(_partial, args) {
82855
+ const flags = [
82856
+ "--format",
82857
+ "--spec",
82858
+ "--no-color",
82859
+ "json",
82860
+ "table",
82861
+ "yaml",
82862
+ "tsv"
82863
+ ];
82864
+ return generateSmartCompletions(this.usage, args, flags);
82865
+ },
82520
82866
  async execute(args, session) {
82521
82867
  const { format, noColor, spec } = parseOutputArgs2(args, session);
82522
82868
  if (spec) {
@@ -82616,7 +82962,19 @@ var init_subscription = __esm({
82616
82962
  description: "Display detailed information about your current subscription plan including tier, features, and limits.",
82617
82963
  descriptionShort: "Show current plan details",
82618
82964
  descriptionMedium: "Display detailed subscription plan information including tier level, features, and resource limits.",
82619
- usage: "",
82965
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
82966
+ async completion(_partial, args) {
82967
+ const flags = [
82968
+ "--format",
82969
+ "--spec",
82970
+ "--no-color",
82971
+ "json",
82972
+ "table",
82973
+ "yaml",
82974
+ "tsv"
82975
+ ];
82976
+ return generateSmartCompletions(this.usage, args, flags);
82977
+ },
82620
82978
  async execute(args, session) {
82621
82979
  const { format, noColor, spec } = parseOutputArgs2(args, session);
82622
82980
  if (spec) {
@@ -82672,7 +83030,19 @@ var init_subscription = __esm({
82672
83030
  description: "List all available subscription plans with their features and pricing tiers.",
82673
83031
  descriptionShort: "List available plans",
82674
83032
  descriptionMedium: "Display all subscription plan options with tier information and feature comparisons.",
82675
- usage: "",
83033
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83034
+ async completion(_partial, args) {
83035
+ const flags = [
83036
+ "--format",
83037
+ "--spec",
83038
+ "--no-color",
83039
+ "json",
83040
+ "table",
83041
+ "yaml",
83042
+ "tsv"
83043
+ ];
83044
+ return generateSmartCompletions(this.usage, args, flags);
83045
+ },
82676
83046
  async execute(args, session) {
82677
83047
  const { format, noColor, spec } = parseOutputArgs2(args, session);
82678
83048
  if (spec) {
@@ -82727,7 +83097,20 @@ var init_subscription = __esm({
82727
83097
  description: "List all available addon services with their status, category, and access level. Use --subscribed to filter for active subscriptions only.",
82728
83098
  descriptionShort: "List addon services",
82729
83099
  descriptionMedium: "Display all addon services with status and access information. Use --subscribed for active only.",
82730
- usage: "[--subscribed]",
83100
+ usage: "[--subscribed] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83101
+ async completion(_partial, args) {
83102
+ const flags = [
83103
+ "--subscribed",
83104
+ "--format",
83105
+ "--spec",
83106
+ "--no-color",
83107
+ "json",
83108
+ "table",
83109
+ "yaml",
83110
+ "tsv"
83111
+ ];
83112
+ return generateSmartCompletions(this.usage, args, flags);
83113
+ },
82731
83114
  async execute(args, session) {
82732
83115
  const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
82733
83116
  args,
@@ -82793,7 +83176,19 @@ var init_subscription = __esm({
82793
83176
  description: "Display detailed information about a specific addon service including features, pricing, and requirements.",
82794
83177
  descriptionShort: "Show addon details",
82795
83178
  descriptionMedium: "Display detailed addon service information including features, pricing, and dependencies.",
82796
- usage: "<addon-name>",
83179
+ usage: "<addon-name> [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83180
+ async completion(_partial, args) {
83181
+ const flags = [
83182
+ "--format",
83183
+ "--spec",
83184
+ "--no-color",
83185
+ "json",
83186
+ "table",
83187
+ "yaml",
83188
+ "tsv"
83189
+ ];
83190
+ return generateSmartCompletions(this.usage, args, flags);
83191
+ },
82797
83192
  async execute(args, session) {
82798
83193
  const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
82799
83194
  args,
@@ -82869,7 +83264,19 @@ var init_subscription = __esm({
82869
83264
  description: "Display activation status for all addon services showing which are active, pending, or inactive.",
82870
83265
  descriptionShort: "Show addon activation status",
82871
83266
  descriptionMedium: "Display activation status for all addon services with detailed state information.",
82872
- usage: "",
83267
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83268
+ async completion(_partial, args) {
83269
+ const flags = [
83270
+ "--format",
83271
+ "--spec",
83272
+ "--no-color",
83273
+ "json",
83274
+ "table",
83275
+ "yaml",
83276
+ "tsv"
83277
+ ];
83278
+ return generateSmartCompletions(this.usage, args, flags);
83279
+ },
82873
83280
  async execute(args, session) {
82874
83281
  const { format, noColor, spec } = parseOutputArgs2(args, session);
82875
83282
  if (spec) {
@@ -82924,7 +83331,19 @@ var init_subscription = __esm({
82924
83331
  description: "Display all tenant-level quota limits including resource caps for load balancers, origins, sites, and other configurable resources.",
82925
83332
  descriptionShort: "Show quota limits",
82926
83333
  descriptionMedium: "Display all tenant-level resource quota limits and their current values.",
82927
- usage: "",
83334
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83335
+ async completion(_partial, args) {
83336
+ const flags = [
83337
+ "--format",
83338
+ "--spec",
83339
+ "--no-color",
83340
+ "json",
83341
+ "table",
83342
+ "yaml",
83343
+ "tsv"
83344
+ ];
83345
+ return generateSmartCompletions(this.usage, args, flags);
83346
+ },
82928
83347
  async execute(args, session) {
82929
83348
  const { format, noColor, spec } = parseOutputArgs2(args, session);
82930
83349
  if (spec) {
@@ -82985,7 +83404,21 @@ var init_subscription = __esm({
82985
83404
  description: "Display current quota usage against limits with utilization percentages. Use --critical to show only quotas above 80% utilization.",
82986
83405
  descriptionShort: "Show quota usage",
82987
83406
  descriptionMedium: "Display current resource usage against quota limits with utilization percentage.",
82988
- usage: "[--critical]",
83407
+ usage: "[--critical] [--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83408
+ async completion(_partial, args) {
83409
+ const flags = [
83410
+ "--critical",
83411
+ "-c",
83412
+ "--format",
83413
+ "--spec",
83414
+ "--no-color",
83415
+ "json",
83416
+ "table",
83417
+ "yaml",
83418
+ "tsv"
83419
+ ];
83420
+ return generateSmartCompletions(this.usage, args, flags);
83421
+ },
82989
83422
  async execute(args, session) {
82990
83423
  const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
82991
83424
  args,
@@ -83056,7 +83489,19 @@ var init_subscription = __esm({
83056
83489
  description: "Display current billing period usage including itemized costs and projected totals.",
83057
83490
  descriptionShort: "Show current period usage",
83058
83491
  descriptionMedium: "Display current billing period usage with cost breakdown and projections.",
83059
- usage: "",
83492
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83493
+ async completion(_partial, args) {
83494
+ const flags = [
83495
+ "--format",
83496
+ "--spec",
83497
+ "--no-color",
83498
+ "json",
83499
+ "table",
83500
+ "yaml",
83501
+ "tsv"
83502
+ ];
83503
+ return generateSmartCompletions(this.usage, args, flags);
83504
+ },
83060
83505
  async execute(args, session) {
83061
83506
  const { format, noColor, spec } = parseOutputArgs2(args, session);
83062
83507
  if (spec) {
@@ -83183,7 +83628,19 @@ var init_subscription = __esm({
83183
83628
  description: "List all configured payment methods showing type, status, and primary designation.",
83184
83629
  descriptionShort: "List payment methods",
83185
83630
  descriptionMedium: "Display all payment methods with type, status, and primary/secondary designation.",
83186
- usage: "",
83631
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83632
+ async completion(_partial, args) {
83633
+ const flags = [
83634
+ "--format",
83635
+ "--spec",
83636
+ "--no-color",
83637
+ "json",
83638
+ "table",
83639
+ "yaml",
83640
+ "tsv"
83641
+ ];
83642
+ return generateSmartCompletions(this.usage, args, flags);
83643
+ },
83187
83644
  async execute(args, session) {
83188
83645
  const { format, noColor, spec } = parseOutputArgs2(args, session);
83189
83646
  if (spec) {
@@ -83311,7 +83768,19 @@ var init_subscription = __esm({
83311
83768
  description: "Generate comprehensive subscription report combining plan details, addon status, quota utilization, usage metrics, and billing summary.",
83312
83769
  descriptionShort: "Generate subscription report",
83313
83770
  descriptionMedium: "Create comprehensive report with plan, addons, quotas, usage, and billing data.",
83314
- usage: "",
83771
+ usage: "[--format <json|table|yaml|tsv>] [--spec] [--no-color]",
83772
+ async completion(_partial, args) {
83773
+ const flags = [
83774
+ "--format",
83775
+ "--spec",
83776
+ "--no-color",
83777
+ "json",
83778
+ "table",
83779
+ "yaml",
83780
+ "tsv"
83781
+ ];
83782
+ return generateSmartCompletions(this.usage, args, flags);
83783
+ },
83315
83784
  async execute(args, session) {
83316
83785
  const { format, noColor, spec } = parseOutputArgs2(args, session);
83317
83786
  if (spec) {
@@ -84372,7 +84841,14 @@ var init_completer = __esm({
84372
84841
  );
84373
84842
  }
84374
84843
  if (subgroupNode?.children) {
84375
- if (args.length === 1 || args.length === 2 && currentWord === args[1]) {
84844
+ const cmdName = args[1]?.toLowerCase() ?? "";
84845
+ const domain2 = customDomains.get(domainName);
84846
+ let cmd = domain2?.actions?.get(subgroupName)?.resources.get(cmdName);
84847
+ if (!cmd) {
84848
+ const subgroup = domain2?.subcommands.get(subgroupName);
84849
+ cmd = subgroup?.commands.get(cmdName);
84850
+ }
84851
+ if (args.length === 1 || args.length === 2 && currentWord === args[1] && !cmd) {
84376
84852
  const prefix = args.length === 2 ? currentWord : "";
84377
84853
  return completionRegistry.getNestedChildSuggestions(
84378
84854
  domainName,
@@ -84380,14 +84856,7 @@ var init_completer = __esm({
84380
84856
  prefix
84381
84857
  );
84382
84858
  }
84383
- if (args.length >= 2 && this.session) {
84384
- const cmdName = args[1]?.toLowerCase() ?? "";
84385
- const domain2 = customDomains.get(domainName);
84386
- let cmd = domain2?.actions?.get(subgroupName)?.resources.get(cmdName);
84387
- if (!cmd) {
84388
- const subgroup = domain2?.subcommands.get(subgroupName);
84389
- cmd = subgroup?.commands.get(cmdName);
84390
- }
84859
+ if (args.length >= 2 && this.session && cmd) {
84391
84860
  if (cmd?.completion) {
84392
84861
  try {
84393
84862
  const completions = await cmd.completion(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robinmordasiewicz/f5xc-xcsh",
3
- "version": "2.0.21-2601142039",
3
+ "version": "2.0.21-2601142307",
4
4
  "description": "F5 Distributed Cloud Shell - Interactive CLI for F5 XC",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,7 +40,9 @@
40
40
  "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
41
41
  "typecheck": "tsc --noEmit",
42
42
  "security:audit": "npm audit --audit-level=high",
43
- "validate": "npm run typecheck && npm run lint && npm run format:check",
43
+ "analyze:consistency": "tsx scripts/analyze-command-consistency.ts",
44
+ "verify:consistency": "tsx scripts/verify-command-consistency.ts",
45
+ "validate": "npm run typecheck && npm run lint && npm run format:check && npm run verify:consistency",
44
46
  "generate:domains": "tsx scripts/generate-domains.ts",
45
47
  "generate:completions": "tsx scripts/generate-completions.ts",
46
48
  "generate:logo": "tsx scripts/generate-logo-asset.ts",