@robinmordasiewicz/f5xc-xcsh 2.0.27-2601160811 → 2.0.27-2601161808

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 +1422 -61
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2022,14 +2022,14 @@ var require_react_development = __commonJS({
2022
2022
  var thenableResult = result;
2023
2023
  var wasAwaited = false;
2024
2024
  var thenable = {
2025
- then: function(resolve2, reject) {
2025
+ then: function(resolve3, reject) {
2026
2026
  wasAwaited = true;
2027
2027
  thenableResult.then(function(returnValue2) {
2028
2028
  popActScope(prevActScopeDepth);
2029
2029
  if (actScopeDepth === 0) {
2030
- recursivelyFlushAsyncActWork(returnValue2, resolve2, reject);
2030
+ recursivelyFlushAsyncActWork(returnValue2, resolve3, reject);
2031
2031
  } else {
2032
- resolve2(returnValue2);
2032
+ resolve3(returnValue2);
2033
2033
  }
2034
2034
  }, function(error2) {
2035
2035
  popActScope(prevActScopeDepth);
@@ -2059,20 +2059,20 @@ var require_react_development = __commonJS({
2059
2059
  ReactCurrentActQueue.current = null;
2060
2060
  }
2061
2061
  var _thenable = {
2062
- then: function(resolve2, reject) {
2062
+ then: function(resolve3, reject) {
2063
2063
  if (ReactCurrentActQueue.current === null) {
2064
2064
  ReactCurrentActQueue.current = [];
2065
- recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
2065
+ recursivelyFlushAsyncActWork(returnValue, resolve3, reject);
2066
2066
  } else {
2067
- resolve2(returnValue);
2067
+ resolve3(returnValue);
2068
2068
  }
2069
2069
  }
2070
2070
  };
2071
2071
  return _thenable;
2072
2072
  } else {
2073
2073
  var _thenable2 = {
2074
- then: function(resolve2, reject) {
2075
- resolve2(returnValue);
2074
+ then: function(resolve3, reject) {
2075
+ resolve3(returnValue);
2076
2076
  }
2077
2077
  };
2078
2078
  return _thenable2;
@@ -2088,7 +2088,7 @@ var require_react_development = __commonJS({
2088
2088
  actScopeDepth = prevActScopeDepth;
2089
2089
  }
2090
2090
  }
2091
- function recursivelyFlushAsyncActWork(returnValue, resolve2, reject) {
2091
+ function recursivelyFlushAsyncActWork(returnValue, resolve3, reject) {
2092
2092
  {
2093
2093
  var queue = ReactCurrentActQueue.current;
2094
2094
  if (queue !== null) {
@@ -2097,16 +2097,16 @@ var require_react_development = __commonJS({
2097
2097
  enqueueTask(function() {
2098
2098
  if (queue.length === 0) {
2099
2099
  ReactCurrentActQueue.current = null;
2100
- resolve2(returnValue);
2100
+ resolve3(returnValue);
2101
2101
  } else {
2102
- recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
2102
+ recursivelyFlushAsyncActWork(returnValue, resolve3, reject);
2103
2103
  }
2104
2104
  });
2105
2105
  } catch (error2) {
2106
2106
  reject(error2);
2107
2107
  }
2108
2108
  } else {
2109
- resolve2(returnValue);
2109
+ resolve3(returnValue);
2110
2110
  }
2111
2111
  }
2112
2112
  }
@@ -28134,7 +28134,7 @@ var require_command = __commonJS({
28134
28134
  var EventEmitter3 = __require("events").EventEmitter;
28135
28135
  var childProcess = __require("child_process");
28136
28136
  var path = __require("path");
28137
- var fs4 = __require("fs");
28137
+ var fs5 = __require("fs");
28138
28138
  var process13 = __require("process");
28139
28139
  var { Argument: Argument2, humanReadableArgName } = require_argument();
28140
28140
  var { CommanderError: CommanderError2 } = require_error();
@@ -29067,10 +29067,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
29067
29067
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
29068
29068
  function findFile(baseDir, baseName) {
29069
29069
  const localBin = path.resolve(baseDir, baseName);
29070
- if (fs4.existsSync(localBin)) return localBin;
29070
+ if (fs5.existsSync(localBin)) return localBin;
29071
29071
  if (sourceExt.includes(path.extname(baseName))) return void 0;
29072
29072
  const foundExt = sourceExt.find(
29073
- (ext) => fs4.existsSync(`${localBin}${ext}`)
29073
+ (ext) => fs5.existsSync(`${localBin}${ext}`)
29074
29074
  );
29075
29075
  if (foundExt) return `${localBin}${foundExt}`;
29076
29076
  return void 0;
@@ -29082,7 +29082,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
29082
29082
  if (this._scriptPath) {
29083
29083
  let resolvedScriptPath;
29084
29084
  try {
29085
- resolvedScriptPath = fs4.realpathSync(this._scriptPath);
29085
+ resolvedScriptPath = fs5.realpathSync(this._scriptPath);
29086
29086
  } catch (err) {
29087
29087
  resolvedScriptPath = this._scriptPath;
29088
29088
  }
@@ -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.27-2601160811") {
41232
- return "v2.0.27-2601160811";
41231
+ if ("v2.0.27-2601161808") {
41232
+ return "v2.0.27-2601161808";
41233
41233
  }
41234
41234
  if (process.env.XCSH_VERSION) {
41235
41235
  return process.env.XCSH_VERSION;
@@ -48151,14 +48151,14 @@ var require_parser = __commonJS({
48151
48151
  case "scalar":
48152
48152
  case "single-quoted-scalar":
48153
48153
  case "double-quoted-scalar": {
48154
- const fs4 = this.flowScalar(this.type);
48154
+ const fs5 = this.flowScalar(this.type);
48155
48155
  if (atNextItem || it.value) {
48156
- map.items.push({ start, key: fs4, sep: [] });
48156
+ map.items.push({ start, key: fs5, sep: [] });
48157
48157
  this.onKeyLine = true;
48158
48158
  } else if (it.sep) {
48159
- this.stack.push(fs4);
48159
+ this.stack.push(fs5);
48160
48160
  } else {
48161
- Object.assign(it, { key: fs4, sep: [] });
48161
+ Object.assign(it, { key: fs5, sep: [] });
48162
48162
  this.onKeyLine = true;
48163
48163
  }
48164
48164
  return;
@@ -48286,13 +48286,13 @@ var require_parser = __commonJS({
48286
48286
  case "scalar":
48287
48287
  case "single-quoted-scalar":
48288
48288
  case "double-quoted-scalar": {
48289
- const fs4 = this.flowScalar(this.type);
48289
+ const fs5 = this.flowScalar(this.type);
48290
48290
  if (!it || it.value)
48291
- fc.items.push({ start: [], key: fs4, sep: [] });
48291
+ fc.items.push({ start: [], key: fs5, sep: [] });
48292
48292
  else if (it.sep)
48293
- this.stack.push(fs4);
48293
+ this.stack.push(fs5);
48294
48294
  else
48295
- Object.assign(it, { key: fs4, sep: [] });
48295
+ Object.assign(it, { key: fs5, sep: [] });
48296
48296
  return;
48297
48297
  }
48298
48298
  case "flow-map-end":
@@ -50094,9 +50094,13 @@ var init_settings = __esm({
50094
50094
  ];
50095
50095
  LOGO_MODE_HELP = LOGO_MODES.map((m) => m.mode).join(", ");
50096
50096
  COMPLETION_MODES = [
50097
+ {
50098
+ mode: "standard",
50099
+ description: "Show primary and CRUD resources with valid descriptions (default)"
50100
+ },
50097
50101
  {
50098
50102
  mode: "all",
50099
- description: "Show all discovered resources (default)"
50103
+ description: "Show all discovered resources"
50100
50104
  },
50101
50105
  {
50102
50106
  mode: "primary",
@@ -50108,7 +50112,7 @@ var init_settings = __esm({
50108
50112
  );
50109
50113
  DEFAULT_SETTINGS = {
50110
50114
  logo: "image",
50111
- completionMode: "all"
50115
+ completionMode: "standard"
50112
50116
  };
50113
50117
  }
50114
50118
  });
@@ -77869,6 +77873,118 @@ var init_response_renderer = __esm({
77869
77873
  }
77870
77874
  });
77871
77875
 
77876
+ // src/repl/completion/flag-aliases.ts
77877
+ function buildFlagAliasLookup() {
77878
+ const lookup = /* @__PURE__ */ new Map();
77879
+ for (const group of FLAG_ALIAS_GROUPS) {
77880
+ const allForms = new Set(group);
77881
+ for (const flag of group) {
77882
+ lookup.set(flag, allForms);
77883
+ }
77884
+ }
77885
+ return lookup;
77886
+ }
77887
+ var FLAG_ALIAS_GROUPS, FLAG_ALIAS_LOOKUP;
77888
+ var init_flag_aliases = __esm({
77889
+ "src/repl/completion/flag-aliases.ts"() {
77890
+ "use strict";
77891
+ FLAG_ALIAS_GROUPS = [
77892
+ // Common flags
77893
+ ["--namespace", "-ns"],
77894
+ ["--output", "-o"],
77895
+ ["--name", "-n"],
77896
+ ["--file", "-f"],
77897
+ ["--url", "-u"],
77898
+ ["--limit"],
77899
+ ["--label"],
77900
+ ["--show-labels"],
77901
+ ["--force"],
77902
+ ["--cascade"],
77903
+ // Creation flags for healthcheck
77904
+ ["--type", "-t"],
77905
+ ["--interval"],
77906
+ ["--timeout"],
77907
+ ["--healthy-threshold"],
77908
+ ["--unhealthy-threshold"],
77909
+ ["--path"],
77910
+ ["--expected-status"],
77911
+ ["--host-header"],
77912
+ ["--use-origin-server-name"],
77913
+ ["--use-http2"],
77914
+ // Creation flags for origin_pool
77915
+ ["--port"],
77916
+ ["--automatic-port"],
77917
+ ["--lb-port"],
77918
+ ["--public-ip"],
77919
+ ["--public-name"],
77920
+ ["--private-ip"],
77921
+ ["--private-name"],
77922
+ ["--k8s-service"],
77923
+ ["--consul-service"],
77924
+ ["--custom-endpoint"],
77925
+ ["--vn-private-ip"],
77926
+ ["--vn-private-name"],
77927
+ ["--cbip-service"],
77928
+ ["--algorithm"],
77929
+ ["--health-check"],
77930
+ ["--no-tls"],
77931
+ ["--use-tls"],
77932
+ ["--site"]
77933
+ ];
77934
+ FLAG_ALIAS_LOOKUP = buildFlagAliasLookup();
77935
+ }
77936
+ });
77937
+
77938
+ // src/repl/completion/flag-utils.ts
77939
+ function extractUsedFlags(args) {
77940
+ const usedFlags = /* @__PURE__ */ new Set();
77941
+ for (const arg of args) {
77942
+ let flagPart = arg;
77943
+ if (arg.includes("=")) {
77944
+ flagPart = arg.split("=")[0] ?? arg;
77945
+ }
77946
+ if (!flagPart.startsWith("-")) {
77947
+ continue;
77948
+ }
77949
+ usedFlags.add(flagPart);
77950
+ const aliases = FLAG_ALIAS_LOOKUP.get(flagPart);
77951
+ if (aliases) {
77952
+ for (const alias of aliases) {
77953
+ usedFlags.add(alias);
77954
+ }
77955
+ }
77956
+ }
77957
+ return usedFlags;
77958
+ }
77959
+ function filterUsedFlags(suggestions, usedFlags) {
77960
+ return suggestions.filter((s) => !usedFlags.has(s.text));
77961
+ }
77962
+ function filterUsedFlagsFromStrings(flags, args) {
77963
+ const usedFlags = extractUsedFlags(args);
77964
+ return flags.filter((flag) => !usedFlags.has(flag));
77965
+ }
77966
+ function countFlagUsage(args) {
77967
+ const counts = /* @__PURE__ */ new Map();
77968
+ for (const arg of args) {
77969
+ let flagPart = arg;
77970
+ if (arg.includes("=")) {
77971
+ flagPart = arg.split("=")[0] ?? arg;
77972
+ }
77973
+ if (!flagPart.startsWith("-")) {
77974
+ continue;
77975
+ }
77976
+ const current = counts.get(flagPart) || 0;
77977
+ counts.set(flagPart, current + 1);
77978
+ }
77979
+ return counts;
77980
+ }
77981
+ var init_flag_utils = __esm({
77982
+ "src/repl/completion/flag-utils.ts"() {
77983
+ "use strict";
77984
+ init_flag_aliases();
77985
+ }
77986
+ });
77987
+
77872
77988
  // src/utils/usage-parser.ts
77873
77989
  function parseUsage(usageString) {
77874
77990
  if (!usageString) {
@@ -77973,25 +78089,27 @@ function stripBrackets(token) {
77973
78089
  return token.replace(/^[<[]/, "").replace(/[>\]]$/, "");
77974
78090
  }
77975
78091
  function generateSmartCompletions(usage, args, flags) {
78092
+ const availableFlags = filterUsedFlagsFromStrings(flags, args);
77976
78093
  if (!usage) {
77977
- return flags;
78094
+ return availableFlags;
77978
78095
  }
77979
78096
  const requirements = parseUsage(usage);
77980
78097
  const positionalArgsProvided = args.filter(
77981
- (arg) => !arg.startsWith("--")
78098
+ (arg) => !arg.startsWith("-")
77982
78099
  ).length;
77983
78100
  const requiredPositional = requirements.positional.filter(
77984
78101
  (p) => p.required
77985
78102
  );
77986
78103
  if (positionalArgsProvided < requiredPositional.length) {
77987
78104
  const placeholders = requiredPositional.slice(positionalArgsProvided).map((p) => `<${p.name}>`);
77988
- return [...placeholders, ...flags];
78105
+ return [...placeholders, ...availableFlags];
77989
78106
  }
77990
- return flags;
78107
+ return availableFlags;
77991
78108
  }
77992
78109
  var init_usage_parser = __esm({
77993
78110
  "src/utils/usage-parser.ts"() {
77994
78111
  "use strict";
78112
+ init_flag_utils();
77995
78113
  }
77996
78114
  });
77997
78115
 
@@ -84586,7 +84704,292 @@ var init_resource_fetcher = __esm({
84586
84704
  }
84587
84705
  });
84588
84706
 
84707
+ // src/repl/completion/creation-flags.ts
84708
+ function getCreationFlags(resourceType) {
84709
+ return CREATION_FLAGS_REGISTRY.get(resourceType) ?? [];
84710
+ }
84711
+ function hasCreationFlags(resourceType) {
84712
+ return CREATION_FLAGS_REGISTRY.has(resourceType);
84713
+ }
84714
+ var HEALTHCHECK_CREATION_FLAGS, ORIGIN_POOL_CREATION_FLAGS, CREATION_FLAGS_REGISTRY;
84715
+ var init_creation_flags = __esm({
84716
+ "src/repl/completion/creation-flags.ts"() {
84717
+ "use strict";
84718
+ HEALTHCHECK_CREATION_FLAGS = [
84719
+ // Required flags
84720
+ {
84721
+ name: "--name",
84722
+ shortName: "-n",
84723
+ description: "Resource name",
84724
+ required: true,
84725
+ hasValue: true,
84726
+ valueType: "string"
84727
+ },
84728
+ {
84729
+ name: "--type",
84730
+ shortName: "-t",
84731
+ description: "Health check type",
84732
+ required: true,
84733
+ hasValue: true,
84734
+ valueType: "enum",
84735
+ enumValues: ["http", "tcp", "dns", "udp-icmp"]
84736
+ },
84737
+ {
84738
+ name: "--interval",
84739
+ description: "Interval between checks (1-600 sec)",
84740
+ required: true,
84741
+ hasValue: true,
84742
+ valueType: "integer"
84743
+ },
84744
+ {
84745
+ name: "--timeout",
84746
+ description: "Timeout for each check (1-600 sec)",
84747
+ required: true,
84748
+ hasValue: true,
84749
+ valueType: "integer"
84750
+ },
84751
+ {
84752
+ name: "--healthy-threshold",
84753
+ description: "Successes before healthy (1-16)",
84754
+ required: true,
84755
+ hasValue: true,
84756
+ valueType: "integer"
84757
+ },
84758
+ {
84759
+ name: "--unhealthy-threshold",
84760
+ description: "Failures before unhealthy (1-16)",
84761
+ required: true,
84762
+ hasValue: true,
84763
+ valueType: "integer"
84764
+ },
84765
+ // HTTP-specific (conditionally required when type=http)
84766
+ {
84767
+ name: "--path",
84768
+ description: "HTTP path to check",
84769
+ required: false,
84770
+ hasValue: true,
84771
+ valueType: "string"
84772
+ },
84773
+ {
84774
+ name: "--expected-status",
84775
+ description: "Expected HTTP status codes",
84776
+ required: false,
84777
+ hasValue: true,
84778
+ valueType: "string"
84779
+ },
84780
+ {
84781
+ name: "--host-header",
84782
+ description: "Host header value",
84783
+ required: false,
84784
+ hasValue: true,
84785
+ valueType: "string"
84786
+ },
84787
+ {
84788
+ name: "--use-origin-server-name",
84789
+ description: "Use origin server hostname",
84790
+ required: false,
84791
+ hasValue: false
84792
+ },
84793
+ {
84794
+ name: "--use-http2",
84795
+ description: "Use HTTP/2",
84796
+ required: false,
84797
+ hasValue: false
84798
+ }
84799
+ ];
84800
+ ORIGIN_POOL_CREATION_FLAGS = [
84801
+ // Required - Name
84802
+ {
84803
+ name: "--name",
84804
+ shortName: "-n",
84805
+ description: "Origin pool name",
84806
+ required: true,
84807
+ hasValue: true,
84808
+ valueType: "string"
84809
+ },
84810
+ // Port configuration (mutually exclusive group)
84811
+ {
84812
+ name: "--port",
84813
+ description: "Backend port (1-65535)",
84814
+ required: false,
84815
+ hasValue: true,
84816
+ valueType: "integer"
84817
+ },
84818
+ {
84819
+ name: "--automatic-port",
84820
+ description: "Use automatic port selection",
84821
+ required: false,
84822
+ hasValue: false
84823
+ },
84824
+ {
84825
+ name: "--lb-port",
84826
+ description: "Use load balancer port",
84827
+ required: false,
84828
+ hasValue: false
84829
+ },
84830
+ // Origin Server Types (ALL 10 - REPEATABLE)
84831
+ {
84832
+ name: "--public-ip",
84833
+ description: "Public IP origin server (repeatable)",
84834
+ required: false,
84835
+ hasValue: true,
84836
+ valueType: "string",
84837
+ isRepeatable: true,
84838
+ maxOccurrences: 32
84839
+ },
84840
+ {
84841
+ name: "--public-name",
84842
+ description: "Public DNS name origin (repeatable)",
84843
+ required: false,
84844
+ hasValue: true,
84845
+ valueType: "string",
84846
+ isRepeatable: true,
84847
+ maxOccurrences: 32
84848
+ },
84849
+ {
84850
+ name: "--private-ip",
84851
+ description: "Private IP origin (site required) (repeatable)",
84852
+ required: false,
84853
+ hasValue: true,
84854
+ valueType: "string",
84855
+ isRepeatable: true,
84856
+ maxOccurrences: 32
84857
+ },
84858
+ {
84859
+ name: "--private-name",
84860
+ description: "Private DNS name origin (site required) (repeatable)",
84861
+ required: false,
84862
+ hasValue: true,
84863
+ valueType: "string",
84864
+ isRepeatable: true,
84865
+ maxOccurrences: 32
84866
+ },
84867
+ {
84868
+ name: "--k8s-service",
84869
+ description: "Kubernetes service origin (format: namespace/service) (repeatable)",
84870
+ required: false,
84871
+ hasValue: true,
84872
+ valueType: "string",
84873
+ isRepeatable: true,
84874
+ maxOccurrences: 32
84875
+ },
84876
+ {
84877
+ name: "--consul-service",
84878
+ description: "Consul service origin (repeatable)",
84879
+ required: false,
84880
+ hasValue: true,
84881
+ valueType: "string",
84882
+ isRepeatable: true,
84883
+ maxOccurrences: 32
84884
+ },
84885
+ {
84886
+ name: "--custom-endpoint",
84887
+ description: "Custom endpoint object reference (repeatable)",
84888
+ required: false,
84889
+ hasValue: true,
84890
+ valueType: "string",
84891
+ isRepeatable: true,
84892
+ maxOccurrences: 32
84893
+ },
84894
+ {
84895
+ name: "--vn-private-ip",
84896
+ description: "Virtual network private IP (repeatable)",
84897
+ required: false,
84898
+ hasValue: true,
84899
+ valueType: "string",
84900
+ isRepeatable: true,
84901
+ maxOccurrences: 32
84902
+ },
84903
+ {
84904
+ name: "--vn-private-name",
84905
+ description: "Virtual network private DNS name (repeatable)",
84906
+ required: false,
84907
+ hasValue: true,
84908
+ valueType: "string",
84909
+ isRepeatable: true,
84910
+ maxOccurrences: 32
84911
+ },
84912
+ {
84913
+ name: "--cbip-service",
84914
+ description: "Cloud-based IP service (repeatable)",
84915
+ required: false,
84916
+ hasValue: true,
84917
+ valueType: "string",
84918
+ isRepeatable: true,
84919
+ maxOccurrences: 32
84920
+ },
84921
+ // Load Balancing Algorithm
84922
+ {
84923
+ name: "--algorithm",
84924
+ description: "Load balancing algorithm",
84925
+ required: false,
84926
+ hasValue: true,
84927
+ valueType: "enum",
84928
+ enumValues: [
84929
+ "ROUND_ROBIN",
84930
+ "LEAST_ACTIVE",
84931
+ "RANDOM",
84932
+ "SOURCE_IP_STICKINESS",
84933
+ "COOKIE_STICKINESS",
84934
+ "RING_HASH"
84935
+ ]
84936
+ },
84937
+ // Health Checks (repeatable, max 4)
84938
+ {
84939
+ name: "--health-check",
84940
+ description: "Health check reference (repeatable, max 4)",
84941
+ required: false,
84942
+ hasValue: true,
84943
+ valueType: "string",
84944
+ isRepeatable: true,
84945
+ maxOccurrences: 4
84946
+ },
84947
+ // TLS Configuration
84948
+ {
84949
+ name: "--no-tls",
84950
+ description: "Disable TLS for origin connections",
84951
+ required: false,
84952
+ hasValue: false
84953
+ },
84954
+ {
84955
+ name: "--use-tls",
84956
+ description: "Enable TLS for origin connections",
84957
+ required: false,
84958
+ hasValue: false
84959
+ },
84960
+ // Site reference (for private origins)
84961
+ {
84962
+ name: "--site",
84963
+ description: "Site reference for private origins",
84964
+ required: false,
84965
+ hasValue: true,
84966
+ valueType: "string"
84967
+ }
84968
+ ];
84969
+ CREATION_FLAGS_REGISTRY = /* @__PURE__ */ new Map([
84970
+ ["healthcheck", HEALTHCHECK_CREATION_FLAGS],
84971
+ ["origin_pool", ORIGIN_POOL_CREATION_FLAGS]
84972
+ ]);
84973
+ }
84974
+ });
84975
+
84589
84976
  // src/repl/completion/completer.ts
84977
+ function isResourceCompletionAppropriate(resource) {
84978
+ if (resource.isPrimary) {
84979
+ return true;
84980
+ }
84981
+ if (resource.resourceCategory && EXCLUDED_RESOURCE_CATEGORIES.has(resource.resourceCategory)) {
84982
+ return false;
84983
+ }
84984
+ const desc = resource.descriptionShort || resource.description || "";
84985
+ if (GENERIC_RESOURCE_DESCRIPTIONS.has(desc)) {
84986
+ return false;
84987
+ }
84988
+ if (desc.toLowerCase() === resource.name.toLowerCase().replace(/_/g, " ")) {
84989
+ return false;
84990
+ }
84991
+ return true;
84992
+ }
84590
84993
  function parseInputArgs(text) {
84591
84994
  const args = [];
84592
84995
  let current = "";
@@ -84642,7 +85045,32 @@ function parseInput(text) {
84642
85045
  "--file",
84643
85046
  "-f",
84644
85047
  "--limit",
84645
- "--label"
85048
+ "--label",
85049
+ // Creation flags for healthcheck
85050
+ "--type",
85051
+ "-t",
85052
+ "--interval",
85053
+ "--timeout",
85054
+ "--healthy-threshold",
85055
+ "--unhealthy-threshold",
85056
+ "--path",
85057
+ "--expected-status",
85058
+ "--host-header",
85059
+ // Creation flags for origin_pool
85060
+ "--port",
85061
+ "--public-ip",
85062
+ "--public-name",
85063
+ "--private-ip",
85064
+ "--private-name",
85065
+ "--k8s-service",
85066
+ "--consul-service",
85067
+ "--custom-endpoint",
85068
+ "--vn-private-ip",
85069
+ "--vn-private-name",
85070
+ "--cbip-service",
85071
+ "--algorithm",
85072
+ "--health-check",
85073
+ "--site"
84646
85074
  ];
84647
85075
  if (args.length >= 1 && !currentWord.startsWith("-")) {
84648
85076
  const flagIndex = endsWithSpace ? args.length - 1 : args.length - 2;
@@ -84671,7 +85099,7 @@ function parseInput(text) {
84671
85099
  currentFlag
84672
85100
  };
84673
85101
  }
84674
- var RESOURCE_ACTIONS, Completer;
85102
+ var RESOURCE_ACTIONS, CREATION_ACTIONS, GENERIC_RESOURCE_DESCRIPTIONS, EXCLUDED_RESOURCE_CATEGORIES, Completer;
84675
85103
  var init_completer = __esm({
84676
85104
  "src/repl/completion/completer.ts"() {
84677
85105
  "use strict";
@@ -84683,6 +85111,8 @@ var init_completer = __esm({
84683
85111
  init_domains();
84684
85112
  init_resource_fetcher();
84685
85113
  init_settings();
85114
+ init_flag_utils();
85115
+ init_creation_flags();
84686
85116
  RESOURCE_ACTIONS = /* @__PURE__ */ new Set([
84687
85117
  "list",
84688
85118
  "get",
@@ -84695,6 +85125,18 @@ var init_completer = __esm({
84695
85125
  "add-labels",
84696
85126
  "remove-labels"
84697
85127
  ]);
85128
+ CREATION_ACTIONS = /* @__PURE__ */ new Set(["create", "apply"]);
85129
+ GENERIC_RESOURCE_DESCRIPTIONS = /* @__PURE__ */ new Set([
85130
+ "Resource retrieval operation",
85131
+ "Resource creation operation",
85132
+ "Resource update operation",
85133
+ "Resource deletion operation"
85134
+ ]);
85135
+ EXCLUDED_RESOURCE_CATEGORIES = /* @__PURE__ */ new Set([
85136
+ "analytics",
85137
+ "utility",
85138
+ "management"
85139
+ ]);
84698
85140
  Completer = class {
84699
85141
  session = null;
84700
85142
  cache;
@@ -84705,7 +85147,7 @@ var init_completer = __esm({
84705
85147
  this.cache = new CompletionCache();
84706
85148
  this.settings = loadSettingsSync();
84707
85149
  const cliCompletionMode = process.env.XCSH_COMPLETION_MODE;
84708
- if (cliCompletionMode && (cliCompletionMode === "all" || cliCompletionMode === "primary")) {
85150
+ if (cliCompletionMode && (cliCompletionMode === "all" || cliCompletionMode === "primary" || cliCompletionMode === "standard")) {
84709
85151
  this.settings.completionMode = cliCompletionMode;
84710
85152
  }
84711
85153
  }
@@ -84749,12 +85191,19 @@ var init_completer = __esm({
84749
85191
  );
84750
85192
  }
84751
85193
  if (parsed.isCompletingFlag) {
84752
- return this.getFlagCompletions(
85194
+ return this.getAvailableFlagCompletions(
84753
85195
  parsed.currentWord,
84754
- resourceCtx.action ?? void 0
85196
+ resourceCtx.action ?? void 0,
85197
+ parsed.args
84755
85198
  );
84756
85199
  }
84757
85200
  if (resourceCtx.resourceType) {
85201
+ if (resourceCtx.action && CREATION_ACTIONS.has(resourceCtx.action) && hasCreationFlags(resourceCtx.resourceType)) {
85202
+ return this.getCreationFlagSuggestions(
85203
+ resourceCtx.resourceType,
85204
+ parsed.args
85205
+ );
85206
+ }
84758
85207
  const resourceNames = await this.getResourceNameSuggestions(
84759
85208
  resourceCtx.resourceType,
84760
85209
  resourceCtx.resourceNamePartial
@@ -84762,29 +85211,36 @@ var init_completer = __esm({
84762
85211
  if (resourceNames.length > 0) {
84763
85212
  return resourceNames;
84764
85213
  }
84765
- return this.getActionFlagSuggestions(
85214
+ const allFlags = this.getActionFlagSuggestions(
84766
85215
  resourceCtx.action ?? void 0
84767
85216
  );
85217
+ const usedFlags = extractUsedFlags(parsed.args);
85218
+ return filterUsedFlags(allFlags, usedFlags);
84768
85219
  }
84769
85220
  if (resourceCtx.domain && resourceCtx.action && RESOURCE_ACTIONS.has(resourceCtx.action) && !resourceCtx.resourceType) {
84770
85221
  const resourceTypes = this.getResourceTypeSuggestions(
84771
85222
  resourceCtx.domain
84772
85223
  );
84773
85224
  if (resourceTypes.length > 0) {
85225
+ let suggestions2 = resourceTypes;
84774
85226
  if (parsed.currentWord && !parsed.currentWord.startsWith("-") && parsed.currentWord.toLowerCase() !== resourceCtx.action) {
84775
85227
  const filtered = this.filterSuggestions(
84776
85228
  resourceTypes,
84777
85229
  parsed.currentWord
84778
85230
  );
84779
85231
  if (filtered.length > 0) {
84780
- return filtered;
85232
+ suggestions2 = filtered;
84781
85233
  }
84782
- } else if (!parsed.currentWord || parsed.currentWord.toLowerCase() === resourceCtx.action) {
84783
- return [
84784
- ...resourceTypes,
84785
- ...this.getActionFlagSuggestions(resourceCtx.action)
84786
- ];
84787
85234
  }
85235
+ const actionFlags = this.getActionFlagSuggestions(
85236
+ resourceCtx.action
85237
+ );
85238
+ const usedFlagsInContext = extractUsedFlags(parsed.args);
85239
+ const availableActionFlags = filterUsedFlags(
85240
+ actionFlags,
85241
+ usedFlagsInContext
85242
+ );
85243
+ return [...suggestions2, ...availableActionFlags];
84788
85244
  }
84789
85245
  }
84790
85246
  let suggestions;
@@ -84803,9 +85259,14 @@ var init_completer = __esm({
84803
85259
  if (!hasAction) {
84804
85260
  suggestions = this.getActionSuggestions();
84805
85261
  } else {
84806
- suggestions = this.getActionFlagSuggestions(
85262
+ const flagsForAction = this.getActionFlagSuggestions(
84807
85263
  parsed.args[1]?.toLowerCase()
84808
85264
  );
85265
+ const usedFlagsHere = extractUsedFlags(parsed.args);
85266
+ suggestions = filterUsedFlags(
85267
+ flagsForAction,
85268
+ usedFlagsHere
85269
+ );
84809
85270
  }
84810
85271
  } else {
84811
85272
  suggestions = completionRegistry.getChildSuggestions(
@@ -85087,7 +85548,10 @@ var init_completer = __esm({
85087
85548
  * Get resource type suggestions for a domain
85088
85549
  * Phase 1 Enhancement: Uses allResources (dynamically discovered) by default
85089
85550
  * Falls back to primaryResources if allResources not available
85090
- * Respects user configuration setting for completion mode
85551
+ * Respects user configuration setting for completion mode:
85552
+ * - "primary": Only curated primary resources
85553
+ * - "standard": Primary + CRUD resources with meaningful descriptions (default)
85554
+ * - "all": Everything discovered from OpenAPI
85091
85555
  */
85092
85556
  getResourceTypeSuggestions(domain) {
85093
85557
  const domainInfo = getDomainInfo(domain);
@@ -85097,6 +85561,12 @@ var init_completer = __esm({
85097
85561
  let resources;
85098
85562
  if (this.settings.completionMode === "primary") {
85099
85563
  resources = domainInfo.primaryResources;
85564
+ } else if (this.settings.completionMode === "standard") {
85565
+ const allResources = domainInfo.allResources || domainInfo.primaryResources;
85566
+ resources = allResources?.filter(isResourceCompletionAppropriate);
85567
+ if (!resources || resources.length === 0) {
85568
+ resources = domainInfo.primaryResources;
85569
+ }
85100
85570
  } else {
85101
85571
  resources = domainInfo.allResources || domainInfo.primaryResources;
85102
85572
  }
@@ -85295,6 +85765,60 @@ var init_completer = __esm({
85295
85765
  }
85296
85766
  return actionFlags;
85297
85767
  }
85768
+ /**
85769
+ * Get creation flag suggestions for a resource type
85770
+ * Shows flags needed to create a new resource (--name, --type, etc.)
85771
+ * instead of existing resource names
85772
+ *
85773
+ * Handles repeatable flags (e.g., --public-ip can be specified multiple times)
85774
+ * by checking maxOccurrences instead of simply filtering out used flags.
85775
+ *
85776
+ * @param resourceType - The resource type being created
85777
+ * @param args - Current command arguments to filter out used flags
85778
+ * @returns Array of flag suggestions for resource creation
85779
+ */
85780
+ getCreationFlagSuggestions(resourceType, args) {
85781
+ const creationFlags = getCreationFlags(resourceType);
85782
+ const usedFlags = extractUsedFlags(args);
85783
+ const flagUsageCounts = countFlagUsage(args);
85784
+ const suggestions = [];
85785
+ if (!usedFlags.has("--file") && !usedFlags.has("-f")) {
85786
+ suggestions.push({
85787
+ text: "--file",
85788
+ description: "Configuration file (YAML/JSON)",
85789
+ category: "flag"
85790
+ });
85791
+ }
85792
+ for (const flag of creationFlags) {
85793
+ if (flag.isRepeatable) {
85794
+ const count = flagUsageCounts.get(flag.name) || 0;
85795
+ const max = flag.maxOccurrences || Infinity;
85796
+ if (count >= max) continue;
85797
+ const marker = " (repeatable)";
85798
+ suggestions.push({
85799
+ text: flag.name,
85800
+ description: flag.description + marker,
85801
+ category: "flag"
85802
+ });
85803
+ } else {
85804
+ if (usedFlags.has(flag.name)) continue;
85805
+ if (flag.shortName && usedFlags.has(flag.shortName)) continue;
85806
+ const marker = flag.required ? " (required)" : "";
85807
+ suggestions.push({
85808
+ text: flag.name,
85809
+ description: flag.description + marker,
85810
+ category: "flag"
85811
+ });
85812
+ }
85813
+ }
85814
+ const commonFlags = this.getCommonFlagSuggestions();
85815
+ for (const flag of commonFlags) {
85816
+ if (!usedFlags.has(flag.text)) {
85817
+ suggestions.push(flag);
85818
+ }
85819
+ }
85820
+ return suggestions;
85821
+ }
85298
85822
  /**
85299
85823
  * Get flag completions filtered by prefix
85300
85824
  * @param prefix - The prefix to filter by
@@ -85304,6 +85828,18 @@ var init_completer = __esm({
85304
85828
  const allFlags = this.getActionFlagSuggestions(action);
85305
85829
  return this.filterSuggestions(allFlags, prefix);
85306
85830
  }
85831
+ /**
85832
+ * Get available flag completions excluding already-used flags
85833
+ * @param prefix - The prefix to filter by
85834
+ * @param action - Optional action for action-specific flags
85835
+ * @param args - Current command arguments to check for used flags
85836
+ */
85837
+ getAvailableFlagCompletions(prefix, action, args = []) {
85838
+ const allFlags = this.getActionFlagSuggestions(action);
85839
+ const usedFlags = extractUsedFlags(args);
85840
+ const availableFlags = filterUsedFlags(allFlags, usedFlags);
85841
+ return this.filterSuggestions(availableFlags, prefix);
85842
+ }
85307
85843
  /**
85308
85844
  * Extract a flag value from args array
85309
85845
  * @param args - Array of command arguments
@@ -85387,6 +85923,159 @@ var init_completer = __esm({
85387
85923
  category: "value"
85388
85924
  }
85389
85925
  ].filter((s) => s.text.startsWith(valuePartial));
85926
+ // Creation flag value completions for healthcheck
85927
+ case "--type":
85928
+ case "-t":
85929
+ return [
85930
+ {
85931
+ text: "http",
85932
+ description: "HTTP health check",
85933
+ category: "value"
85934
+ },
85935
+ {
85936
+ text: "tcp",
85937
+ description: "TCP health check",
85938
+ category: "value"
85939
+ },
85940
+ {
85941
+ text: "dns",
85942
+ description: "DNS health check",
85943
+ category: "value"
85944
+ },
85945
+ {
85946
+ text: "udp-icmp",
85947
+ description: "UDP ICMP health check",
85948
+ category: "value"
85949
+ }
85950
+ ].filter((s) => s.text.startsWith(lowerPartial));
85951
+ case "--interval":
85952
+ case "--timeout":
85953
+ return [
85954
+ {
85955
+ text: "5",
85956
+ description: "5 seconds",
85957
+ category: "value"
85958
+ },
85959
+ {
85960
+ text: "10",
85961
+ description: "10 seconds",
85962
+ category: "value"
85963
+ },
85964
+ {
85965
+ text: "30",
85966
+ description: "30 seconds",
85967
+ category: "value"
85968
+ },
85969
+ {
85970
+ text: "60",
85971
+ description: "1 minute",
85972
+ category: "value"
85973
+ }
85974
+ ].filter((s) => s.text.startsWith(valuePartial));
85975
+ case "--healthy-threshold":
85976
+ case "--unhealthy-threshold":
85977
+ return [
85978
+ {
85979
+ text: "2",
85980
+ description: "2 checks",
85981
+ category: "value"
85982
+ },
85983
+ {
85984
+ text: "3",
85985
+ description: "3 checks",
85986
+ category: "value"
85987
+ },
85988
+ {
85989
+ text: "5",
85990
+ description: "5 checks",
85991
+ category: "value"
85992
+ }
85993
+ ].filter((s) => s.text.startsWith(valuePartial));
85994
+ case "--path":
85995
+ return [
85996
+ {
85997
+ text: "/health",
85998
+ description: "Common health endpoint",
85999
+ category: "value"
86000
+ },
86001
+ {
86002
+ text: "/healthz",
86003
+ description: "Kubernetes-style",
86004
+ category: "value"
86005
+ },
86006
+ {
86007
+ text: "/ready",
86008
+ description: "Readiness endpoint",
86009
+ category: "value"
86010
+ },
86011
+ {
86012
+ text: "/",
86013
+ description: "Root path",
86014
+ category: "value"
86015
+ }
86016
+ ].filter((s) => s.text.toLowerCase().startsWith(lowerPartial));
86017
+ // Origin pool flag value completions
86018
+ case "--algorithm":
86019
+ return [
86020
+ {
86021
+ text: "ROUND_ROBIN",
86022
+ description: "Round robin distribution",
86023
+ category: "value"
86024
+ },
86025
+ {
86026
+ text: "LEAST_ACTIVE",
86027
+ description: "Least active connections",
86028
+ category: "value"
86029
+ },
86030
+ {
86031
+ text: "RANDOM",
86032
+ description: "Random selection",
86033
+ category: "value"
86034
+ },
86035
+ {
86036
+ text: "SOURCE_IP_STICKINESS",
86037
+ description: "Sticky by source IP",
86038
+ category: "value"
86039
+ },
86040
+ {
86041
+ text: "COOKIE_STICKINESS",
86042
+ description: "Sticky by cookie",
86043
+ category: "value"
86044
+ },
86045
+ {
86046
+ text: "RING_HASH",
86047
+ description: "Consistent ring hash",
86048
+ category: "value"
86049
+ }
86050
+ ].filter((s) => s.text.toLowerCase().startsWith(lowerPartial));
86051
+ case "--port":
86052
+ return [
86053
+ {
86054
+ text: "80",
86055
+ description: "HTTP port",
86056
+ category: "value"
86057
+ },
86058
+ {
86059
+ text: "443",
86060
+ description: "HTTPS port",
86061
+ category: "value"
86062
+ },
86063
+ {
86064
+ text: "8080",
86065
+ description: "Alt HTTP port",
86066
+ category: "value"
86067
+ },
86068
+ {
86069
+ text: "8443",
86070
+ description: "Alt HTTPS port",
86071
+ category: "value"
86072
+ }
86073
+ ].filter((s) => s.text.startsWith(valuePartial));
86074
+ case "--health-check":
86075
+ return this.getResourceNameSuggestions(
86076
+ "healthcheck",
86077
+ valuePartial
86078
+ );
85390
86079
  default:
85391
86080
  return [];
85392
86081
  }
@@ -91579,8 +92268,8 @@ var Ink = class {
91579
92268
  }
91580
92269
  }
91581
92270
  async waitUntilExit() {
91582
- this.exitPromise ||= new Promise((resolve2, reject) => {
91583
- this.resolveExitPromise = resolve2;
92271
+ this.exitPromise ||= new Promise((resolve3, reject) => {
92272
+ this.resolveExitPromise = resolve3;
91584
92273
  this.rejectExitPromise = reject;
91585
92274
  });
91586
92275
  return this.exitPromise;
@@ -92342,7 +93031,7 @@ function calculateBackoffDelay(attempt, config) {
92342
93031
  return cappedDelay;
92343
93032
  }
92344
93033
  function sleep(ms) {
92345
- return new Promise((resolve2) => setTimeout(resolve2, ms));
93034
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
92346
93035
  }
92347
93036
  var APIClient = class {
92348
93037
  serverUrl;
@@ -95242,9 +95931,9 @@ async function detectWithAllDomainScan(resourceName, namespace, client) {
95242
95931
  }
95243
95932
  async function detectDependencies(resourceType, resourceName, namespace, client) {
95244
95933
  const startTime = Date.now();
95245
- const timeoutPromise = new Promise((resolve2) => {
95934
+ const timeoutPromise = new Promise((resolve3) => {
95246
95935
  setTimeout(() => {
95247
- resolve2({
95936
+ resolve3({
95248
95937
  found: false,
95249
95938
  references: [],
95250
95939
  searchedDomains: [],
@@ -95396,6 +96085,540 @@ function hasUnsubstitutedParams(path) {
95396
96085
  return /\{[^}]+\}/.test(path);
95397
96086
  }
95398
96087
 
96088
+ // src/repl/executor.ts
96089
+ var import_yaml4 = __toESM(require_dist(), 1);
96090
+ import { promises as fs4 } from "fs";
96091
+ import { resolve } from "path";
96092
+
96093
+ // src/repl/creation/flag-parser.ts
96094
+ init_creation_flags();
96095
+ function hasCreationFlagsInArgs(args, resourceType) {
96096
+ const flagDefs = getCreationFlags(resourceType);
96097
+ if (flagDefs.length === 0) return false;
96098
+ const flagNames = /* @__PURE__ */ new Set();
96099
+ for (const def of flagDefs) {
96100
+ flagNames.add(def.name);
96101
+ if (def.shortName) {
96102
+ flagNames.add(def.shortName);
96103
+ }
96104
+ }
96105
+ for (const arg of args) {
96106
+ if (!arg) continue;
96107
+ const flagPart = arg.includes("=") ? arg.split("=")[0] ?? arg : arg;
96108
+ if (flagNames.has(flagPart)) {
96109
+ return true;
96110
+ }
96111
+ }
96112
+ return false;
96113
+ }
96114
+ function hasFileFlag(args) {
96115
+ return args.some((arg) => arg === "--file" || arg.startsWith("--file="));
96116
+ }
96117
+ function getFilePath(args) {
96118
+ for (let i = 0; i < args.length; i++) {
96119
+ const arg = args[i];
96120
+ if (!arg) continue;
96121
+ if (arg === "--file" && i + 1 < args.length) {
96122
+ const nextArg = args[i + 1];
96123
+ return nextArg ?? null;
96124
+ }
96125
+ if (arg.startsWith("--file=")) {
96126
+ return arg.substring("--file=".length);
96127
+ }
96128
+ }
96129
+ return null;
96130
+ }
96131
+ function parseCreationFlags(args, resourceType) {
96132
+ const flagDefs = getCreationFlags(resourceType);
96133
+ const result = {
96134
+ values: /* @__PURE__ */ new Map(),
96135
+ errors: [],
96136
+ hasFlags: false
96137
+ };
96138
+ if (flagDefs.length === 0) {
96139
+ result.errors.push(
96140
+ `No creation flags defined for resource type: ${resourceType}`
96141
+ );
96142
+ return result;
96143
+ }
96144
+ const flagByName = /* @__PURE__ */ new Map();
96145
+ const flagByShortName = /* @__PURE__ */ new Map();
96146
+ for (const def of flagDefs) {
96147
+ flagByName.set(def.name, def);
96148
+ if (def.shortName) {
96149
+ flagByShortName.set(def.shortName, def);
96150
+ }
96151
+ }
96152
+ const usageCounts = /* @__PURE__ */ new Map();
96153
+ let i = 0;
96154
+ while (i < args.length) {
96155
+ const arg = args[i];
96156
+ if (!arg || !arg.startsWith("-")) {
96157
+ i++;
96158
+ continue;
96159
+ }
96160
+ let flagName;
96161
+ let inlineValue;
96162
+ if (arg.includes("=")) {
96163
+ const eqIndex = arg.indexOf("=");
96164
+ flagName = arg.substring(0, eqIndex);
96165
+ inlineValue = arg.substring(eqIndex + 1);
96166
+ } else {
96167
+ flagName = arg;
96168
+ }
96169
+ if (flagName === "--file") {
96170
+ i += inlineValue !== void 0 ? 1 : 2;
96171
+ continue;
96172
+ }
96173
+ if (flagName === "--namespace" || flagName === "-ns") {
96174
+ i += inlineValue !== void 0 ? 1 : 2;
96175
+ continue;
96176
+ }
96177
+ const def = flagByName.get(flagName) ?? flagByShortName.get(flagName);
96178
+ if (!def) {
96179
+ i++;
96180
+ continue;
96181
+ }
96182
+ result.hasFlags = true;
96183
+ const currentCount = usageCounts.get(def.name) ?? 0;
96184
+ usageCounts.set(def.name, currentCount + 1);
96185
+ if (def.isRepeatable && def.maxOccurrences) {
96186
+ if (currentCount + 1 > def.maxOccurrences) {
96187
+ result.errors.push(
96188
+ `Flag ${def.name} can only be used ${def.maxOccurrences} times`
96189
+ );
96190
+ i++;
96191
+ continue;
96192
+ }
96193
+ } else if (!def.isRepeatable && currentCount > 0) {
96194
+ result.errors.push(
96195
+ `Flag ${def.name} cannot be specified multiple times`
96196
+ );
96197
+ i++;
96198
+ continue;
96199
+ }
96200
+ if (!def.hasValue) {
96201
+ result.values.set(def.name, "true");
96202
+ i++;
96203
+ continue;
96204
+ }
96205
+ let value;
96206
+ if (inlineValue !== void 0) {
96207
+ value = inlineValue;
96208
+ i++;
96209
+ } else {
96210
+ const nextArg = args[i + 1];
96211
+ if (nextArg && !nextArg.startsWith("-")) {
96212
+ value = nextArg;
96213
+ i += 2;
96214
+ } else {
96215
+ result.errors.push(`Flag ${def.name} requires a value`);
96216
+ i++;
96217
+ continue;
96218
+ }
96219
+ }
96220
+ if (def.valueType === "enum" && def.enumValues) {
96221
+ if (!def.enumValues.includes(value)) {
96222
+ result.errors.push(
96223
+ `Invalid value '${value}' for ${def.name}. Allowed: ${def.enumValues.join(", ")}`
96224
+ );
96225
+ continue;
96226
+ }
96227
+ }
96228
+ if (def.valueType === "integer") {
96229
+ const num = parseInt(value, 10);
96230
+ if (isNaN(num)) {
96231
+ result.errors.push(
96232
+ `Invalid integer value '${value}' for ${def.name}`
96233
+ );
96234
+ continue;
96235
+ }
96236
+ }
96237
+ if (def.isRepeatable) {
96238
+ const existing = result.values.get(def.name);
96239
+ if (Array.isArray(existing)) {
96240
+ existing.push(value);
96241
+ } else {
96242
+ result.values.set(def.name, [value]);
96243
+ }
96244
+ } else {
96245
+ result.values.set(def.name, value);
96246
+ }
96247
+ }
96248
+ for (const def of flagDefs) {
96249
+ if (def.required && !result.values.has(def.name)) {
96250
+ if (result.hasFlags) {
96251
+ result.errors.push(`Required flag ${def.name} is missing`);
96252
+ }
96253
+ }
96254
+ }
96255
+ return result;
96256
+ }
96257
+ function getFlagValue(parsed, flagName) {
96258
+ const value = parsed.values.get(flagName);
96259
+ if (Array.isArray(value)) {
96260
+ return value[0];
96261
+ }
96262
+ return value;
96263
+ }
96264
+ function getFlagValues(parsed, flagName) {
96265
+ const value = parsed.values.get(flagName);
96266
+ if (Array.isArray(value)) {
96267
+ return value;
96268
+ }
96269
+ if (value !== void 0) {
96270
+ return [value];
96271
+ }
96272
+ return [];
96273
+ }
96274
+ function getFlagIntValue(parsed, flagName) {
96275
+ const value = getFlagValue(parsed, flagName);
96276
+ if (value !== void 0) {
96277
+ const num = parseInt(value, 10);
96278
+ return isNaN(num) ? void 0 : num;
96279
+ }
96280
+ return void 0;
96281
+ }
96282
+ function isFlagSet(parsed, flagName) {
96283
+ return parsed.values.has(flagName);
96284
+ }
96285
+
96286
+ // src/repl/creation/builders/healthcheck-builder.ts
96287
+ function buildHealthcheckRequest(flags, namespace) {
96288
+ const name = getFlagValue(flags, "--name");
96289
+ const type = getFlagValue(flags, "--type");
96290
+ const interval = getFlagIntValue(flags, "--interval");
96291
+ const timeout = getFlagIntValue(flags, "--timeout");
96292
+ const healthyThreshold = getFlagIntValue(flags, "--healthy-threshold");
96293
+ const unhealthyThreshold = getFlagIntValue(flags, "--unhealthy-threshold");
96294
+ const request = {
96295
+ metadata: {
96296
+ name: name || "",
96297
+ namespace
96298
+ },
96299
+ spec: {
96300
+ timeout: timeout || 5,
96301
+ interval: interval || 10,
96302
+ healthy_threshold: healthyThreshold || 2,
96303
+ unhealthy_threshold: unhealthyThreshold || 3
96304
+ }
96305
+ };
96306
+ switch (type) {
96307
+ case "http": {
96308
+ const path = getFlagValue(flags, "--path") || "/";
96309
+ const useOriginServerName = isFlagSet(
96310
+ flags,
96311
+ "--use-origin-server-name"
96312
+ );
96313
+ const useHttp2 = isFlagSet(flags, "--use-http2");
96314
+ const expectedStatus = getFlagValue(flags, "--expected-status");
96315
+ const hostHeader = getFlagValue(flags, "--host-header");
96316
+ request.spec.http_health_check = {
96317
+ path,
96318
+ use_origin_server_name: useOriginServerName,
96319
+ use_http2: useHttp2
96320
+ };
96321
+ if (expectedStatus) {
96322
+ request.spec.http_health_check.expected_status_codes = expectedStatus.split(",").map((s) => s.trim());
96323
+ }
96324
+ if (hostHeader) {
96325
+ request.spec.http_health_check.headers = {
96326
+ Host: hostHeader
96327
+ };
96328
+ }
96329
+ break;
96330
+ }
96331
+ case "tcp": {
96332
+ request.spec.tcp_health_check = {};
96333
+ break;
96334
+ }
96335
+ case "dns": {
96336
+ request.spec.dns_health_check = {};
96337
+ break;
96338
+ }
96339
+ case "udp-icmp": {
96340
+ break;
96341
+ }
96342
+ }
96343
+ return request;
96344
+ }
96345
+ function validateHealthcheckFlags(flags) {
96346
+ const errors = [];
96347
+ const name = getFlagValue(flags, "--name");
96348
+ if (!name) {
96349
+ errors.push("--name is required");
96350
+ } else if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name) && name.length > 1) {
96351
+ errors.push(
96352
+ "--name must contain only lowercase alphanumeric characters and hyphens"
96353
+ );
96354
+ }
96355
+ const type = getFlagValue(flags, "--type");
96356
+ if (!type) {
96357
+ errors.push("--type is required (http, tcp, dns, or udp-icmp)");
96358
+ }
96359
+ const interval = getFlagIntValue(flags, "--interval");
96360
+ if (interval === void 0) {
96361
+ errors.push("--interval is required");
96362
+ } else if (interval < 1 || interval > 600) {
96363
+ errors.push("--interval must be between 1 and 600 seconds");
96364
+ }
96365
+ const timeout = getFlagIntValue(flags, "--timeout");
96366
+ if (timeout === void 0) {
96367
+ errors.push("--timeout is required");
96368
+ } else if (timeout < 1 || timeout > 600) {
96369
+ errors.push("--timeout must be between 1 and 600 seconds");
96370
+ }
96371
+ const healthyThreshold = getFlagIntValue(flags, "--healthy-threshold");
96372
+ if (healthyThreshold === void 0) {
96373
+ errors.push("--healthy-threshold is required");
96374
+ } else if (healthyThreshold < 1 || healthyThreshold > 16) {
96375
+ errors.push("--healthy-threshold must be between 1 and 16");
96376
+ }
96377
+ const unhealthyThreshold = getFlagIntValue(flags, "--unhealthy-threshold");
96378
+ if (unhealthyThreshold === void 0) {
96379
+ errors.push("--unhealthy-threshold is required");
96380
+ } else if (unhealthyThreshold < 1 || unhealthyThreshold > 16) {
96381
+ errors.push("--unhealthy-threshold must be between 1 and 16");
96382
+ }
96383
+ if (type === "http") {
96384
+ const path = getFlagValue(flags, "--path");
96385
+ if (path && !path.startsWith("/")) {
96386
+ errors.push("--path must start with /");
96387
+ }
96388
+ }
96389
+ return {
96390
+ valid: errors.length === 0,
96391
+ errors
96392
+ };
96393
+ }
96394
+
96395
+ // src/repl/creation/builders/origin-pool-builder.ts
96396
+ function buildOriginPoolRequest(flags, namespace) {
96397
+ const name = getFlagValue(flags, "--name");
96398
+ const port = getFlagIntValue(flags, "--port");
96399
+ const algorithm = getFlagValue(flags, "--algorithm");
96400
+ const site = getFlagValue(flags, "--site");
96401
+ const originServers = [];
96402
+ const publicIps = getFlagValues(flags, "--public-ip");
96403
+ for (const ip of publicIps) {
96404
+ originServers.push({ public_ip: { ip } });
96405
+ }
96406
+ const publicNames = getFlagValues(flags, "--public-name");
96407
+ for (const dnsName of publicNames) {
96408
+ originServers.push({ public_name: { dns_name: dnsName } });
96409
+ }
96410
+ const privateIps = getFlagValues(flags, "--private-ip");
96411
+ for (const ip of privateIps) {
96412
+ const origin = {
96413
+ private_ip: { ip }
96414
+ };
96415
+ if (site) {
96416
+ origin.private_ip.site_locator = {
96417
+ site: { name: site, namespace: "system" }
96418
+ };
96419
+ }
96420
+ originServers.push(origin);
96421
+ }
96422
+ const privateNames = getFlagValues(flags, "--private-name");
96423
+ for (const dnsName of privateNames) {
96424
+ const origin = {
96425
+ private_name: { dns_name: dnsName }
96426
+ };
96427
+ if (site) {
96428
+ origin.private_name.site_locator = {
96429
+ site: { name: site, namespace: "system" }
96430
+ };
96431
+ }
96432
+ originServers.push(origin);
96433
+ }
96434
+ const k8sServices = getFlagValues(flags, "--k8s-service");
96435
+ for (const svc of k8sServices) {
96436
+ const origin = {
96437
+ k8s_service: { service_name: svc }
96438
+ };
96439
+ if (site) {
96440
+ origin.k8s_service.site_locator = {
96441
+ site: { name: site, namespace: "system" }
96442
+ };
96443
+ }
96444
+ originServers.push(origin);
96445
+ }
96446
+ const consulServices = getFlagValues(flags, "--consul-service");
96447
+ for (const svc of consulServices) {
96448
+ const origin = {
96449
+ consul_service: { service_name: svc }
96450
+ };
96451
+ if (site) {
96452
+ origin.consul_service.site_locator = {
96453
+ site: { name: site, namespace: "system" }
96454
+ };
96455
+ }
96456
+ originServers.push(origin);
96457
+ }
96458
+ const customEndpoints = getFlagValues(flags, "--custom-endpoint");
96459
+ for (const endpoint of customEndpoints) {
96460
+ originServers.push({
96461
+ custom_endpoint_object: {
96462
+ endpoint: { name: endpoint, namespace }
96463
+ }
96464
+ });
96465
+ }
96466
+ const vnPrivateIps = getFlagValues(flags, "--vn-private-ip");
96467
+ for (const ip of vnPrivateIps) {
96468
+ originServers.push({
96469
+ vn_private_ip: { ip }
96470
+ });
96471
+ }
96472
+ const vnPrivateNames = getFlagValues(flags, "--vn-private-name");
96473
+ for (const dnsName of vnPrivateNames) {
96474
+ originServers.push({
96475
+ vn_private_name: { dns_name: dnsName }
96476
+ });
96477
+ }
96478
+ const request = {
96479
+ metadata: {
96480
+ name: name || "",
96481
+ namespace
96482
+ },
96483
+ spec: {
96484
+ origin_servers: originServers
96485
+ }
96486
+ };
96487
+ if (port !== void 0) {
96488
+ request.spec.port = port;
96489
+ } else if (isFlagSet(flags, "--automatic-port")) {
96490
+ request.spec.automatic_port = {};
96491
+ } else if (isFlagSet(flags, "--lb-port")) {
96492
+ request.spec.lb_port = {};
96493
+ }
96494
+ if (algorithm) {
96495
+ request.spec.loadbalancer_algorithm = algorithm;
96496
+ }
96497
+ if (isFlagSet(flags, "--no-tls")) {
96498
+ request.spec.no_tls = {};
96499
+ } else if (isFlagSet(flags, "--use-tls")) {
96500
+ request.spec.use_tls = {
96501
+ use_host_header_as_sni: {},
96502
+ tls_config: {
96503
+ default_security: {}
96504
+ },
96505
+ skip_server_verification: {}
96506
+ };
96507
+ }
96508
+ const healthChecks = getFlagValues(flags, "--health-check");
96509
+ if (healthChecks.length > 0) {
96510
+ request.spec.healthcheck = healthChecks.map((hc) => ({
96511
+ name: hc,
96512
+ namespace
96513
+ }));
96514
+ }
96515
+ return request;
96516
+ }
96517
+ function validateOriginPoolFlags(flags) {
96518
+ const errors = [];
96519
+ const name = getFlagValue(flags, "--name");
96520
+ if (!name) {
96521
+ errors.push("--name is required");
96522
+ } else if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name) && name.length > 1) {
96523
+ errors.push(
96524
+ "--name must contain only lowercase alphanumeric characters and hyphens"
96525
+ );
96526
+ }
96527
+ const originFlagNames = [
96528
+ "--public-ip",
96529
+ "--public-name",
96530
+ "--private-ip",
96531
+ "--private-name",
96532
+ "--k8s-service",
96533
+ "--consul-service",
96534
+ "--custom-endpoint",
96535
+ "--vn-private-ip",
96536
+ "--vn-private-name",
96537
+ "--cbip-service"
96538
+ ];
96539
+ let hasOrigin = false;
96540
+ for (const flagName of originFlagNames) {
96541
+ if (getFlagValues(flags, flagName).length > 0) {
96542
+ hasOrigin = true;
96543
+ break;
96544
+ }
96545
+ }
96546
+ if (!hasOrigin) {
96547
+ errors.push(
96548
+ "At least one origin server is required (e.g., --public-ip, --public-name)"
96549
+ );
96550
+ }
96551
+ const port = getFlagIntValue(flags, "--port");
96552
+ if (port !== void 0 && (port < 1 || port > 65535)) {
96553
+ errors.push("--port must be between 1 and 65535");
96554
+ }
96555
+ const portOptions = [
96556
+ isFlagSet(flags, "--port") || port !== void 0,
96557
+ isFlagSet(flags, "--automatic-port"),
96558
+ isFlagSet(flags, "--lb-port")
96559
+ ].filter(Boolean).length;
96560
+ if (portOptions > 1) {
96561
+ errors.push(
96562
+ "--port, --automatic-port, and --lb-port are mutually exclusive"
96563
+ );
96564
+ }
96565
+ if (isFlagSet(flags, "--no-tls") && isFlagSet(flags, "--use-tls")) {
96566
+ errors.push("--no-tls and --use-tls are mutually exclusive");
96567
+ }
96568
+ const privateIps = getFlagValues(flags, "--private-ip");
96569
+ const privateNames = getFlagValues(flags, "--private-name");
96570
+ const k8sServices = getFlagValues(flags, "--k8s-service");
96571
+ const consulServices = getFlagValues(flags, "--consul-service");
96572
+ if ((privateIps.length > 0 || privateNames.length > 0 || k8sServices.length > 0 || consulServices.length > 0) && !getFlagValue(flags, "--site")) {
96573
+ errors.push(
96574
+ "--site is required when using private origins (--private-ip, --private-name, --k8s-service, --consul-service)"
96575
+ );
96576
+ }
96577
+ const healthChecks = getFlagValues(flags, "--health-check");
96578
+ if (healthChecks.length > 4) {
96579
+ errors.push("Maximum of 4 health checks allowed");
96580
+ }
96581
+ return {
96582
+ valid: errors.length === 0,
96583
+ errors
96584
+ };
96585
+ }
96586
+
96587
+ // src/repl/creation/builders/index.ts
96588
+ var BUILDERS_REGISTRY = {
96589
+ healthcheck: {
96590
+ build: (flags, namespace) => buildHealthcheckRequest(flags, namespace),
96591
+ validate: validateHealthcheckFlags
96592
+ },
96593
+ origin_pool: {
96594
+ build: (flags, namespace) => buildOriginPoolRequest(flags, namespace),
96595
+ validate: validateOriginPoolFlags
96596
+ }
96597
+ };
96598
+ function getResourceBuilder(resourceType) {
96599
+ return BUILDERS_REGISTRY[resourceType];
96600
+ }
96601
+ function hasResourceBuilder(resourceType) {
96602
+ return resourceType in BUILDERS_REGISTRY;
96603
+ }
96604
+ function buildResource(resourceType, flags, namespace) {
96605
+ const builder = getResourceBuilder(resourceType);
96606
+ if (!builder) {
96607
+ return null;
96608
+ }
96609
+ return builder.build(flags, namespace);
96610
+ }
96611
+ function validateResourceFlags(resourceType, flags) {
96612
+ const builder = getResourceBuilder(resourceType);
96613
+ if (!builder) {
96614
+ return {
96615
+ valid: false,
96616
+ errors: [`No builder found for resource type: ${resourceType}`]
96617
+ };
96618
+ }
96619
+ return builder.validate(flags);
96620
+ }
96621
+
95399
96622
  // src/repl/executor.ts
95400
96623
  var WRITE_OPERATIONS = /* @__PURE__ */ new Set([
95401
96624
  "create",
@@ -96373,15 +97596,153 @@ async function executeAPICommand(session, ctx, cmd) {
96373
97596
  case "create":
96374
97597
  case "replace":
96375
97598
  case "apply": {
96376
- return {
96377
- output: [
97599
+ let requestBody = null;
97600
+ if (hasFileFlag(args)) {
97601
+ const filePath = getFilePath(args);
97602
+ if (!filePath) {
97603
+ return {
97604
+ output: ["Error: --file requires a file path"],
97605
+ shouldExit: false,
97606
+ shouldClear: false,
97607
+ contextChanged: false
97608
+ };
97609
+ }
97610
+ try {
97611
+ const absolutePath = resolve(filePath);
97612
+ const fileContent = await fs4.readFile(
97613
+ absolutePath,
97614
+ "utf-8"
97615
+ );
97616
+ requestBody = import_yaml4.default.parse(fileContent);
97617
+ if (!requestBody || typeof requestBody !== "object") {
97618
+ return {
97619
+ output: [
97620
+ "Error: File must contain a valid YAML/JSON object"
97621
+ ],
97622
+ shouldExit: false,
97623
+ shouldClear: false,
97624
+ contextChanged: false
97625
+ };
97626
+ }
97627
+ } catch (error) {
97628
+ const errMsg = error instanceof Error ? error.message : String(error);
97629
+ return {
97630
+ output: [`Error reading file: ${errMsg}`],
97631
+ shouldExit: false,
97632
+ shouldClear: false,
97633
+ contextChanged: false
97634
+ };
97635
+ }
97636
+ } else if (effectiveResourceType && hasResourceBuilder(effectiveResourceType) && hasCreationFlagsInArgs(args, effectiveResourceType)) {
97637
+ const parsed = parseCreationFlags(
97638
+ args,
97639
+ effectiveResourceType
97640
+ );
97641
+ if (parsed.errors.length > 0) {
97642
+ return {
97643
+ output: [
97644
+ "Error parsing creation flags:",
97645
+ ...parsed.errors.map((e) => ` - ${e}`)
97646
+ ],
97647
+ shouldExit: false,
97648
+ shouldClear: false,
97649
+ contextChanged: false
97650
+ };
97651
+ }
97652
+ const validation = validateResourceFlags(
97653
+ effectiveResourceType,
97654
+ parsed
97655
+ );
97656
+ if (!validation.valid) {
97657
+ return {
97658
+ output: [
97659
+ "Validation errors:",
97660
+ ...validation.errors.map((e) => ` - ${e}`)
97661
+ ],
97662
+ shouldExit: false,
97663
+ shouldClear: false,
97664
+ contextChanged: false
97665
+ };
97666
+ }
97667
+ requestBody = buildResource(
97668
+ effectiveResourceType,
97669
+ parsed,
97670
+ effectiveNamespace
97671
+ );
97672
+ } else {
97673
+ const supportsFlagCreation = effectiveResourceType && hasResourceBuilder(effectiveResourceType);
97674
+ const hints = [
96378
97675
  `Action '${action}' requires a resource specification.`,
96379
- "Use --file <path> to provide resource YAML/JSON."
96380
- ],
96381
- shouldExit: false,
96382
- shouldClear: false,
96383
- contextChanged: false
96384
- };
97676
+ "",
97677
+ "Options:",
97678
+ " 1. Use --file <path> to provide resource YAML/JSON"
97679
+ ];
97680
+ if (supportsFlagCreation) {
97681
+ hints.push(
97682
+ ` 2. Use creation flags (e.g., --name, --type, etc.)`,
97683
+ "",
97684
+ `Example with flags:`,
97685
+ ` create ${effectiveResourceType} --name my-resource ...`
97686
+ );
97687
+ }
97688
+ return {
97689
+ output: hints,
97690
+ shouldExit: false,
97691
+ shouldClear: false,
97692
+ contextChanged: false
97693
+ };
97694
+ }
97695
+ if (!requestBody) {
97696
+ return {
97697
+ output: ["Error: Failed to build request body"],
97698
+ shouldExit: false,
97699
+ shouldClear: false,
97700
+ contextChanged: false
97701
+ };
97702
+ }
97703
+ if (action === "create") {
97704
+ const response = await client.post(apiPath, requestBody);
97705
+ result = response.data ?? {
97706
+ message: `Created ${canonicalDomain}`
97707
+ };
97708
+ } else if (action === "replace") {
97709
+ const resourceName = requestBody.metadata?.name ?? name;
97710
+ if (resourceName && !usedOperationPath) {
97711
+ apiPath += `/${resourceName}`;
97712
+ }
97713
+ const response = await client.put(apiPath, requestBody);
97714
+ result = response.data ?? {
97715
+ message: `Replaced ${canonicalDomain}`
97716
+ };
97717
+ } else {
97718
+ try {
97719
+ const response = await client.post(
97720
+ apiPath,
97721
+ requestBody
97722
+ );
97723
+ result = response.data ?? {
97724
+ message: `Applied ${canonicalDomain}`
97725
+ };
97726
+ } catch (postError) {
97727
+ if (postError instanceof APIError && postError.statusCode === 409) {
97728
+ const resourceName = requestBody.metadata?.name ?? name;
97729
+ let putPath = apiPath;
97730
+ if (resourceName && !usedOperationPath) {
97731
+ putPath += `/${resourceName}`;
97732
+ }
97733
+ const response = await client.put(
97734
+ putPath,
97735
+ requestBody
97736
+ );
97737
+ result = response.data ?? {
97738
+ message: `Updated ${canonicalDomain}`
97739
+ };
97740
+ } else {
97741
+ throw postError;
97742
+ }
97743
+ }
97744
+ }
97745
+ break;
96385
97746
  }
96386
97747
  case "status": {
96387
97748
  if (!name) {
@@ -96612,11 +97973,11 @@ init_terminal2();
96612
97973
 
96613
97974
  // src/debug/logger.ts
96614
97975
  import { appendFileSync, writeFileSync as writeFileSync2 } from "fs";
96615
- import { resolve } from "path";
97976
+ import { resolve as resolve2 } from "path";
96616
97977
  var DEBUG_ENABLED = process.env.XCSH_DEBUG === "1" || process.env.DEBUG === "xcsh" || process.env.DEBUG === "*";
96617
97978
  var DEBUG_FILE = process.env.XCSH_DEBUG_FILE || "./xcsh-debug.log";
96618
97979
  if (DEBUG_ENABLED) {
96619
- const logPath = resolve(DEBUG_FILE);
97980
+ const logPath = resolve2(DEBUG_FILE);
96620
97981
  try {
96621
97982
  writeFileSync2(
96622
97983
  logPath,