caplets 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
3
  import process$1, { stdin, stdout } from "node:process";
4
- import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
6
6
  import { dirname, join } from "node:path";
7
7
  import { PassThrough } from "node:stream";
@@ -6494,7 +6494,7 @@ function initializeContext(params) {
6494
6494
  external: params?.external ?? void 0
6495
6495
  };
6496
6496
  }
6497
- function process$2(schema, ctx, _params = {
6497
+ function process$3(schema, ctx, _params = {
6498
6498
  path: [],
6499
6499
  schemaPath: []
6500
6500
  }) {
@@ -6531,7 +6531,7 @@ function process$2(schema, ctx, _params = {
6531
6531
  const parent = schema._zod.parent;
6532
6532
  if (parent) {
6533
6533
  if (!result.ref) result.ref = parent;
6534
- process$2(parent, ctx, params);
6534
+ process$3(parent, ctx, params);
6535
6535
  ctx.seen.get(parent).isParent = true;
6536
6536
  }
6537
6537
  }
@@ -6751,7 +6751,7 @@ const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
6751
6751
  ...params,
6752
6752
  processors
6753
6753
  });
6754
- process$2(schema, ctx);
6754
+ process$3(schema, ctx);
6755
6755
  extractDefs(ctx, schema);
6756
6756
  return finalize(ctx, schema);
6757
6757
  };
@@ -6763,7 +6763,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
6763
6763
  io,
6764
6764
  processors
6765
6765
  });
6766
- process$2(schema, ctx);
6766
+ process$3(schema, ctx);
6767
6767
  extractDefs(ctx, schema);
6768
6768
  return finalize(ctx, schema);
6769
6769
  };
@@ -6929,7 +6929,7 @@ const arrayProcessor = (schema, ctx, _json, params) => {
6929
6929
  if (typeof minimum === "number") json.minItems = minimum;
6930
6930
  if (typeof maximum === "number") json.maxItems = maximum;
6931
6931
  json.type = "array";
6932
- json.items = process$2(def.element, ctx, {
6932
+ json.items = process$3(def.element, ctx, {
6933
6933
  ...params,
6934
6934
  path: [...params.path, "items"]
6935
6935
  });
@@ -6940,7 +6940,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
6940
6940
  json.type = "object";
6941
6941
  json.properties = {};
6942
6942
  const shape = def.shape;
6943
- for (const key in shape) json.properties[key] = process$2(shape[key], ctx, {
6943
+ for (const key in shape) json.properties[key] = process$3(shape[key], ctx, {
6944
6944
  ...params,
6945
6945
  path: [
6946
6946
  ...params.path,
@@ -6958,7 +6958,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
6958
6958
  if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
6959
6959
  else if (!def.catchall) {
6960
6960
  if (ctx.io === "output") json.additionalProperties = false;
6961
- } else if (def.catchall) json.additionalProperties = process$2(def.catchall, ctx, {
6961
+ } else if (def.catchall) json.additionalProperties = process$3(def.catchall, ctx, {
6962
6962
  ...params,
6963
6963
  path: [...params.path, "additionalProperties"]
6964
6964
  });
@@ -6966,7 +6966,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
6966
6966
  const unionProcessor = (schema, ctx, json, params) => {
6967
6967
  const def = schema._zod.def;
6968
6968
  const isExclusive = def.inclusive === false;
6969
- const options = def.options.map((x, i) => process$2(x, ctx, {
6969
+ const options = def.options.map((x, i) => process$3(x, ctx, {
6970
6970
  ...params,
6971
6971
  path: [
6972
6972
  ...params.path,
@@ -6979,7 +6979,7 @@ const unionProcessor = (schema, ctx, json, params) => {
6979
6979
  };
6980
6980
  const intersectionProcessor = (schema, ctx, json, params) => {
6981
6981
  const def = schema._zod.def;
6982
- const a = process$2(def.left, ctx, {
6982
+ const a = process$3(def.left, ctx, {
6983
6983
  ...params,
6984
6984
  path: [
6985
6985
  ...params.path,
@@ -6987,7 +6987,7 @@ const intersectionProcessor = (schema, ctx, json, params) => {
6987
6987
  0
6988
6988
  ]
6989
6989
  });
6990
- const b = process$2(def.right, ctx, {
6990
+ const b = process$3(def.right, ctx, {
6991
6991
  ...params,
6992
6992
  path: [
6993
6993
  ...params.path,
@@ -7004,7 +7004,7 @@ const tupleProcessor = (schema, ctx, _json, params) => {
7004
7004
  json.type = "array";
7005
7005
  const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
7006
7006
  const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
7007
- const prefixItems = def.items.map((x, i) => process$2(x, ctx, {
7007
+ const prefixItems = def.items.map((x, i) => process$3(x, ctx, {
7008
7008
  ...params,
7009
7009
  path: [
7010
7010
  ...params.path,
@@ -7012,7 +7012,7 @@ const tupleProcessor = (schema, ctx, _json, params) => {
7012
7012
  i
7013
7013
  ]
7014
7014
  }));
7015
- const rest = def.rest ? process$2(def.rest, ctx, {
7015
+ const rest = def.rest ? process$3(def.rest, ctx, {
7016
7016
  ...params,
7017
7017
  path: [
7018
7018
  ...params.path,
@@ -7043,7 +7043,7 @@ const recordProcessor = (schema, ctx, _json, params) => {
7043
7043
  const keyType = def.keyType;
7044
7044
  const patterns = keyType._zod.bag?.patterns;
7045
7045
  if (def.mode === "loose" && patterns && patterns.size > 0) {
7046
- const valueSchema = process$2(def.valueType, ctx, {
7046
+ const valueSchema = process$3(def.valueType, ctx, {
7047
7047
  ...params,
7048
7048
  path: [
7049
7049
  ...params.path,
@@ -7054,11 +7054,11 @@ const recordProcessor = (schema, ctx, _json, params) => {
7054
7054
  json.patternProperties = {};
7055
7055
  for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
7056
7056
  } else {
7057
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$2(def.keyType, ctx, {
7057
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$3(def.keyType, ctx, {
7058
7058
  ...params,
7059
7059
  path: [...params.path, "propertyNames"]
7060
7060
  });
7061
- json.additionalProperties = process$2(def.valueType, ctx, {
7061
+ json.additionalProperties = process$3(def.valueType, ctx, {
7062
7062
  ...params,
7063
7063
  path: [...params.path, "additionalProperties"]
7064
7064
  });
@@ -7071,7 +7071,7 @@ const recordProcessor = (schema, ctx, _json, params) => {
7071
7071
  };
7072
7072
  const nullableProcessor = (schema, ctx, json, params) => {
7073
7073
  const def = schema._zod.def;
7074
- const inner = process$2(def.innerType, ctx, params);
7074
+ const inner = process$3(def.innerType, ctx, params);
7075
7075
  const seen = ctx.seen.get(schema);
7076
7076
  if (ctx.target === "openapi-3.0") {
7077
7077
  seen.ref = def.innerType;
@@ -7080,27 +7080,27 @@ const nullableProcessor = (schema, ctx, json, params) => {
7080
7080
  };
7081
7081
  const nonoptionalProcessor = (schema, ctx, _json, params) => {
7082
7082
  const def = schema._zod.def;
7083
- process$2(def.innerType, ctx, params);
7083
+ process$3(def.innerType, ctx, params);
7084
7084
  const seen = ctx.seen.get(schema);
7085
7085
  seen.ref = def.innerType;
7086
7086
  };
7087
7087
  const defaultProcessor = (schema, ctx, json, params) => {
7088
7088
  const def = schema._zod.def;
7089
- process$2(def.innerType, ctx, params);
7089
+ process$3(def.innerType, ctx, params);
7090
7090
  const seen = ctx.seen.get(schema);
7091
7091
  seen.ref = def.innerType;
7092
7092
  json.default = JSON.parse(JSON.stringify(def.defaultValue));
7093
7093
  };
7094
7094
  const prefaultProcessor = (schema, ctx, json, params) => {
7095
7095
  const def = schema._zod.def;
7096
- process$2(def.innerType, ctx, params);
7096
+ process$3(def.innerType, ctx, params);
7097
7097
  const seen = ctx.seen.get(schema);
7098
7098
  seen.ref = def.innerType;
7099
7099
  if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
7100
7100
  };
7101
7101
  const catchProcessor = (schema, ctx, json, params) => {
7102
7102
  const def = schema._zod.def;
7103
- process$2(def.innerType, ctx, params);
7103
+ process$3(def.innerType, ctx, params);
7104
7104
  const seen = ctx.seen.get(schema);
7105
7105
  seen.ref = def.innerType;
7106
7106
  let catchValue;
@@ -7115,32 +7115,32 @@ const pipeProcessor = (schema, ctx, _json, params) => {
7115
7115
  const def = schema._zod.def;
7116
7116
  const inIsTransform = def.in._zod.traits.has("$ZodTransform");
7117
7117
  const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
7118
- process$2(innerType, ctx, params);
7118
+ process$3(innerType, ctx, params);
7119
7119
  const seen = ctx.seen.get(schema);
7120
7120
  seen.ref = innerType;
7121
7121
  };
7122
7122
  const readonlyProcessor = (schema, ctx, json, params) => {
7123
7123
  const def = schema._zod.def;
7124
- process$2(def.innerType, ctx, params);
7124
+ process$3(def.innerType, ctx, params);
7125
7125
  const seen = ctx.seen.get(schema);
7126
7126
  seen.ref = def.innerType;
7127
7127
  json.readOnly = true;
7128
7128
  };
7129
7129
  const promiseProcessor = (schema, ctx, _json, params) => {
7130
7130
  const def = schema._zod.def;
7131
- process$2(def.innerType, ctx, params);
7131
+ process$3(def.innerType, ctx, params);
7132
7132
  const seen = ctx.seen.get(schema);
7133
7133
  seen.ref = def.innerType;
7134
7134
  };
7135
7135
  const optionalProcessor = (schema, ctx, _json, params) => {
7136
7136
  const def = schema._zod.def;
7137
- process$2(def.innerType, ctx, params);
7137
+ process$3(def.innerType, ctx, params);
7138
7138
  const seen = ctx.seen.get(schema);
7139
7139
  seen.ref = def.innerType;
7140
7140
  };
7141
7141
  const lazyProcessor = (schema, ctx, _json, params) => {
7142
7142
  const innerType = schema._zod.innerType;
7143
- process$2(innerType, ctx, params);
7143
+ process$3(innerType, ctx, params);
7144
7144
  const seen = ctx.seen.get(schema);
7145
7145
  seen.ref = innerType;
7146
7146
  };
@@ -7195,7 +7195,7 @@ function toJSONSchema(input, params) {
7195
7195
  const defs = {};
7196
7196
  for (const entry of registry._idmap.entries()) {
7197
7197
  const [_, schema] = entry;
7198
- process$2(schema, ctx);
7198
+ process$3(schema, ctx);
7199
7199
  }
7200
7200
  const schemas = {};
7201
7201
  ctx.external = {
@@ -7215,7 +7215,7 @@ function toJSONSchema(input, params) {
7215
7215
  ...params,
7216
7216
  processors: allProcessors
7217
7217
  });
7218
- process$2(input, ctx);
7218
+ process$3(input, ctx);
7219
7219
  extractDefs(ctx, input);
7220
7220
  return finalize(ctx, input);
7221
7221
  }
@@ -19847,7 +19847,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
19847
19847
  } };
19848
19848
  //#endregion
19849
19849
  //#region package.json
19850
- var version = "0.1.0";
19850
+ var version = "0.2.1";
19851
19851
  //#endregion
19852
19852
  //#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
19853
19853
  /**
@@ -20001,6 +20001,7 @@ const FORBIDDEN_HEADERS = new Set([
20001
20001
  ]);
20002
20002
  join(homedir(), ".caplets", "config.json");
20003
20003
  join(homedir(), ".caplets", "auth");
20004
+ const PROJECT_CONFIG_FILE = join(".caplets", "config.json");
20004
20005
  const remoteAuthSchema = discriminatedUnion("type", [
20005
20006
  object({ type: literal("none") }).strict(),
20006
20007
  object({
@@ -20021,37 +20022,36 @@ const remoteAuthSchema = discriminatedUnion("type", [
20021
20022
  scopes: array(string().min(1)).optional(),
20022
20023
  redirectUri: string().url().optional()
20023
20024
  }).strict()
20024
- ]);
20025
+ ]).describe("Authentication settings for a remote MCP server.");
20025
20026
  const serverSchema = object({
20026
- name: string().trim().min(1).max(80),
20027
- description: string().refine((value) => value.trim().length >= 10, "description must contain at least 10 non-whitespace characters").refine((value) => value.length <= 1500, "description must be at most 1500 characters"),
20027
+ name: string().trim().min(1).max(80).describe("Human-readable server display name."),
20028
+ description: string().describe("Capability description shown to agents before downstream tools are disclosed.").refine((value) => value.trim().length >= 10, "description must contain at least 10 non-whitespace characters").refine((value) => value.length <= 1500, "description must be at most 1500 characters"),
20028
20029
  transport: _enum([
20029
20030
  "stdio",
20030
20031
  "http",
20031
20032
  "sse"
20032
- ]).optional(),
20033
- command: string().min(1).optional(),
20034
- args: array(string()).optional(),
20035
- env: record(string(), string()).optional(),
20036
- cwd: string().min(1).optional(),
20037
- url: string().url().optional(),
20033
+ ]).optional().describe("Downstream MCP transport. Defaults to stdio when command is present."),
20034
+ command: string().min(1).optional().describe("Executable command for stdio servers."),
20035
+ args: array(string()).optional().describe("Arguments passed to the stdio command."),
20036
+ env: record(string(), string()).optional().describe("Environment variables for stdio servers. Supports ${VAR} and $env:VAR."),
20037
+ cwd: string().min(1).optional().describe("Working directory for stdio servers."),
20038
+ url: string().url().optional().describe("Remote MCP server URL for http or sse transport."),
20038
20039
  auth: remoteAuthSchema.optional(),
20039
- startupTimeoutMs: number$1().int().positive().default(1e4),
20040
- callTimeoutMs: number$1().int().positive().default(6e4),
20041
- toolCacheTtlMs: number$1().int().nonnegative().default(3e4),
20042
- disabled: boolean().default(false)
20040
+ startupTimeoutMs: number$1().int().positive().default(1e4).describe("Timeout in milliseconds for starting or checking a downstream server."),
20041
+ callTimeoutMs: number$1().int().positive().default(6e4).describe("Timeout in milliseconds for downstream tool calls."),
20042
+ toolCacheTtlMs: number$1().int().nonnegative().default(3e4).describe("Milliseconds downstream tool metadata stays fresh. Set 0 to refresh every time."),
20043
+ disabled: boolean().default(false).describe("When true, omit this server from Caplets discovery and do not start it.")
20043
20044
  }).strict();
20044
- const rawConfigSchema = object({
20045
- version: literal(1).default(1),
20046
- caplets: object({
20047
- defaultSearchLimit: number$1().int().positive().default(20),
20048
- maxSearchLimit: number$1().int().positive().max(50).default(50)
20049
- }).strict().prefault({}),
20050
- mcpServers: record(string(), serverSchema)
20045
+ const configFileSchema = object({
20046
+ $schema: string().url().optional().describe("Optional JSON Schema URL for editor validation."),
20047
+ version: literal(1).default(1).describe("Caplets config schema version."),
20048
+ defaultSearchLimit: number$1().int().positive().default(20).describe("Default maximum number of same-server search results."),
20049
+ maxSearchLimit: number$1().int().positive().max(50).default(50).describe("Maximum accepted search_tools limit."),
20050
+ mcpServers: record(string().regex(SERVER_ID_PATTERN), serverSchema).describe("Downstream MCP servers keyed by stable server ID.")
20051
20051
  }).strict().superRefine((config, ctx) => {
20052
- if (config.caplets.defaultSearchLimit > config.caplets.maxSearchLimit) ctx.addIssue({
20052
+ if (config.defaultSearchLimit > config.maxSearchLimit) ctx.addIssue({
20053
20053
  code: "custom",
20054
- path: ["caplets", "defaultSearchLimit"],
20054
+ path: ["defaultSearchLimit"],
20055
20055
  message: "defaultSearchLimit must be <= maxSearchLimit"
20056
20056
  });
20057
20057
  for (const [server, raw] of Object.entries(config.mcpServers)) {
@@ -20112,17 +20112,45 @@ const rawConfigSchema = object({
20112
20112
  function resolveConfigPath(path) {
20113
20113
  return path ?? join(homedir(), ".caplets", "config.json");
20114
20114
  }
20115
- function loadConfig(path = resolveConfigPath()) {
20116
- if (!existsSync(path)) throw new CapletsError("CONFIG_NOT_FOUND", `Caplets config not found at ${path}`);
20115
+ function resolveProjectConfigPath(cwd = process.cwd()) {
20116
+ return join(cwd, PROJECT_CONFIG_FILE);
20117
+ }
20118
+ function loadConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
20119
+ const hasUserConfig = existsSync(path);
20120
+ const hasProjectConfig = existsSync(projectPath);
20121
+ if (!hasUserConfig && !hasProjectConfig) throw new CapletsError("CONFIG_NOT_FOUND", `Caplets config not found at ${path} or ${projectPath}`);
20117
20122
  try {
20118
- return parseConfig(JSON.parse(readFileSync(path, "utf8")));
20123
+ return parseConfig(mergeConfigInputs(hasProjectConfig ? readConfigFile(projectPath) : void 0, hasUserConfig ? readConfigFile(path) : void 0));
20119
20124
  } catch (error) {
20120
20125
  if (error instanceof CapletsError) throw error;
20121
20126
  throw new CapletsError("CONFIG_INVALID", "Caplets config is not valid JSON", redactSecrets(error));
20122
20127
  }
20123
20128
  }
20129
+ function readConfigFile(path) {
20130
+ try {
20131
+ return JSON.parse(readFileSync(path, "utf8"));
20132
+ } catch (error) {
20133
+ throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is not valid JSON`, redactSecrets(error));
20134
+ }
20135
+ }
20136
+ function mergeConfigInputs(projectConfig, userConfig) {
20137
+ if (projectConfig === void 0) return userConfig;
20138
+ if (userConfig === void 0) return projectConfig;
20139
+ if (!isPlainConfigObject(projectConfig) || !isPlainConfigObject(userConfig)) return userConfig;
20140
+ return {
20141
+ ...userConfig,
20142
+ ...projectConfig,
20143
+ mcpServers: {
20144
+ ...userConfig.mcpServers,
20145
+ ...projectConfig.mcpServers
20146
+ }
20147
+ };
20148
+ }
20149
+ function isPlainConfigObject(value) {
20150
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
20151
+ }
20124
20152
  function parseConfig(input) {
20125
- const parsed = rawConfigSchema.safeParse(interpolateServer(input));
20153
+ const parsed = configFileSchema.safeParse(interpolateServer(input));
20126
20154
  if (!parsed.success) throw new CapletsError("CONFIG_INVALID", "Caplets config is invalid", parsed.error.issues);
20127
20155
  const servers = {};
20128
20156
  for (const [server, raw] of Object.entries(parsed.data.mcpServers)) {
@@ -20135,7 +20163,10 @@ function parseConfig(input) {
20135
20163
  }
20136
20164
  return {
20137
20165
  version: parsed.data.version,
20138
- caplets: parsed.data.caplets,
20166
+ options: {
20167
+ defaultSearchLimit: parsed.data.defaultSearchLimit,
20168
+ maxSearchLimit: parsed.data.maxSearchLimit
20169
+ },
20139
20170
  mcpServers: servers
20140
20171
  };
20141
20172
  }
@@ -20820,7 +20851,7 @@ var Client = class extends Protocol {
20820
20851
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20821
20852
  module.exports = isexe;
20822
20853
  isexe.sync = sync;
20823
- var fs$2 = __require("fs");
20854
+ var fs$3 = __require("fs");
20824
20855
  function checkPathExt(path, options) {
20825
20856
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
20826
20857
  if (!pathext) return true;
@@ -20837,12 +20868,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20837
20868
  return checkPathExt(path, options);
20838
20869
  }
20839
20870
  function isexe(path, options, cb) {
20840
- fs$2.stat(path, function(er, stat) {
20871
+ fs$3.stat(path, function(er, stat) {
20841
20872
  cb(er, er ? false : checkStat(stat, path, options));
20842
20873
  });
20843
20874
  }
20844
20875
  function sync(path, options) {
20845
- return checkStat(fs$2.statSync(path), path, options);
20876
+ return checkStat(fs$3.statSync(path), path, options);
20846
20877
  }
20847
20878
  }));
20848
20879
  //#endregion
@@ -20850,14 +20881,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20850
20881
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20851
20882
  module.exports = isexe;
20852
20883
  isexe.sync = sync;
20853
- var fs$1 = __require("fs");
20884
+ var fs$2 = __require("fs");
20854
20885
  function isexe(path, options, cb) {
20855
- fs$1.stat(path, function(er, stat) {
20886
+ fs$2.stat(path, function(er, stat) {
20856
20887
  cb(er, er ? false : checkStat(stat, options));
20857
20888
  });
20858
20889
  }
20859
20890
  function sync(path, options) {
20860
- return checkStat(fs$1.statSync(path), options);
20891
+ return checkStat(fs$2.statSync(path), options);
20861
20892
  }
20862
20893
  function checkStat(stat, options) {
20863
20894
  return stat.isFile() && checkMode(stat, options);
@@ -20921,7 +20952,7 @@ var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20921
20952
  //#region node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
20922
20953
  var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20923
20954
  const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
20924
- const path$2 = __require("path");
20955
+ const path$3 = __require("path");
20925
20956
  const COLON = isWindows ? ";" : ":";
20926
20957
  const isexe = require_isexe();
20927
20958
  const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -20951,7 +20982,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20951
20982
  if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
20952
20983
  const ppRaw = pathEnv[i];
20953
20984
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
20954
- const pCmd = path$2.join(pathPart, cmd);
20985
+ const pCmd = path$3.join(pathPart, cmd);
20955
20986
  resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
20956
20987
  });
20957
20988
  const subStep = (p, i, ii) => new Promise((resolve, reject) => {
@@ -20972,7 +21003,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
20972
21003
  for (let i = 0; i < pathEnv.length; i++) {
20973
21004
  const ppRaw = pathEnv[i];
20974
21005
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
20975
- const pCmd = path$2.join(pathPart, cmd);
21006
+ const pCmd = path$3.join(pathPart, cmd);
20976
21007
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
20977
21008
  for (let j = 0; j < pathExt.length; j++) {
20978
21009
  const cur = p + pathExt[j];
@@ -21003,7 +21034,7 @@ var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21003
21034
  //#endregion
21004
21035
  //#region node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
21005
21036
  var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21006
- const path$1 = __require("path");
21037
+ const path$2 = __require("path");
21007
21038
  const which = require_which();
21008
21039
  const getPathKey = require_path_key();
21009
21040
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -21018,12 +21049,12 @@ var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) =>
21018
21049
  try {
21019
21050
  resolved = which.sync(parsed.command, {
21020
21051
  path: env[getPathKey({ env })],
21021
- pathExt: withoutPathExt ? path$1.delimiter : void 0
21052
+ pathExt: withoutPathExt ? path$2.delimiter : void 0
21022
21053
  });
21023
21054
  } catch (e) {} finally {
21024
21055
  if (shouldSwitchCwd) process.chdir(cwd);
21025
21056
  }
21026
- if (resolved) resolved = path$1.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
21057
+ if (resolved) resolved = path$2.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
21027
21058
  return resolved;
21028
21059
  }
21029
21060
  function resolveCommand(parsed) {
@@ -21072,16 +21103,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
21072
21103
  //#endregion
21073
21104
  //#region node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
21074
21105
  var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21075
- const fs = __require("fs");
21106
+ const fs$1 = __require("fs");
21076
21107
  const shebangCommand = require_shebang_command();
21077
21108
  function readShebang(command) {
21078
21109
  const size = 150;
21079
21110
  const buffer = Buffer.alloc(size);
21080
21111
  let fd;
21081
21112
  try {
21082
- fd = fs.openSync(command, "r");
21083
- fs.readSync(fd, buffer, 0, size, 0);
21084
- fs.closeSync(fd);
21113
+ fd = fs$1.openSync(command, "r");
21114
+ fs$1.readSync(fd, buffer, 0, size, 0);
21115
+ fs$1.closeSync(fd);
21085
21116
  } catch (e) {}
21086
21117
  return shebangCommand(buffer.toString());
21087
21118
  }
@@ -21090,7 +21121,7 @@ var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21090
21121
  //#endregion
21091
21122
  //#region node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
21092
21123
  var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21093
- const path = __require("path");
21124
+ const path$1 = __require("path");
21094
21125
  const resolveCommand = require_resolveCommand();
21095
21126
  const escape = require_escape();
21096
21127
  const readShebang = require_readShebang();
@@ -21113,7 +21144,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21113
21144
  const needsShell = !isExecutableRegExp.test(commandFile);
21114
21145
  if (parsed.options.forceShell || needsShell) {
21115
21146
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
21116
- parsed.command = path.normalize(parsed.command);
21147
+ parsed.command = path$1.normalize(parsed.command);
21117
21148
  parsed.command = escape.command(parsed.command);
21118
21149
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
21119
21150
  parsed.args = [
@@ -23365,6 +23396,15 @@ function readTokenBundle(server, authDir) {
23365
23396
  if (!existsSync(path)) return;
23366
23397
  return JSON.parse(readFileSync(path, "utf8"));
23367
23398
  }
23399
+ function deleteTokenBundle(server, authDir) {
23400
+ const path = authStorePath(server, authDir);
23401
+ if (!existsSync(path)) return false;
23402
+ rmSync(path, { force: true });
23403
+ return true;
23404
+ }
23405
+ function isTokenBundleExpired(bundle) {
23406
+ return Boolean(bundle.expiresAt && Date.parse(bundle.expiresAt) <= Date.now());
23407
+ }
23368
23408
  function writeTokenBundle(bundle, authDir) {
23369
23409
  const path = authStorePath(bundle.server, authDir);
23370
23410
  mkdirSync(dirname(path), {
@@ -23389,12 +23429,12 @@ function oauthHeaders(server, authDir) {
23389
23429
  if (!bundle?.accessToken) throw new CapletsError("AUTH_REQUIRED", `OAuth credentials required for ${server.server}`, {
23390
23430
  server: server.server,
23391
23431
  authType: "oauth2",
23392
- nextAction: "run_caplets_auth"
23432
+ nextAction: "run_caplets_auth_login"
23393
23433
  });
23394
23434
  if (bundle.expiresAt && Date.parse(bundle.expiresAt) <= Date.now()) throw new CapletsError("AUTH_REFRESH_FAILED", `OAuth token for ${server.server} is expired`, {
23395
23435
  server: server.server,
23396
23436
  authType: "oauth2",
23397
- nextAction: "run_caplets_auth"
23437
+ nextAction: "run_caplets_auth_login"
23398
23438
  });
23399
23439
  return { authorization: `${bundle.tokenType ?? "Bearer"} ${bundle.accessToken}` };
23400
23440
  }
@@ -23466,11 +23506,11 @@ var FileOAuthProvider = class {
23466
23506
  codeVerifier() {
23467
23507
  return this.verifier;
23468
23508
  }
23469
- async addClientAuthentication(headers, params) {
23509
+ addClientAuthentication = async (headers, params) => {
23470
23510
  if (this.server.auth?.type !== "oauth2" || !this.server.auth.clientSecret) return;
23471
23511
  params.set("client_secret", this.server.auth.clientSecret);
23472
23512
  headers.set("content-type", "application/x-www-form-urlencoded");
23473
- }
23513
+ };
23474
23514
  };
23475
23515
  async function runOAuthFlow(server, options = {}) {
23476
23516
  if (server.transport === "stdio" || !server.url || server.auth?.type !== "oauth2") throw new CapletsError("REQUEST_INVALID", `${server.server} is not a configured OAuth remote server`);
@@ -23533,7 +23573,7 @@ function classifyRemoteAuthError(server, response) {
23533
23573
  message: response.statusText,
23534
23574
  authType: server.auth?.type ?? "none",
23535
23575
  challenge: redactSecrets(challenge),
23536
- ...server.auth?.type === "oauth2" ? { nextAction: "run_caplets_auth" } : {}
23576
+ ...server.auth?.type === "oauth2" ? { nextAction: "run_caplets_auth_login" } : {}
23537
23577
  });
23538
23578
  }
23539
23579
  async function createLoopbackCallback(onCallback) {
@@ -23804,7 +23844,16 @@ var ServerRegistry = class {
23804
23844
  }
23805
23845
  };
23806
23846
  function capabilityDescription(server) {
23807
- const hint = `Use this tool to inspect and call tools from ${server.server}. Start with search_tools or list_tools; use get_tool for schema; use call_tool to invoke.`;
23847
+ const hint = [
23848
+ `Use this Caplets wrapper to inspect and call tools from ${server.server}.`,
23849
+ "",
23850
+ "Recommended flow:",
23851
+ "- Discover tools: {\"operation\":\"list_tools\"} or {\"operation\":\"search_tools\",\"query\":\"<what you need>\"}",
23852
+ "- Read one tool schema: {\"operation\":\"get_tool\",\"tool\":\"<tool name>\"}",
23853
+ "- Invoke one downstream tool: {\"operation\":\"call_tool\",\"tool\":\"<tool name>\",\"arguments\":{...}}",
23854
+ "",
23855
+ "Important: call_tool requires a top-level \"arguments\" JSON object containing the downstream tool inputs. Do not put downstream arguments at the top level of this wrapper request."
23856
+ ].join("\n");
23808
23857
  return `${server.name}\n\n${server.description}\n\n${hint}`;
23809
23858
  }
23810
23859
  //#endregion
@@ -23818,14 +23867,18 @@ const operations = [
23818
23867
  "call_tool"
23819
23868
  ];
23820
23869
  const generatedToolInputSchema = object({
23821
- operation: _enum(operations).describe("Operation to perform for this configured MCP server."),
23822
- query: string().optional().describe("Required for search_tools."),
23823
- limit: number$1().int().positive().optional().describe("Optional for search_tools; defaults to configured limit."),
23824
- tool: string().optional().describe("Exact downstream tool name for get_tool or call_tool."),
23825
- arguments: record(string(), unknown()).optional().describe("JSON object arguments for call_tool.")
23870
+ operation: _enum(operations).describe([
23871
+ "Caplets wrapper operation to perform for this configured MCP server.",
23872
+ "Use list_tools or search_tools to discover downstream tools, get_tool to read a downstream input schema, and call_tool to run one downstream tool.",
23873
+ "For call_tool, pass downstream inputs only inside the top-level \"arguments\" object."
23874
+ ].join(" ")),
23875
+ query: string().optional().describe("Required only for search_tools. Example: {\"operation\":\"search_tools\",\"query\":\"web search\",\"limit\":5}. Do not use query for call_tool; put downstream query values under arguments.query."),
23876
+ limit: number$1().int().positive().optional().describe("Optional only for search_tools; defaults to the configured search limit. For downstream result limits, use call_tool.arguments with the downstream schema field name."),
23877
+ tool: string().optional().describe("Exact downstream tool name for get_tool or call_tool. Example: {\"operation\":\"get_tool\",\"tool\":\"web_search_exa\"} before calling it."),
23878
+ arguments: record(string(), unknown()).optional().describe("Required JSON object only for call_tool. Put every downstream tool input inside this object. Example: {\"operation\":\"call_tool\",\"tool\":\"web_search_exa\",\"arguments\":{\"query\":\"latest MCP docs\",\"numResults\":3}}. Do not send downstream inputs as top-level query, limit, url, path, or other fields.")
23826
23879
  }).strict();
23827
23880
  async function handleServerTool(server, request, registry, downstream) {
23828
- const parsed = validateOperationRequest(request, registry.config.caplets.maxSearchLimit);
23881
+ const parsed = validateOperationRequest(request, registry.config.options.maxSearchLimit);
23829
23882
  switch (parsed.operation) {
23830
23883
  case "get_server": return jsonResult(registry.detail(server));
23831
23884
  case "check_server": return jsonResult(await downstream.checkServer(server));
@@ -23838,7 +23891,7 @@ async function handleServerTool(server, request, registry, downstream) {
23838
23891
  }
23839
23892
  case "search_tools": {
23840
23893
  const tools = await downstream.listTools(server);
23841
- const limit = parsed.limit ?? registry.config.caplets.defaultSearchLimit;
23894
+ const limit = parsed.limit ?? registry.config.options.defaultSearchLimit;
23842
23895
  return jsonResult({
23843
23896
  server: server.server,
23844
23897
  query: parsed.query,
@@ -23915,26 +23968,3138 @@ function isPlainObject(value) {
23915
23968
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
23916
23969
  }
23917
23970
  //#endregion
23918
- //#region src/cli.ts
23919
- async function runCli(args) {
23920
- const [command, serverId, ...rest] = args;
23921
- if (command !== "auth" || !serverId) throw new CapletsError("REQUEST_INVALID", "Usage: caplets auth <server> [--no-open]");
23922
- const noOpen = rest.includes("--no-open");
23923
- const server = loadConfig(process.env.CAPLETS_CONFIG).mcpServers[serverId];
23924
- if (!server) throw new CapletsError("SERVER_NOT_FOUND", `Server ${serverId} is not configured`);
23925
- if (server.disabled) throw new CapletsError("SERVER_UNAVAILABLE", `Server ${serverId} is disabled`);
23926
- if (server.transport === "stdio" || server.auth?.type !== "oauth2") throw new CapletsError("REQUEST_INVALID", `Server ${serverId} is not a remote OAuth server`);
23927
- try {
23928
- await runOAuthFlow(server, {
23929
- noOpen,
23930
- ...noOpen ? { readManualInput: maybeReadManualInput } : {},
23931
- print: (line) => console.log(line)
23932
- });
23933
- console.log(`Authenticated ${serverId}`);
23934
- } catch (error) {
23935
- console.error(JSON.stringify(toSafeError(error, "AUTH_FAILED"), null, 2));
23936
- process.exitCode = 1;
23971
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/error.js
23972
+ var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
23973
+ /**
23974
+ * CommanderError class
23975
+ */
23976
+ var CommanderError = class extends Error {
23977
+ /**
23978
+ * Constructs the CommanderError class
23979
+ * @param {number} exitCode suggested exit code which could be used with process.exit
23980
+ * @param {string} code an id string representing the error
23981
+ * @param {string} message human-readable description of the error
23982
+ */
23983
+ constructor(exitCode, code, message) {
23984
+ super(message);
23985
+ Error.captureStackTrace(this, this.constructor);
23986
+ this.name = this.constructor.name;
23987
+ this.code = code;
23988
+ this.exitCode = exitCode;
23989
+ this.nestedError = void 0;
23990
+ }
23991
+ };
23992
+ /**
23993
+ * InvalidArgumentError class
23994
+ */
23995
+ var InvalidArgumentError = class extends CommanderError {
23996
+ /**
23997
+ * Constructs the InvalidArgumentError class
23998
+ * @param {string} [message] explanation of why argument is invalid
23999
+ */
24000
+ constructor(message) {
24001
+ super(1, "commander.invalidArgument", message);
24002
+ Error.captureStackTrace(this, this.constructor);
24003
+ this.name = this.constructor.name;
24004
+ }
24005
+ };
24006
+ exports.CommanderError = CommanderError;
24007
+ exports.InvalidArgumentError = InvalidArgumentError;
24008
+ }));
24009
+ //#endregion
24010
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/argument.js
24011
+ var require_argument = /* @__PURE__ */ __commonJSMin(((exports) => {
24012
+ const { InvalidArgumentError } = require_error();
24013
+ var Argument = class {
24014
+ /**
24015
+ * Initialize a new command argument with the given name and description.
24016
+ * The default is that the argument is required, and you can explicitly
24017
+ * indicate this with <> around the name. Put [] around the name for an optional argument.
24018
+ *
24019
+ * @param {string} name
24020
+ * @param {string} [description]
24021
+ */
24022
+ constructor(name, description) {
24023
+ this.description = description || "";
24024
+ this.variadic = false;
24025
+ this.parseArg = void 0;
24026
+ this.defaultValue = void 0;
24027
+ this.defaultValueDescription = void 0;
24028
+ this.argChoices = void 0;
24029
+ switch (name[0]) {
24030
+ case "<":
24031
+ this.required = true;
24032
+ this._name = name.slice(1, -1);
24033
+ break;
24034
+ case "[":
24035
+ this.required = false;
24036
+ this._name = name.slice(1, -1);
24037
+ break;
24038
+ default:
24039
+ this.required = true;
24040
+ this._name = name;
24041
+ break;
24042
+ }
24043
+ if (this._name.endsWith("...")) {
24044
+ this.variadic = true;
24045
+ this._name = this._name.slice(0, -3);
24046
+ }
24047
+ }
24048
+ /**
24049
+ * Return argument name.
24050
+ *
24051
+ * @return {string}
24052
+ */
24053
+ name() {
24054
+ return this._name;
24055
+ }
24056
+ /**
24057
+ * @package
24058
+ */
24059
+ _collectValue(value, previous) {
24060
+ if (previous === this.defaultValue || !Array.isArray(previous)) return [value];
24061
+ previous.push(value);
24062
+ return previous;
24063
+ }
24064
+ /**
24065
+ * Set the default value, and optionally supply the description to be displayed in the help.
24066
+ *
24067
+ * @param {*} value
24068
+ * @param {string} [description]
24069
+ * @return {Argument}
24070
+ */
24071
+ default(value, description) {
24072
+ this.defaultValue = value;
24073
+ this.defaultValueDescription = description;
24074
+ return this;
24075
+ }
24076
+ /**
24077
+ * Set the custom handler for processing CLI command arguments into argument values.
24078
+ *
24079
+ * @param {Function} [fn]
24080
+ * @return {Argument}
24081
+ */
24082
+ argParser(fn) {
24083
+ this.parseArg = fn;
24084
+ return this;
24085
+ }
24086
+ /**
24087
+ * Only allow argument value to be one of choices.
24088
+ *
24089
+ * @param {string[]} values
24090
+ * @return {Argument}
24091
+ */
24092
+ choices(values) {
24093
+ this.argChoices = values.slice();
24094
+ this.parseArg = (arg, previous) => {
24095
+ if (!this.argChoices.includes(arg)) throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
24096
+ if (this.variadic) return this._collectValue(arg, previous);
24097
+ return arg;
24098
+ };
24099
+ return this;
24100
+ }
24101
+ /**
24102
+ * Make argument required.
24103
+ *
24104
+ * @returns {Argument}
24105
+ */
24106
+ argRequired() {
24107
+ this.required = true;
24108
+ return this;
24109
+ }
24110
+ /**
24111
+ * Make argument optional.
24112
+ *
24113
+ * @returns {Argument}
24114
+ */
24115
+ argOptional() {
24116
+ this.required = false;
24117
+ return this;
24118
+ }
24119
+ };
24120
+ /**
24121
+ * Takes an argument and returns its human readable equivalent for help usage.
24122
+ *
24123
+ * @param {Argument} arg
24124
+ * @return {string}
24125
+ * @private
24126
+ */
24127
+ function humanReadableArgName(arg) {
24128
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
24129
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
24130
+ }
24131
+ exports.Argument = Argument;
24132
+ exports.humanReadableArgName = humanReadableArgName;
24133
+ }));
24134
+ //#endregion
24135
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/help.js
24136
+ var require_help = /* @__PURE__ */ __commonJSMin(((exports) => {
24137
+ const { humanReadableArgName } = require_argument();
24138
+ /**
24139
+ * TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`
24140
+ * https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types
24141
+ * @typedef { import("./argument.js").Argument } Argument
24142
+ * @typedef { import("./command.js").Command } Command
24143
+ * @typedef { import("./option.js").Option } Option
24144
+ */
24145
+ var Help = class {
24146
+ constructor() {
24147
+ this.helpWidth = void 0;
24148
+ this.minWidthToWrap = 40;
24149
+ this.sortSubcommands = false;
24150
+ this.sortOptions = false;
24151
+ this.showGlobalOptions = false;
24152
+ }
24153
+ /**
24154
+ * prepareContext is called by Commander after applying overrides from `Command.configureHelp()`
24155
+ * and just before calling `formatHelp()`.
24156
+ *
24157
+ * Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.
24158
+ *
24159
+ * @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions
24160
+ */
24161
+ prepareContext(contextOptions) {
24162
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
24163
+ }
24164
+ /**
24165
+ * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
24166
+ *
24167
+ * @param {Command} cmd
24168
+ * @returns {Command[]}
24169
+ */
24170
+ visibleCommands(cmd) {
24171
+ const visibleCommands = cmd.commands.filter((cmd) => !cmd._hidden);
24172
+ const helpCommand = cmd._getHelpCommand();
24173
+ if (helpCommand && !helpCommand._hidden) visibleCommands.push(helpCommand);
24174
+ if (this.sortSubcommands) visibleCommands.sort((a, b) => {
24175
+ return a.name().localeCompare(b.name());
24176
+ });
24177
+ return visibleCommands;
24178
+ }
24179
+ /**
24180
+ * Compare options for sort.
24181
+ *
24182
+ * @param {Option} a
24183
+ * @param {Option} b
24184
+ * @returns {number}
24185
+ */
24186
+ compareOptions(a, b) {
24187
+ const getSortKey = (option) => {
24188
+ return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
24189
+ };
24190
+ return getSortKey(a).localeCompare(getSortKey(b));
24191
+ }
24192
+ /**
24193
+ * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
24194
+ *
24195
+ * @param {Command} cmd
24196
+ * @returns {Option[]}
24197
+ */
24198
+ visibleOptions(cmd) {
24199
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
24200
+ const helpOption = cmd._getHelpOption();
24201
+ if (helpOption && !helpOption.hidden) {
24202
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
24203
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
24204
+ if (!removeShort && !removeLong) visibleOptions.push(helpOption);
24205
+ else if (helpOption.long && !removeLong) visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
24206
+ else if (helpOption.short && !removeShort) visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
24207
+ }
24208
+ if (this.sortOptions) visibleOptions.sort(this.compareOptions);
24209
+ return visibleOptions;
24210
+ }
24211
+ /**
24212
+ * Get an array of the visible global options. (Not including help.)
24213
+ *
24214
+ * @param {Command} cmd
24215
+ * @returns {Option[]}
24216
+ */
24217
+ visibleGlobalOptions(cmd) {
24218
+ if (!this.showGlobalOptions) return [];
24219
+ const globalOptions = [];
24220
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
24221
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
24222
+ globalOptions.push(...visibleOptions);
24223
+ }
24224
+ if (this.sortOptions) globalOptions.sort(this.compareOptions);
24225
+ return globalOptions;
24226
+ }
24227
+ /**
24228
+ * Get an array of the arguments if any have a description.
24229
+ *
24230
+ * @param {Command} cmd
24231
+ * @returns {Argument[]}
24232
+ */
24233
+ visibleArguments(cmd) {
24234
+ if (cmd._argsDescription) cmd.registeredArguments.forEach((argument) => {
24235
+ argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
24236
+ });
24237
+ if (cmd.registeredArguments.find((argument) => argument.description)) return cmd.registeredArguments;
24238
+ return [];
24239
+ }
24240
+ /**
24241
+ * Get the command term to show in the list of subcommands.
24242
+ *
24243
+ * @param {Command} cmd
24244
+ * @returns {string}
24245
+ */
24246
+ subcommandTerm(cmd) {
24247
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
24248
+ return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
24249
+ }
24250
+ /**
24251
+ * Get the option term to show in the list of options.
24252
+ *
24253
+ * @param {Option} option
24254
+ * @returns {string}
24255
+ */
24256
+ optionTerm(option) {
24257
+ return option.flags;
24258
+ }
24259
+ /**
24260
+ * Get the argument term to show in the list of arguments.
24261
+ *
24262
+ * @param {Argument} argument
24263
+ * @returns {string}
24264
+ */
24265
+ argumentTerm(argument) {
24266
+ return argument.name();
24267
+ }
24268
+ /**
24269
+ * Get the longest command term length.
24270
+ *
24271
+ * @param {Command} cmd
24272
+ * @param {Help} helper
24273
+ * @returns {number}
24274
+ */
24275
+ longestSubcommandTermLength(cmd, helper) {
24276
+ return helper.visibleCommands(cmd).reduce((max, command) => {
24277
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
24278
+ }, 0);
24279
+ }
24280
+ /**
24281
+ * Get the longest option term length.
24282
+ *
24283
+ * @param {Command} cmd
24284
+ * @param {Help} helper
24285
+ * @returns {number}
24286
+ */
24287
+ longestOptionTermLength(cmd, helper) {
24288
+ return helper.visibleOptions(cmd).reduce((max, option) => {
24289
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
24290
+ }, 0);
24291
+ }
24292
+ /**
24293
+ * Get the longest global option term length.
24294
+ *
24295
+ * @param {Command} cmd
24296
+ * @param {Help} helper
24297
+ * @returns {number}
24298
+ */
24299
+ longestGlobalOptionTermLength(cmd, helper) {
24300
+ return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
24301
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
24302
+ }, 0);
24303
+ }
24304
+ /**
24305
+ * Get the longest argument term length.
24306
+ *
24307
+ * @param {Command} cmd
24308
+ * @param {Help} helper
24309
+ * @returns {number}
24310
+ */
24311
+ longestArgumentTermLength(cmd, helper) {
24312
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
24313
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
24314
+ }, 0);
24315
+ }
24316
+ /**
24317
+ * Get the command usage to be displayed at the top of the built-in help.
24318
+ *
24319
+ * @param {Command} cmd
24320
+ * @returns {string}
24321
+ */
24322
+ commandUsage(cmd) {
24323
+ let cmdName = cmd._name;
24324
+ if (cmd._aliases[0]) cmdName = cmdName + "|" + cmd._aliases[0];
24325
+ let ancestorCmdNames = "";
24326
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
24327
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
24328
+ }
24329
+ /**
24330
+ * Get the description for the command.
24331
+ *
24332
+ * @param {Command} cmd
24333
+ * @returns {string}
24334
+ */
24335
+ commandDescription(cmd) {
24336
+ return cmd.description();
24337
+ }
24338
+ /**
24339
+ * Get the subcommand summary to show in the list of subcommands.
24340
+ * (Fallback to description for backwards compatibility.)
24341
+ *
24342
+ * @param {Command} cmd
24343
+ * @returns {string}
24344
+ */
24345
+ subcommandDescription(cmd) {
24346
+ return cmd.summary() || cmd.description();
24347
+ }
24348
+ /**
24349
+ * Get the option description to show in the list of options.
24350
+ *
24351
+ * @param {Option} option
24352
+ * @return {string}
24353
+ */
24354
+ optionDescription(option) {
24355
+ const extraInfo = [];
24356
+ if (option.argChoices) extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
24357
+ if (option.defaultValue !== void 0) {
24358
+ if (option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean") extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
24359
+ }
24360
+ if (option.presetArg !== void 0 && option.optional) extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
24361
+ if (option.envVar !== void 0) extraInfo.push(`env: ${option.envVar}`);
24362
+ if (extraInfo.length > 0) {
24363
+ const extraDescription = `(${extraInfo.join(", ")})`;
24364
+ if (option.description) return `${option.description} ${extraDescription}`;
24365
+ return extraDescription;
24366
+ }
24367
+ return option.description;
24368
+ }
24369
+ /**
24370
+ * Get the argument description to show in the list of arguments.
24371
+ *
24372
+ * @param {Argument} argument
24373
+ * @return {string}
24374
+ */
24375
+ argumentDescription(argument) {
24376
+ const extraInfo = [];
24377
+ if (argument.argChoices) extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
24378
+ if (argument.defaultValue !== void 0) extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
24379
+ if (extraInfo.length > 0) {
24380
+ const extraDescription = `(${extraInfo.join(", ")})`;
24381
+ if (argument.description) return `${argument.description} ${extraDescription}`;
24382
+ return extraDescription;
24383
+ }
24384
+ return argument.description;
24385
+ }
24386
+ /**
24387
+ * Format a list of items, given a heading and an array of formatted items.
24388
+ *
24389
+ * @param {string} heading
24390
+ * @param {string[]} items
24391
+ * @param {Help} helper
24392
+ * @returns string[]
24393
+ */
24394
+ formatItemList(heading, items, helper) {
24395
+ if (items.length === 0) return [];
24396
+ return [
24397
+ helper.styleTitle(heading),
24398
+ ...items,
24399
+ ""
24400
+ ];
24401
+ }
24402
+ /**
24403
+ * Group items by their help group heading.
24404
+ *
24405
+ * @param {Command[] | Option[]} unsortedItems
24406
+ * @param {Command[] | Option[]} visibleItems
24407
+ * @param {Function} getGroup
24408
+ * @returns {Map<string, Command[] | Option[]>}
24409
+ */
24410
+ groupItems(unsortedItems, visibleItems, getGroup) {
24411
+ const result = /* @__PURE__ */ new Map();
24412
+ unsortedItems.forEach((item) => {
24413
+ const group = getGroup(item);
24414
+ if (!result.has(group)) result.set(group, []);
24415
+ });
24416
+ visibleItems.forEach((item) => {
24417
+ const group = getGroup(item);
24418
+ if (!result.has(group)) result.set(group, []);
24419
+ result.get(group).push(item);
24420
+ });
24421
+ return result;
24422
+ }
24423
+ /**
24424
+ * Generate the built-in help text.
24425
+ *
24426
+ * @param {Command} cmd
24427
+ * @param {Help} helper
24428
+ * @returns {string}
24429
+ */
24430
+ formatHelp(cmd, helper) {
24431
+ const termWidth = helper.padWidth(cmd, helper);
24432
+ const helpWidth = helper.helpWidth ?? 80;
24433
+ function callFormatItem(term, description) {
24434
+ return helper.formatItem(term, termWidth, description, helper);
24435
+ }
24436
+ let output = [`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`, ""];
24437
+ const commandDescription = helper.commandDescription(cmd);
24438
+ if (commandDescription.length > 0) output = output.concat([helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth), ""]);
24439
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
24440
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
24441
+ });
24442
+ output = output.concat(this.formatItemList("Arguments:", argumentList, helper));
24443
+ this.groupItems(cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:").forEach((options, group) => {
24444
+ const optionList = options.map((option) => {
24445
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
24446
+ });
24447
+ output = output.concat(this.formatItemList(group, optionList, helper));
24448
+ });
24449
+ if (helper.showGlobalOptions) {
24450
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
24451
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
24452
+ });
24453
+ output = output.concat(this.formatItemList("Global Options:", globalOptionList, helper));
24454
+ }
24455
+ this.groupItems(cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:").forEach((commands, group) => {
24456
+ const commandList = commands.map((sub) => {
24457
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)));
24458
+ });
24459
+ output = output.concat(this.formatItemList(group, commandList, helper));
24460
+ });
24461
+ return output.join("\n");
24462
+ }
24463
+ /**
24464
+ * Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.
24465
+ *
24466
+ * @param {string} str
24467
+ * @returns {number}
24468
+ */
24469
+ displayWidth(str) {
24470
+ return stripColor(str).length;
24471
+ }
24472
+ /**
24473
+ * Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.
24474
+ *
24475
+ * @param {string} str
24476
+ * @returns {string}
24477
+ */
24478
+ styleTitle(str) {
24479
+ return str;
24480
+ }
24481
+ styleUsage(str) {
24482
+ return str.split(" ").map((word) => {
24483
+ if (word === "[options]") return this.styleOptionText(word);
24484
+ if (word === "[command]") return this.styleSubcommandText(word);
24485
+ if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word);
24486
+ return this.styleCommandText(word);
24487
+ }).join(" ");
24488
+ }
24489
+ styleCommandDescription(str) {
24490
+ return this.styleDescriptionText(str);
24491
+ }
24492
+ styleOptionDescription(str) {
24493
+ return this.styleDescriptionText(str);
24494
+ }
24495
+ styleSubcommandDescription(str) {
24496
+ return this.styleDescriptionText(str);
24497
+ }
24498
+ styleArgumentDescription(str) {
24499
+ return this.styleDescriptionText(str);
24500
+ }
24501
+ styleDescriptionText(str) {
24502
+ return str;
24503
+ }
24504
+ styleOptionTerm(str) {
24505
+ return this.styleOptionText(str);
24506
+ }
24507
+ styleSubcommandTerm(str) {
24508
+ return str.split(" ").map((word) => {
24509
+ if (word === "[options]") return this.styleOptionText(word);
24510
+ if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word);
24511
+ return this.styleSubcommandText(word);
24512
+ }).join(" ");
24513
+ }
24514
+ styleArgumentTerm(str) {
24515
+ return this.styleArgumentText(str);
24516
+ }
24517
+ styleOptionText(str) {
24518
+ return str;
24519
+ }
24520
+ styleArgumentText(str) {
24521
+ return str;
24522
+ }
24523
+ styleSubcommandText(str) {
24524
+ return str;
24525
+ }
24526
+ styleCommandText(str) {
24527
+ return str;
24528
+ }
24529
+ /**
24530
+ * Calculate the pad width from the maximum term length.
24531
+ *
24532
+ * @param {Command} cmd
24533
+ * @param {Help} helper
24534
+ * @returns {number}
24535
+ */
24536
+ padWidth(cmd, helper) {
24537
+ return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
24538
+ }
24539
+ /**
24540
+ * Detect manually wrapped and indented strings by checking for line break followed by whitespace.
24541
+ *
24542
+ * @param {string} str
24543
+ * @returns {boolean}
24544
+ */
24545
+ preformatted(str) {
24546
+ return /\n[^\S\r\n]/.test(str);
24547
+ }
24548
+ /**
24549
+ * Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.
24550
+ *
24551
+ * So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so:
24552
+ * TTT DDD DDDD
24553
+ * DD DDD
24554
+ *
24555
+ * @param {string} term
24556
+ * @param {number} termWidth
24557
+ * @param {string} description
24558
+ * @param {Help} helper
24559
+ * @returns {string}
24560
+ */
24561
+ formatItem(term, termWidth, description, helper) {
24562
+ const itemIndent = 2;
24563
+ const itemIndentStr = " ".repeat(itemIndent);
24564
+ if (!description) return itemIndentStr + term;
24565
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
24566
+ const spacerWidth = 2;
24567
+ const remainingWidth = (this.helpWidth ?? 80) - termWidth - spacerWidth - itemIndent;
24568
+ let formattedDescription;
24569
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) formattedDescription = description;
24570
+ else formattedDescription = helper.boxWrap(description, remainingWidth).replace(/\n/g, "\n" + " ".repeat(termWidth + spacerWidth));
24571
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `\n${itemIndentStr}`);
24572
+ }
24573
+ /**
24574
+ * Wrap a string at whitespace, preserving existing line breaks.
24575
+ * Wrapping is skipped if the width is less than `minWidthToWrap`.
24576
+ *
24577
+ * @param {string} str
24578
+ * @param {number} width
24579
+ * @returns {string}
24580
+ */
24581
+ boxWrap(str, width) {
24582
+ if (width < this.minWidthToWrap) return str;
24583
+ const rawLines = str.split(/\r\n|\n/);
24584
+ const chunkPattern = /[\s]*[^\s]+/g;
24585
+ const wrappedLines = [];
24586
+ rawLines.forEach((line) => {
24587
+ const chunks = line.match(chunkPattern);
24588
+ if (chunks === null) {
24589
+ wrappedLines.push("");
24590
+ return;
24591
+ }
24592
+ let sumChunks = [chunks.shift()];
24593
+ let sumWidth = this.displayWidth(sumChunks[0]);
24594
+ chunks.forEach((chunk) => {
24595
+ const visibleWidth = this.displayWidth(chunk);
24596
+ if (sumWidth + visibleWidth <= width) {
24597
+ sumChunks.push(chunk);
24598
+ sumWidth += visibleWidth;
24599
+ return;
24600
+ }
24601
+ wrappedLines.push(sumChunks.join(""));
24602
+ const nextChunk = chunk.trimStart();
24603
+ sumChunks = [nextChunk];
24604
+ sumWidth = this.displayWidth(nextChunk);
24605
+ });
24606
+ wrappedLines.push(sumChunks.join(""));
24607
+ });
24608
+ return wrappedLines.join("\n");
24609
+ }
24610
+ };
24611
+ /**
24612
+ * Strip style ANSI escape sequences from the string. In particular, SGR (Select Graphic Rendition) codes.
24613
+ *
24614
+ * @param {string} str
24615
+ * @returns {string}
24616
+ * @package
24617
+ */
24618
+ function stripColor(str) {
24619
+ return str.replace(/\x1b\[\d*(;\d*)*m/g, "");
23937
24620
  }
24621
+ exports.Help = Help;
24622
+ exports.stripColor = stripColor;
24623
+ }));
24624
+ //#endregion
24625
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/option.js
24626
+ var require_option = /* @__PURE__ */ __commonJSMin(((exports) => {
24627
+ const { InvalidArgumentError } = require_error();
24628
+ var Option = class {
24629
+ /**
24630
+ * Initialize a new `Option` with the given `flags` and `description`.
24631
+ *
24632
+ * @param {string} flags
24633
+ * @param {string} [description]
24634
+ */
24635
+ constructor(flags, description) {
24636
+ this.flags = flags;
24637
+ this.description = description || "";
24638
+ this.required = flags.includes("<");
24639
+ this.optional = flags.includes("[");
24640
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags);
24641
+ this.mandatory = false;
24642
+ const optionFlags = splitOptionFlags(flags);
24643
+ this.short = optionFlags.shortFlag;
24644
+ this.long = optionFlags.longFlag;
24645
+ this.negate = false;
24646
+ if (this.long) this.negate = this.long.startsWith("--no-");
24647
+ this.defaultValue = void 0;
24648
+ this.defaultValueDescription = void 0;
24649
+ this.presetArg = void 0;
24650
+ this.envVar = void 0;
24651
+ this.parseArg = void 0;
24652
+ this.hidden = false;
24653
+ this.argChoices = void 0;
24654
+ this.conflictsWith = [];
24655
+ this.implied = void 0;
24656
+ this.helpGroupHeading = void 0;
24657
+ }
24658
+ /**
24659
+ * Set the default value, and optionally supply the description to be displayed in the help.
24660
+ *
24661
+ * @param {*} value
24662
+ * @param {string} [description]
24663
+ * @return {Option}
24664
+ */
24665
+ default(value, description) {
24666
+ this.defaultValue = value;
24667
+ this.defaultValueDescription = description;
24668
+ return this;
24669
+ }
24670
+ /**
24671
+ * Preset to use when option used without option-argument, especially optional but also boolean and negated.
24672
+ * The custom processing (parseArg) is called.
24673
+ *
24674
+ * @example
24675
+ * new Option('--color').default('GREYSCALE').preset('RGB');
24676
+ * new Option('--donate [amount]').preset('20').argParser(parseFloat);
24677
+ *
24678
+ * @param {*} arg
24679
+ * @return {Option}
24680
+ */
24681
+ preset(arg) {
24682
+ this.presetArg = arg;
24683
+ return this;
24684
+ }
24685
+ /**
24686
+ * Add option name(s) that conflict with this option.
24687
+ * An error will be displayed if conflicting options are found during parsing.
24688
+ *
24689
+ * @example
24690
+ * new Option('--rgb').conflicts('cmyk');
24691
+ * new Option('--js').conflicts(['ts', 'jsx']);
24692
+ *
24693
+ * @param {(string | string[])} names
24694
+ * @return {Option}
24695
+ */
24696
+ conflicts(names) {
24697
+ this.conflictsWith = this.conflictsWith.concat(names);
24698
+ return this;
24699
+ }
24700
+ /**
24701
+ * Specify implied option values for when this option is set and the implied options are not.
24702
+ *
24703
+ * The custom processing (parseArg) is not called on the implied values.
24704
+ *
24705
+ * @example
24706
+ * program
24707
+ * .addOption(new Option('--log', 'write logging information to file'))
24708
+ * .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
24709
+ *
24710
+ * @param {object} impliedOptionValues
24711
+ * @return {Option}
24712
+ */
24713
+ implies(impliedOptionValues) {
24714
+ let newImplied = impliedOptionValues;
24715
+ if (typeof impliedOptionValues === "string") newImplied = { [impliedOptionValues]: true };
24716
+ this.implied = Object.assign(this.implied || {}, newImplied);
24717
+ return this;
24718
+ }
24719
+ /**
24720
+ * Set environment variable to check for option value.
24721
+ *
24722
+ * An environment variable is only used if when processed the current option value is
24723
+ * undefined, or the source of the current value is 'default' or 'config' or 'env'.
24724
+ *
24725
+ * @param {string} name
24726
+ * @return {Option}
24727
+ */
24728
+ env(name) {
24729
+ this.envVar = name;
24730
+ return this;
24731
+ }
24732
+ /**
24733
+ * Set the custom handler for processing CLI option arguments into option values.
24734
+ *
24735
+ * @param {Function} [fn]
24736
+ * @return {Option}
24737
+ */
24738
+ argParser(fn) {
24739
+ this.parseArg = fn;
24740
+ return this;
24741
+ }
24742
+ /**
24743
+ * Whether the option is mandatory and must have a value after parsing.
24744
+ *
24745
+ * @param {boolean} [mandatory=true]
24746
+ * @return {Option}
24747
+ */
24748
+ makeOptionMandatory(mandatory = true) {
24749
+ this.mandatory = !!mandatory;
24750
+ return this;
24751
+ }
24752
+ /**
24753
+ * Hide option in help.
24754
+ *
24755
+ * @param {boolean} [hide=true]
24756
+ * @return {Option}
24757
+ */
24758
+ hideHelp(hide = true) {
24759
+ this.hidden = !!hide;
24760
+ return this;
24761
+ }
24762
+ /**
24763
+ * @package
24764
+ */
24765
+ _collectValue(value, previous) {
24766
+ if (previous === this.defaultValue || !Array.isArray(previous)) return [value];
24767
+ previous.push(value);
24768
+ return previous;
24769
+ }
24770
+ /**
24771
+ * Only allow option value to be one of choices.
24772
+ *
24773
+ * @param {string[]} values
24774
+ * @return {Option}
24775
+ */
24776
+ choices(values) {
24777
+ this.argChoices = values.slice();
24778
+ this.parseArg = (arg, previous) => {
24779
+ if (!this.argChoices.includes(arg)) throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
24780
+ if (this.variadic) return this._collectValue(arg, previous);
24781
+ return arg;
24782
+ };
24783
+ return this;
24784
+ }
24785
+ /**
24786
+ * Return option name.
24787
+ *
24788
+ * @return {string}
24789
+ */
24790
+ name() {
24791
+ if (this.long) return this.long.replace(/^--/, "");
24792
+ return this.short.replace(/^-/, "");
24793
+ }
24794
+ /**
24795
+ * Return option name, in a camelcase format that can be used
24796
+ * as an object attribute key.
24797
+ *
24798
+ * @return {string}
24799
+ */
24800
+ attributeName() {
24801
+ if (this.negate) return camelcase(this.name().replace(/^no-/, ""));
24802
+ return camelcase(this.name());
24803
+ }
24804
+ /**
24805
+ * Set the help group heading.
24806
+ *
24807
+ * @param {string} heading
24808
+ * @return {Option}
24809
+ */
24810
+ helpGroup(heading) {
24811
+ this.helpGroupHeading = heading;
24812
+ return this;
24813
+ }
24814
+ /**
24815
+ * Check if `arg` matches the short or long flag.
24816
+ *
24817
+ * @param {string} arg
24818
+ * @return {boolean}
24819
+ * @package
24820
+ */
24821
+ is(arg) {
24822
+ return this.short === arg || this.long === arg;
24823
+ }
24824
+ /**
24825
+ * Return whether a boolean option.
24826
+ *
24827
+ * Options are one of boolean, negated, required argument, or optional argument.
24828
+ *
24829
+ * @return {boolean}
24830
+ * @package
24831
+ */
24832
+ isBoolean() {
24833
+ return !this.required && !this.optional && !this.negate;
24834
+ }
24835
+ };
24836
+ /**
24837
+ * This class is to make it easier to work with dual options, without changing the existing
24838
+ * implementation. We support separate dual options for separate positive and negative options,
24839
+ * like `--build` and `--no-build`, which share a single option value. This works nicely for some
24840
+ * use cases, but is tricky for others where we want separate behaviours despite
24841
+ * the single shared option value.
24842
+ */
24843
+ var DualOptions = class {
24844
+ /**
24845
+ * @param {Option[]} options
24846
+ */
24847
+ constructor(options) {
24848
+ this.positiveOptions = /* @__PURE__ */ new Map();
24849
+ this.negativeOptions = /* @__PURE__ */ new Map();
24850
+ this.dualOptions = /* @__PURE__ */ new Set();
24851
+ options.forEach((option) => {
24852
+ if (option.negate) this.negativeOptions.set(option.attributeName(), option);
24853
+ else this.positiveOptions.set(option.attributeName(), option);
24854
+ });
24855
+ this.negativeOptions.forEach((value, key) => {
24856
+ if (this.positiveOptions.has(key)) this.dualOptions.add(key);
24857
+ });
24858
+ }
24859
+ /**
24860
+ * Did the value come from the option, and not from possible matching dual option?
24861
+ *
24862
+ * @param {*} value
24863
+ * @param {Option} option
24864
+ * @returns {boolean}
24865
+ */
24866
+ valueFromOption(value, option) {
24867
+ const optionKey = option.attributeName();
24868
+ if (!this.dualOptions.has(optionKey)) return true;
24869
+ const preset = this.negativeOptions.get(optionKey).presetArg;
24870
+ const negativeValue = preset !== void 0 ? preset : false;
24871
+ return option.negate === (negativeValue === value);
24872
+ }
24873
+ };
24874
+ /**
24875
+ * Convert string from kebab-case to camelCase.
24876
+ *
24877
+ * @param {string} str
24878
+ * @return {string}
24879
+ * @private
24880
+ */
24881
+ function camelcase(str) {
24882
+ return str.split("-").reduce((str, word) => {
24883
+ return str + word[0].toUpperCase() + word.slice(1);
24884
+ });
24885
+ }
24886
+ /**
24887
+ * Split the short and long flag out of something like '-m,--mixed <value>'
24888
+ *
24889
+ * @private
24890
+ */
24891
+ function splitOptionFlags(flags) {
24892
+ let shortFlag;
24893
+ let longFlag;
24894
+ const shortFlagExp = /^-[^-]$/;
24895
+ const longFlagExp = /^--[^-]/;
24896
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
24897
+ if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
24898
+ if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
24899
+ if (!shortFlag && shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
24900
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
24901
+ shortFlag = longFlag;
24902
+ longFlag = flagParts.shift();
24903
+ }
24904
+ if (flagParts[0].startsWith("-")) {
24905
+ const unsupportedFlag = flagParts[0];
24906
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
24907
+ if (/^-[^-][^-]/.test(unsupportedFlag)) throw new Error(`${baseError}
24908
+ - a short flag is a single dash and a single character
24909
+ - either use a single dash and a single character (for a short flag)
24910
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
24911
+ if (shortFlagExp.test(unsupportedFlag)) throw new Error(`${baseError}
24912
+ - too many short flags`);
24913
+ if (longFlagExp.test(unsupportedFlag)) throw new Error(`${baseError}
24914
+ - too many long flags`);
24915
+ throw new Error(`${baseError}
24916
+ - unrecognised flag format`);
24917
+ }
24918
+ if (shortFlag === void 0 && longFlag === void 0) throw new Error(`option creation failed due to no flags found in '${flags}'.`);
24919
+ return {
24920
+ shortFlag,
24921
+ longFlag
24922
+ };
24923
+ }
24924
+ exports.Option = Option;
24925
+ exports.DualOptions = DualOptions;
24926
+ }));
24927
+ //#endregion
24928
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/suggestSimilar.js
24929
+ var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
24930
+ const maxDistance = 3;
24931
+ function editDistance(a, b) {
24932
+ if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);
24933
+ const d = [];
24934
+ for (let i = 0; i <= a.length; i++) d[i] = [i];
24935
+ for (let j = 0; j <= b.length; j++) d[0][j] = j;
24936
+ for (let j = 1; j <= b.length; j++) for (let i = 1; i <= a.length; i++) {
24937
+ let cost = 1;
24938
+ if (a[i - 1] === b[j - 1]) cost = 0;
24939
+ else cost = 1;
24940
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
24941
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
24942
+ }
24943
+ return d[a.length][b.length];
24944
+ }
24945
+ /**
24946
+ * Find close matches, restricted to same number of edits.
24947
+ *
24948
+ * @param {string} word
24949
+ * @param {string[]} candidates
24950
+ * @returns {string}
24951
+ */
24952
+ function suggestSimilar(word, candidates) {
24953
+ if (!candidates || candidates.length === 0) return "";
24954
+ candidates = Array.from(new Set(candidates));
24955
+ const searchingOptions = word.startsWith("--");
24956
+ if (searchingOptions) {
24957
+ word = word.slice(2);
24958
+ candidates = candidates.map((candidate) => candidate.slice(2));
24959
+ }
24960
+ let similar = [];
24961
+ let bestDistance = maxDistance;
24962
+ const minSimilarity = .4;
24963
+ candidates.forEach((candidate) => {
24964
+ if (candidate.length <= 1) return;
24965
+ const distance = editDistance(word, candidate);
24966
+ const length = Math.max(word.length, candidate.length);
24967
+ if ((length - distance) / length > minSimilarity) {
24968
+ if (distance < bestDistance) {
24969
+ bestDistance = distance;
24970
+ similar = [candidate];
24971
+ } else if (distance === bestDistance) similar.push(candidate);
24972
+ }
24973
+ });
24974
+ similar.sort((a, b) => a.localeCompare(b));
24975
+ if (searchingOptions) similar = similar.map((candidate) => `--${candidate}`);
24976
+ if (similar.length > 1) return `\n(Did you mean one of ${similar.join(", ")}?)`;
24977
+ if (similar.length === 1) return `\n(Did you mean ${similar[0]}?)`;
24978
+ return "";
24979
+ }
24980
+ exports.suggestSimilar = suggestSimilar;
24981
+ }));
24982
+ //#endregion
24983
+ //#region node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/command.js
24984
+ var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
24985
+ const EventEmitter = __require("node:events").EventEmitter;
24986
+ const childProcess = __require("node:child_process");
24987
+ const path = __require("node:path");
24988
+ const fs = __require("node:fs");
24989
+ const process$2 = __require("node:process");
24990
+ const { Argument, humanReadableArgName } = require_argument();
24991
+ const { CommanderError } = require_error();
24992
+ const { Help, stripColor } = require_help();
24993
+ const { Option, DualOptions } = require_option();
24994
+ const { suggestSimilar } = require_suggestSimilar();
24995
+ var Command = class Command extends EventEmitter {
24996
+ /**
24997
+ * Initialize a new `Command`.
24998
+ *
24999
+ * @param {string} [name]
25000
+ */
25001
+ constructor(name) {
25002
+ super();
25003
+ /** @type {Command[]} */
25004
+ this.commands = [];
25005
+ /** @type {Option[]} */
25006
+ this.options = [];
25007
+ this.parent = null;
25008
+ this._allowUnknownOption = false;
25009
+ this._allowExcessArguments = false;
25010
+ /** @type {Argument[]} */
25011
+ this.registeredArguments = [];
25012
+ this._args = this.registeredArguments;
25013
+ /** @type {string[]} */
25014
+ this.args = [];
25015
+ this.rawArgs = [];
25016
+ this.processedArgs = [];
25017
+ this._scriptPath = null;
25018
+ this._name = name || "";
25019
+ this._optionValues = {};
25020
+ this._optionValueSources = {};
25021
+ this._storeOptionsAsProperties = false;
25022
+ this._actionHandler = null;
25023
+ this._executableHandler = false;
25024
+ this._executableFile = null;
25025
+ this._executableDir = null;
25026
+ this._defaultCommandName = null;
25027
+ this._exitCallback = null;
25028
+ this._aliases = [];
25029
+ this._combineFlagAndOptionalValue = true;
25030
+ this._description = "";
25031
+ this._summary = "";
25032
+ this._argsDescription = void 0;
25033
+ this._enablePositionalOptions = false;
25034
+ this._passThroughOptions = false;
25035
+ this._lifeCycleHooks = {};
25036
+ /** @type {(boolean | string)} */
25037
+ this._showHelpAfterError = false;
25038
+ this._showSuggestionAfterError = true;
25039
+ this._savedState = null;
25040
+ this._outputConfiguration = {
25041
+ writeOut: (str) => process$2.stdout.write(str),
25042
+ writeErr: (str) => process$2.stderr.write(str),
25043
+ outputError: (str, write) => write(str),
25044
+ getOutHelpWidth: () => process$2.stdout.isTTY ? process$2.stdout.columns : void 0,
25045
+ getErrHelpWidth: () => process$2.stderr.isTTY ? process$2.stderr.columns : void 0,
25046
+ getOutHasColors: () => useColor() ?? (process$2.stdout.isTTY && process$2.stdout.hasColors?.()),
25047
+ getErrHasColors: () => useColor() ?? (process$2.stderr.isTTY && process$2.stderr.hasColors?.()),
25048
+ stripColor: (str) => stripColor(str)
25049
+ };
25050
+ this._hidden = false;
25051
+ /** @type {(Option | null | undefined)} */
25052
+ this._helpOption = void 0;
25053
+ this._addImplicitHelpCommand = void 0;
25054
+ /** @type {Command} */
25055
+ this._helpCommand = void 0;
25056
+ this._helpConfiguration = {};
25057
+ /** @type {string | undefined} */
25058
+ this._helpGroupHeading = void 0;
25059
+ /** @type {string | undefined} */
25060
+ this._defaultCommandGroup = void 0;
25061
+ /** @type {string | undefined} */
25062
+ this._defaultOptionGroup = void 0;
25063
+ }
25064
+ /**
25065
+ * Copy settings that are useful to have in common across root command and subcommands.
25066
+ *
25067
+ * (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
25068
+ *
25069
+ * @param {Command} sourceCommand
25070
+ * @return {Command} `this` command for chaining
25071
+ */
25072
+ copyInheritedSettings(sourceCommand) {
25073
+ this._outputConfiguration = sourceCommand._outputConfiguration;
25074
+ this._helpOption = sourceCommand._helpOption;
25075
+ this._helpCommand = sourceCommand._helpCommand;
25076
+ this._helpConfiguration = sourceCommand._helpConfiguration;
25077
+ this._exitCallback = sourceCommand._exitCallback;
25078
+ this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
25079
+ this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
25080
+ this._allowExcessArguments = sourceCommand._allowExcessArguments;
25081
+ this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
25082
+ this._showHelpAfterError = sourceCommand._showHelpAfterError;
25083
+ this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
25084
+ return this;
25085
+ }
25086
+ /**
25087
+ * @returns {Command[]}
25088
+ * @private
25089
+ */
25090
+ _getCommandAndAncestors() {
25091
+ const result = [];
25092
+ for (let command = this; command; command = command.parent) result.push(command);
25093
+ return result;
25094
+ }
25095
+ /**
25096
+ * Define a command.
25097
+ *
25098
+ * There are two styles of command: pay attention to where to put the description.
25099
+ *
25100
+ * @example
25101
+ * // Command implemented using action handler (description is supplied separately to `.command`)
25102
+ * program
25103
+ * .command('clone <source> [destination]')
25104
+ * .description('clone a repository into a newly created directory')
25105
+ * .action((source, destination) => {
25106
+ * console.log('clone command called');
25107
+ * });
25108
+ *
25109
+ * // Command implemented using separate executable file (description is second parameter to `.command`)
25110
+ * program
25111
+ * .command('start <service>', 'start named service')
25112
+ * .command('stop [service]', 'stop named service, or all if no name supplied');
25113
+ *
25114
+ * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
25115
+ * @param {(object | string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
25116
+ * @param {object} [execOpts] - configuration options (for executable)
25117
+ * @return {Command} returns new command for action handler, or `this` for executable command
25118
+ */
25119
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
25120
+ let desc = actionOptsOrExecDesc;
25121
+ let opts = execOpts;
25122
+ if (typeof desc === "object" && desc !== null) {
25123
+ opts = desc;
25124
+ desc = null;
25125
+ }
25126
+ opts = opts || {};
25127
+ const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
25128
+ const cmd = this.createCommand(name);
25129
+ if (desc) {
25130
+ cmd.description(desc);
25131
+ cmd._executableHandler = true;
25132
+ }
25133
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
25134
+ cmd._hidden = !!(opts.noHelp || opts.hidden);
25135
+ cmd._executableFile = opts.executableFile || null;
25136
+ if (args) cmd.arguments(args);
25137
+ this._registerCommand(cmd);
25138
+ cmd.parent = this;
25139
+ cmd.copyInheritedSettings(this);
25140
+ if (desc) return this;
25141
+ return cmd;
25142
+ }
25143
+ /**
25144
+ * Factory routine to create a new unattached command.
25145
+ *
25146
+ * See .command() for creating an attached subcommand, which uses this routine to
25147
+ * create the command. You can override createCommand to customise subcommands.
25148
+ *
25149
+ * @param {string} [name]
25150
+ * @return {Command} new command
25151
+ */
25152
+ createCommand(name) {
25153
+ return new Command(name);
25154
+ }
25155
+ /**
25156
+ * You can customise the help with a subclass of Help by overriding createHelp,
25157
+ * or by overriding Help properties using configureHelp().
25158
+ *
25159
+ * @return {Help}
25160
+ */
25161
+ createHelp() {
25162
+ return Object.assign(new Help(), this.configureHelp());
25163
+ }
25164
+ /**
25165
+ * You can customise the help by overriding Help properties using configureHelp(),
25166
+ * or with a subclass of Help by overriding createHelp().
25167
+ *
25168
+ * @param {object} [configuration] - configuration options
25169
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
25170
+ */
25171
+ configureHelp(configuration) {
25172
+ if (configuration === void 0) return this._helpConfiguration;
25173
+ this._helpConfiguration = configuration;
25174
+ return this;
25175
+ }
25176
+ /**
25177
+ * The default output goes to stdout and stderr. You can customise this for special
25178
+ * applications. You can also customise the display of errors by overriding outputError.
25179
+ *
25180
+ * The configuration properties are all functions:
25181
+ *
25182
+ * // change how output being written, defaults to stdout and stderr
25183
+ * writeOut(str)
25184
+ * writeErr(str)
25185
+ * // change how output being written for errors, defaults to writeErr
25186
+ * outputError(str, write) // used for displaying errors and not used for displaying help
25187
+ * // specify width for wrapping help
25188
+ * getOutHelpWidth()
25189
+ * getErrHelpWidth()
25190
+ * // color support, currently only used with Help
25191
+ * getOutHasColors()
25192
+ * getErrHasColors()
25193
+ * stripColor() // used to remove ANSI escape codes if output does not have colors
25194
+ *
25195
+ * @param {object} [configuration] - configuration options
25196
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
25197
+ */
25198
+ configureOutput(configuration) {
25199
+ if (configuration === void 0) return this._outputConfiguration;
25200
+ this._outputConfiguration = {
25201
+ ...this._outputConfiguration,
25202
+ ...configuration
25203
+ };
25204
+ return this;
25205
+ }
25206
+ /**
25207
+ * Display the help or a custom message after an error occurs.
25208
+ *
25209
+ * @param {(boolean|string)} [displayHelp]
25210
+ * @return {Command} `this` command for chaining
25211
+ */
25212
+ showHelpAfterError(displayHelp = true) {
25213
+ if (typeof displayHelp !== "string") displayHelp = !!displayHelp;
25214
+ this._showHelpAfterError = displayHelp;
25215
+ return this;
25216
+ }
25217
+ /**
25218
+ * Display suggestion of similar commands for unknown commands, or options for unknown options.
25219
+ *
25220
+ * @param {boolean} [displaySuggestion]
25221
+ * @return {Command} `this` command for chaining
25222
+ */
25223
+ showSuggestionAfterError(displaySuggestion = true) {
25224
+ this._showSuggestionAfterError = !!displaySuggestion;
25225
+ return this;
25226
+ }
25227
+ /**
25228
+ * Add a prepared subcommand.
25229
+ *
25230
+ * See .command() for creating an attached subcommand which inherits settings from its parent.
25231
+ *
25232
+ * @param {Command} cmd - new subcommand
25233
+ * @param {object} [opts] - configuration options
25234
+ * @return {Command} `this` command for chaining
25235
+ */
25236
+ addCommand(cmd, opts) {
25237
+ if (!cmd._name) throw new Error(`Command passed to .addCommand() must have a name
25238
+ - specify the name in Command constructor or using .name()`);
25239
+ opts = opts || {};
25240
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
25241
+ if (opts.noHelp || opts.hidden) cmd._hidden = true;
25242
+ this._registerCommand(cmd);
25243
+ cmd.parent = this;
25244
+ cmd._checkForBrokenPassThrough();
25245
+ return this;
25246
+ }
25247
+ /**
25248
+ * Factory routine to create a new unattached argument.
25249
+ *
25250
+ * See .argument() for creating an attached argument, which uses this routine to
25251
+ * create the argument. You can override createArgument to return a custom argument.
25252
+ *
25253
+ * @param {string} name
25254
+ * @param {string} [description]
25255
+ * @return {Argument} new argument
25256
+ */
25257
+ createArgument(name, description) {
25258
+ return new Argument(name, description);
25259
+ }
25260
+ /**
25261
+ * Define argument syntax for command.
25262
+ *
25263
+ * The default is that the argument is required, and you can explicitly
25264
+ * indicate this with <> around the name. Put [] around the name for an optional argument.
25265
+ *
25266
+ * @example
25267
+ * program.argument('<input-file>');
25268
+ * program.argument('[output-file]');
25269
+ *
25270
+ * @param {string} name
25271
+ * @param {string} [description]
25272
+ * @param {(Function|*)} [parseArg] - custom argument processing function or default value
25273
+ * @param {*} [defaultValue]
25274
+ * @return {Command} `this` command for chaining
25275
+ */
25276
+ argument(name, description, parseArg, defaultValue) {
25277
+ const argument = this.createArgument(name, description);
25278
+ if (typeof parseArg === "function") argument.default(defaultValue).argParser(parseArg);
25279
+ else argument.default(parseArg);
25280
+ this.addArgument(argument);
25281
+ return this;
25282
+ }
25283
+ /**
25284
+ * Define argument syntax for command, adding multiple at once (without descriptions).
25285
+ *
25286
+ * See also .argument().
25287
+ *
25288
+ * @example
25289
+ * program.arguments('<cmd> [env]');
25290
+ *
25291
+ * @param {string} names
25292
+ * @return {Command} `this` command for chaining
25293
+ */
25294
+ arguments(names) {
25295
+ names.trim().split(/ +/).forEach((detail) => {
25296
+ this.argument(detail);
25297
+ });
25298
+ return this;
25299
+ }
25300
+ /**
25301
+ * Define argument syntax for command, adding a prepared argument.
25302
+ *
25303
+ * @param {Argument} argument
25304
+ * @return {Command} `this` command for chaining
25305
+ */
25306
+ addArgument(argument) {
25307
+ const previousArgument = this.registeredArguments.slice(-1)[0];
25308
+ if (previousArgument?.variadic) throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
25309
+ if (argument.required && argument.defaultValue !== void 0 && argument.parseArg === void 0) throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
25310
+ this.registeredArguments.push(argument);
25311
+ return this;
25312
+ }
25313
+ /**
25314
+ * Customise or override default help command. By default a help command is automatically added if your command has subcommands.
25315
+ *
25316
+ * @example
25317
+ * program.helpCommand('help [cmd]');
25318
+ * program.helpCommand('help [cmd]', 'show help');
25319
+ * program.helpCommand(false); // suppress default help command
25320
+ * program.helpCommand(true); // add help command even if no subcommands
25321
+ *
25322
+ * @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
25323
+ * @param {string} [description] - custom description
25324
+ * @return {Command} `this` command for chaining
25325
+ */
25326
+ helpCommand(enableOrNameAndArgs, description) {
25327
+ if (typeof enableOrNameAndArgs === "boolean") {
25328
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
25329
+ if (enableOrNameAndArgs && this._defaultCommandGroup) this._initCommandGroup(this._getHelpCommand());
25330
+ return this;
25331
+ }
25332
+ const [, helpName, helpArgs] = (enableOrNameAndArgs ?? "help [command]").match(/([^ ]+) *(.*)/);
25333
+ const helpDescription = description ?? "display help for command";
25334
+ const helpCommand = this.createCommand(helpName);
25335
+ helpCommand.helpOption(false);
25336
+ if (helpArgs) helpCommand.arguments(helpArgs);
25337
+ if (helpDescription) helpCommand.description(helpDescription);
25338
+ this._addImplicitHelpCommand = true;
25339
+ this._helpCommand = helpCommand;
25340
+ if (enableOrNameAndArgs || description) this._initCommandGroup(helpCommand);
25341
+ return this;
25342
+ }
25343
+ /**
25344
+ * Add prepared custom help command.
25345
+ *
25346
+ * @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
25347
+ * @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
25348
+ * @return {Command} `this` command for chaining
25349
+ */
25350
+ addHelpCommand(helpCommand, deprecatedDescription) {
25351
+ if (typeof helpCommand !== "object") {
25352
+ this.helpCommand(helpCommand, deprecatedDescription);
25353
+ return this;
25354
+ }
25355
+ this._addImplicitHelpCommand = true;
25356
+ this._helpCommand = helpCommand;
25357
+ this._initCommandGroup(helpCommand);
25358
+ return this;
25359
+ }
25360
+ /**
25361
+ * Lazy create help command.
25362
+ *
25363
+ * @return {(Command|null)}
25364
+ * @package
25365
+ */
25366
+ _getHelpCommand() {
25367
+ if (this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"))) {
25368
+ if (this._helpCommand === void 0) this.helpCommand(void 0, void 0);
25369
+ return this._helpCommand;
25370
+ }
25371
+ return null;
25372
+ }
25373
+ /**
25374
+ * Add hook for life cycle event.
25375
+ *
25376
+ * @param {string} event
25377
+ * @param {Function} listener
25378
+ * @return {Command} `this` command for chaining
25379
+ */
25380
+ hook(event, listener) {
25381
+ const allowedValues = [
25382
+ "preSubcommand",
25383
+ "preAction",
25384
+ "postAction"
25385
+ ];
25386
+ if (!allowedValues.includes(event)) throw new Error(`Unexpected value for event passed to hook : '${event}'.
25387
+ Expecting one of '${allowedValues.join("', '")}'`);
25388
+ if (this._lifeCycleHooks[event]) this._lifeCycleHooks[event].push(listener);
25389
+ else this._lifeCycleHooks[event] = [listener];
25390
+ return this;
25391
+ }
25392
+ /**
25393
+ * Register callback to use as replacement for calling process.exit.
25394
+ *
25395
+ * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
25396
+ * @return {Command} `this` command for chaining
25397
+ */
25398
+ exitOverride(fn) {
25399
+ if (fn) this._exitCallback = fn;
25400
+ else this._exitCallback = (err) => {
25401
+ if (err.code !== "commander.executeSubCommandAsync") throw err;
25402
+ };
25403
+ return this;
25404
+ }
25405
+ /**
25406
+ * Call process.exit, and _exitCallback if defined.
25407
+ *
25408
+ * @param {number} exitCode exit code for using with process.exit
25409
+ * @param {string} code an id string representing the error
25410
+ * @param {string} message human-readable description of the error
25411
+ * @return never
25412
+ * @private
25413
+ */
25414
+ _exit(exitCode, code, message) {
25415
+ if (this._exitCallback) this._exitCallback(new CommanderError(exitCode, code, message));
25416
+ process$2.exit(exitCode);
25417
+ }
25418
+ /**
25419
+ * Register callback `fn` for the command.
25420
+ *
25421
+ * @example
25422
+ * program
25423
+ * .command('serve')
25424
+ * .description('start service')
25425
+ * .action(function() {
25426
+ * // do work here
25427
+ * });
25428
+ *
25429
+ * @param {Function} fn
25430
+ * @return {Command} `this` command for chaining
25431
+ */
25432
+ action(fn) {
25433
+ const listener = (args) => {
25434
+ const expectedArgsCount = this.registeredArguments.length;
25435
+ const actionArgs = args.slice(0, expectedArgsCount);
25436
+ if (this._storeOptionsAsProperties) actionArgs[expectedArgsCount] = this;
25437
+ else actionArgs[expectedArgsCount] = this.opts();
25438
+ actionArgs.push(this);
25439
+ return fn.apply(this, actionArgs);
25440
+ };
25441
+ this._actionHandler = listener;
25442
+ return this;
25443
+ }
25444
+ /**
25445
+ * Factory routine to create a new unattached option.
25446
+ *
25447
+ * See .option() for creating an attached option, which uses this routine to
25448
+ * create the option. You can override createOption to return a custom option.
25449
+ *
25450
+ * @param {string} flags
25451
+ * @param {string} [description]
25452
+ * @return {Option} new option
25453
+ */
25454
+ createOption(flags, description) {
25455
+ return new Option(flags, description);
25456
+ }
25457
+ /**
25458
+ * Wrap parseArgs to catch 'commander.invalidArgument'.
25459
+ *
25460
+ * @param {(Option | Argument)} target
25461
+ * @param {string} value
25462
+ * @param {*} previous
25463
+ * @param {string} invalidArgumentMessage
25464
+ * @private
25465
+ */
25466
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
25467
+ try {
25468
+ return target.parseArg(value, previous);
25469
+ } catch (err) {
25470
+ if (err.code === "commander.invalidArgument") {
25471
+ const message = `${invalidArgumentMessage} ${err.message}`;
25472
+ this.error(message, {
25473
+ exitCode: err.exitCode,
25474
+ code: err.code
25475
+ });
25476
+ }
25477
+ throw err;
25478
+ }
25479
+ }
25480
+ /**
25481
+ * Check for option flag conflicts.
25482
+ * Register option if no conflicts found, or throw on conflict.
25483
+ *
25484
+ * @param {Option} option
25485
+ * @private
25486
+ */
25487
+ _registerOption(option) {
25488
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
25489
+ if (matchingOption) {
25490
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
25491
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
25492
+ - already used by option '${matchingOption.flags}'`);
25493
+ }
25494
+ this._initOptionGroup(option);
25495
+ this.options.push(option);
25496
+ }
25497
+ /**
25498
+ * Check for command name and alias conflicts with existing commands.
25499
+ * Register command if no conflicts found, or throw on conflict.
25500
+ *
25501
+ * @param {Command} command
25502
+ * @private
25503
+ */
25504
+ _registerCommand(command) {
25505
+ const knownBy = (cmd) => {
25506
+ return [cmd.name()].concat(cmd.aliases());
25507
+ };
25508
+ const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
25509
+ if (alreadyUsed) {
25510
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
25511
+ const newCmd = knownBy(command).join("|");
25512
+ throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
25513
+ }
25514
+ this._initCommandGroup(command);
25515
+ this.commands.push(command);
25516
+ }
25517
+ /**
25518
+ * Add an option.
25519
+ *
25520
+ * @param {Option} option
25521
+ * @return {Command} `this` command for chaining
25522
+ */
25523
+ addOption(option) {
25524
+ this._registerOption(option);
25525
+ const oname = option.name();
25526
+ const name = option.attributeName();
25527
+ if (option.negate) {
25528
+ const positiveLongFlag = option.long.replace(/^--no-/, "--");
25529
+ if (!this._findOption(positiveLongFlag)) this.setOptionValueWithSource(name, option.defaultValue === void 0 ? true : option.defaultValue, "default");
25530
+ } else if (option.defaultValue !== void 0) this.setOptionValueWithSource(name, option.defaultValue, "default");
25531
+ const handleOptionValue = (val, invalidValueMessage, valueSource) => {
25532
+ if (val == null && option.presetArg !== void 0) val = option.presetArg;
25533
+ const oldValue = this.getOptionValue(name);
25534
+ if (val !== null && option.parseArg) val = this._callParseArg(option, val, oldValue, invalidValueMessage);
25535
+ else if (val !== null && option.variadic) val = option._collectValue(val, oldValue);
25536
+ if (val == null) if (option.negate) val = false;
25537
+ else if (option.isBoolean() || option.optional) val = true;
25538
+ else val = "";
25539
+ this.setOptionValueWithSource(name, val, valueSource);
25540
+ };
25541
+ this.on("option:" + oname, (val) => {
25542
+ handleOptionValue(val, `error: option '${option.flags}' argument '${val}' is invalid.`, "cli");
25543
+ });
25544
+ if (option.envVar) this.on("optionEnv:" + oname, (val) => {
25545
+ handleOptionValue(val, `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`, "env");
25546
+ });
25547
+ return this;
25548
+ }
25549
+ /**
25550
+ * Internal implementation shared by .option() and .requiredOption()
25551
+ *
25552
+ * @return {Command} `this` command for chaining
25553
+ * @private
25554
+ */
25555
+ _optionEx(config, flags, description, fn, defaultValue) {
25556
+ if (typeof flags === "object" && flags instanceof Option) throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
25557
+ const option = this.createOption(flags, description);
25558
+ option.makeOptionMandatory(!!config.mandatory);
25559
+ if (typeof fn === "function") option.default(defaultValue).argParser(fn);
25560
+ else if (fn instanceof RegExp) {
25561
+ const regex = fn;
25562
+ fn = (val, def) => {
25563
+ const m = regex.exec(val);
25564
+ return m ? m[0] : def;
25565
+ };
25566
+ option.default(defaultValue).argParser(fn);
25567
+ } else option.default(fn);
25568
+ return this.addOption(option);
25569
+ }
25570
+ /**
25571
+ * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
25572
+ *
25573
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
25574
+ * option-argument is indicated by `<>` and an optional option-argument by `[]`.
25575
+ *
25576
+ * See the README for more details, and see also addOption() and requiredOption().
25577
+ *
25578
+ * @example
25579
+ * program
25580
+ * .option('-p, --pepper', 'add pepper')
25581
+ * .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
25582
+ * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
25583
+ * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
25584
+ *
25585
+ * @param {string} flags
25586
+ * @param {string} [description]
25587
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
25588
+ * @param {*} [defaultValue]
25589
+ * @return {Command} `this` command for chaining
25590
+ */
25591
+ option(flags, description, parseArg, defaultValue) {
25592
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
25593
+ }
25594
+ /**
25595
+ * Add a required option which must have a value after parsing. This usually means
25596
+ * the option must be specified on the command line. (Otherwise the same as .option().)
25597
+ *
25598
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
25599
+ *
25600
+ * @param {string} flags
25601
+ * @param {string} [description]
25602
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
25603
+ * @param {*} [defaultValue]
25604
+ * @return {Command} `this` command for chaining
25605
+ */
25606
+ requiredOption(flags, description, parseArg, defaultValue) {
25607
+ return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
25608
+ }
25609
+ /**
25610
+ * Alter parsing of short flags with optional values.
25611
+ *
25612
+ * @example
25613
+ * // for `.option('-f,--flag [value]'):
25614
+ * program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
25615
+ * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
25616
+ *
25617
+ * @param {boolean} [combine] - if `true` or omitted, an optional value can be specified directly after the flag.
25618
+ * @return {Command} `this` command for chaining
25619
+ */
25620
+ combineFlagAndOptionalValue(combine = true) {
25621
+ this._combineFlagAndOptionalValue = !!combine;
25622
+ return this;
25623
+ }
25624
+ /**
25625
+ * Allow unknown options on the command line.
25626
+ *
25627
+ * @param {boolean} [allowUnknown] - if `true` or omitted, no error will be thrown for unknown options.
25628
+ * @return {Command} `this` command for chaining
25629
+ */
25630
+ allowUnknownOption(allowUnknown = true) {
25631
+ this._allowUnknownOption = !!allowUnknown;
25632
+ return this;
25633
+ }
25634
+ /**
25635
+ * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
25636
+ *
25637
+ * @param {boolean} [allowExcess] - if `true` or omitted, no error will be thrown for excess arguments.
25638
+ * @return {Command} `this` command for chaining
25639
+ */
25640
+ allowExcessArguments(allowExcess = true) {
25641
+ this._allowExcessArguments = !!allowExcess;
25642
+ return this;
25643
+ }
25644
+ /**
25645
+ * Enable positional options. Positional means global options are specified before subcommands which lets
25646
+ * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
25647
+ * The default behaviour is non-positional and global options may appear anywhere on the command line.
25648
+ *
25649
+ * @param {boolean} [positional]
25650
+ * @return {Command} `this` command for chaining
25651
+ */
25652
+ enablePositionalOptions(positional = true) {
25653
+ this._enablePositionalOptions = !!positional;
25654
+ return this;
25655
+ }
25656
+ /**
25657
+ * Pass through options that come after command-arguments rather than treat them as command-options,
25658
+ * so actual command-options come before command-arguments. Turning this on for a subcommand requires
25659
+ * positional options to have been enabled on the program (parent commands).
25660
+ * The default behaviour is non-positional and options may appear before or after command-arguments.
25661
+ *
25662
+ * @param {boolean} [passThrough] for unknown options.
25663
+ * @return {Command} `this` command for chaining
25664
+ */
25665
+ passThroughOptions(passThrough = true) {
25666
+ this._passThroughOptions = !!passThrough;
25667
+ this._checkForBrokenPassThrough();
25668
+ return this;
25669
+ }
25670
+ /**
25671
+ * @private
25672
+ */
25673
+ _checkForBrokenPassThrough() {
25674
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
25675
+ }
25676
+ /**
25677
+ * Whether to store option values as properties on command object,
25678
+ * or store separately (specify false). In both cases the option values can be accessed using .opts().
25679
+ *
25680
+ * @param {boolean} [storeAsProperties=true]
25681
+ * @return {Command} `this` command for chaining
25682
+ */
25683
+ storeOptionsAsProperties(storeAsProperties = true) {
25684
+ if (this.options.length) throw new Error("call .storeOptionsAsProperties() before adding options");
25685
+ if (Object.keys(this._optionValues).length) throw new Error("call .storeOptionsAsProperties() before setting option values");
25686
+ this._storeOptionsAsProperties = !!storeAsProperties;
25687
+ return this;
25688
+ }
25689
+ /**
25690
+ * Retrieve option value.
25691
+ *
25692
+ * @param {string} key
25693
+ * @return {object} value
25694
+ */
25695
+ getOptionValue(key) {
25696
+ if (this._storeOptionsAsProperties) return this[key];
25697
+ return this._optionValues[key];
25698
+ }
25699
+ /**
25700
+ * Store option value.
25701
+ *
25702
+ * @param {string} key
25703
+ * @param {object} value
25704
+ * @return {Command} `this` command for chaining
25705
+ */
25706
+ setOptionValue(key, value) {
25707
+ return this.setOptionValueWithSource(key, value, void 0);
25708
+ }
25709
+ /**
25710
+ * Store option value and where the value came from.
25711
+ *
25712
+ * @param {string} key
25713
+ * @param {object} value
25714
+ * @param {string} source - expected values are default/config/env/cli/implied
25715
+ * @return {Command} `this` command for chaining
25716
+ */
25717
+ setOptionValueWithSource(key, value, source) {
25718
+ if (this._storeOptionsAsProperties) this[key] = value;
25719
+ else this._optionValues[key] = value;
25720
+ this._optionValueSources[key] = source;
25721
+ return this;
25722
+ }
25723
+ /**
25724
+ * Get source of option value.
25725
+ * Expected values are default | config | env | cli | implied
25726
+ *
25727
+ * @param {string} key
25728
+ * @return {string}
25729
+ */
25730
+ getOptionValueSource(key) {
25731
+ return this._optionValueSources[key];
25732
+ }
25733
+ /**
25734
+ * Get source of option value. See also .optsWithGlobals().
25735
+ * Expected values are default | config | env | cli | implied
25736
+ *
25737
+ * @param {string} key
25738
+ * @return {string}
25739
+ */
25740
+ getOptionValueSourceWithGlobals(key) {
25741
+ let source;
25742
+ this._getCommandAndAncestors().forEach((cmd) => {
25743
+ if (cmd.getOptionValueSource(key) !== void 0) source = cmd.getOptionValueSource(key);
25744
+ });
25745
+ return source;
25746
+ }
25747
+ /**
25748
+ * Get user arguments from implied or explicit arguments.
25749
+ * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
25750
+ *
25751
+ * @private
25752
+ */
25753
+ _prepareUserArgs(argv, parseOptions) {
25754
+ if (argv !== void 0 && !Array.isArray(argv)) throw new Error("first parameter to parse must be array or undefined");
25755
+ parseOptions = parseOptions || {};
25756
+ if (argv === void 0 && parseOptions.from === void 0) {
25757
+ if (process$2.versions?.electron) parseOptions.from = "electron";
25758
+ const execArgv = process$2.execArgv ?? [];
25759
+ if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) parseOptions.from = "eval";
25760
+ }
25761
+ if (argv === void 0) argv = process$2.argv;
25762
+ this.rawArgs = argv.slice();
25763
+ let userArgs;
25764
+ switch (parseOptions.from) {
25765
+ case void 0:
25766
+ case "node":
25767
+ this._scriptPath = argv[1];
25768
+ userArgs = argv.slice(2);
25769
+ break;
25770
+ case "electron":
25771
+ if (process$2.defaultApp) {
25772
+ this._scriptPath = argv[1];
25773
+ userArgs = argv.slice(2);
25774
+ } else userArgs = argv.slice(1);
25775
+ break;
25776
+ case "user":
25777
+ userArgs = argv.slice(0);
25778
+ break;
25779
+ case "eval":
25780
+ userArgs = argv.slice(1);
25781
+ break;
25782
+ default: throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
25783
+ }
25784
+ if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
25785
+ this._name = this._name || "program";
25786
+ return userArgs;
25787
+ }
25788
+ /**
25789
+ * Parse `argv`, setting options and invoking commands when defined.
25790
+ *
25791
+ * Use parseAsync instead of parse if any of your action handlers are async.
25792
+ *
25793
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
25794
+ *
25795
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
25796
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
25797
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
25798
+ * - `'user'`: just user arguments
25799
+ *
25800
+ * @example
25801
+ * program.parse(); // parse process.argv and auto-detect electron and special node flags
25802
+ * program.parse(process.argv); // assume argv[0] is app and argv[1] is script
25803
+ * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
25804
+ *
25805
+ * @param {string[]} [argv] - optional, defaults to process.argv
25806
+ * @param {object} [parseOptions] - optionally specify style of options with from: node/user/electron
25807
+ * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
25808
+ * @return {Command} `this` command for chaining
25809
+ */
25810
+ parse(argv, parseOptions) {
25811
+ this._prepareForParse();
25812
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
25813
+ this._parseCommand([], userArgs);
25814
+ return this;
25815
+ }
25816
+ /**
25817
+ * Parse `argv`, setting options and invoking commands when defined.
25818
+ *
25819
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
25820
+ *
25821
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
25822
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
25823
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
25824
+ * - `'user'`: just user arguments
25825
+ *
25826
+ * @example
25827
+ * await program.parseAsync(); // parse process.argv and auto-detect electron and special node flags
25828
+ * await program.parseAsync(process.argv); // assume argv[0] is app and argv[1] is script
25829
+ * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
25830
+ *
25831
+ * @param {string[]} [argv]
25832
+ * @param {object} [parseOptions]
25833
+ * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
25834
+ * @return {Promise}
25835
+ */
25836
+ async parseAsync(argv, parseOptions) {
25837
+ this._prepareForParse();
25838
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
25839
+ await this._parseCommand([], userArgs);
25840
+ return this;
25841
+ }
25842
+ _prepareForParse() {
25843
+ if (this._savedState === null) this.saveStateBeforeParse();
25844
+ else this.restoreStateBeforeParse();
25845
+ }
25846
+ /**
25847
+ * Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
25848
+ * Not usually called directly, but available for subclasses to save their custom state.
25849
+ *
25850
+ * This is called in a lazy way. Only commands used in parsing chain will have state saved.
25851
+ */
25852
+ saveStateBeforeParse() {
25853
+ this._savedState = {
25854
+ _name: this._name,
25855
+ _optionValues: { ...this._optionValues },
25856
+ _optionValueSources: { ...this._optionValueSources }
25857
+ };
25858
+ }
25859
+ /**
25860
+ * Restore state before parse for calls after the first.
25861
+ * Not usually called directly, but available for subclasses to save their custom state.
25862
+ *
25863
+ * This is called in a lazy way. Only commands used in parsing chain will have state restored.
25864
+ */
25865
+ restoreStateBeforeParse() {
25866
+ if (this._storeOptionsAsProperties) throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
25867
+ - either make a new Command for each call to parse, or stop storing options as properties`);
25868
+ this._name = this._savedState._name;
25869
+ this._scriptPath = null;
25870
+ this.rawArgs = [];
25871
+ this._optionValues = { ...this._savedState._optionValues };
25872
+ this._optionValueSources = { ...this._savedState._optionValueSources };
25873
+ this.args = [];
25874
+ this.processedArgs = [];
25875
+ }
25876
+ /**
25877
+ * Throw if expected executable is missing. Add lots of help for author.
25878
+ *
25879
+ * @param {string} executableFile
25880
+ * @param {string} executableDir
25881
+ * @param {string} subcommandName
25882
+ */
25883
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
25884
+ if (fs.existsSync(executableFile)) return;
25885
+ const executableMissing = `'${executableFile}' does not exist
25886
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
25887
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
25888
+ - ${executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory"}`;
25889
+ throw new Error(executableMissing);
25890
+ }
25891
+ /**
25892
+ * Execute a sub-command executable.
25893
+ *
25894
+ * @private
25895
+ */
25896
+ _executeSubCommand(subcommand, args) {
25897
+ args = args.slice();
25898
+ let launchWithNode = false;
25899
+ const sourceExt = [
25900
+ ".js",
25901
+ ".ts",
25902
+ ".tsx",
25903
+ ".mjs",
25904
+ ".cjs"
25905
+ ];
25906
+ function findFile(baseDir, baseName) {
25907
+ const localBin = path.resolve(baseDir, baseName);
25908
+ if (fs.existsSync(localBin)) return localBin;
25909
+ if (sourceExt.includes(path.extname(baseName))) return void 0;
25910
+ const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
25911
+ if (foundExt) return `${localBin}${foundExt}`;
25912
+ }
25913
+ this._checkForMissingMandatoryOptions();
25914
+ this._checkForConflictingOptions();
25915
+ let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
25916
+ let executableDir = this._executableDir || "";
25917
+ if (this._scriptPath) {
25918
+ let resolvedScriptPath;
25919
+ try {
25920
+ resolvedScriptPath = fs.realpathSync(this._scriptPath);
25921
+ } catch {
25922
+ resolvedScriptPath = this._scriptPath;
25923
+ }
25924
+ executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
25925
+ }
25926
+ if (executableDir) {
25927
+ let localFile = findFile(executableDir, executableFile);
25928
+ if (!localFile && !subcommand._executableFile && this._scriptPath) {
25929
+ const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
25930
+ if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
25931
+ }
25932
+ executableFile = localFile || executableFile;
25933
+ }
25934
+ launchWithNode = sourceExt.includes(path.extname(executableFile));
25935
+ let proc;
25936
+ if (process$2.platform !== "win32") if (launchWithNode) {
25937
+ args.unshift(executableFile);
25938
+ args = incrementNodeInspectorPort(process$2.execArgv).concat(args);
25939
+ proc = childProcess.spawn(process$2.argv[0], args, { stdio: "inherit" });
25940
+ } else proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
25941
+ else {
25942
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
25943
+ args.unshift(executableFile);
25944
+ args = incrementNodeInspectorPort(process$2.execArgv).concat(args);
25945
+ proc = childProcess.spawn(process$2.execPath, args, { stdio: "inherit" });
25946
+ }
25947
+ if (!proc.killed) [
25948
+ "SIGUSR1",
25949
+ "SIGUSR2",
25950
+ "SIGTERM",
25951
+ "SIGINT",
25952
+ "SIGHUP"
25953
+ ].forEach((signal) => {
25954
+ process$2.on(signal, () => {
25955
+ if (proc.killed === false && proc.exitCode === null) proc.kill(signal);
25956
+ });
25957
+ });
25958
+ const exitCallback = this._exitCallback;
25959
+ proc.on("close", (code) => {
25960
+ code = code ?? 1;
25961
+ if (!exitCallback) process$2.exit(code);
25962
+ else exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
25963
+ });
25964
+ proc.on("error", (err) => {
25965
+ if (err.code === "ENOENT") this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
25966
+ else if (err.code === "EACCES") throw new Error(`'${executableFile}' not executable`);
25967
+ if (!exitCallback) process$2.exit(1);
25968
+ else {
25969
+ const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
25970
+ wrappedError.nestedError = err;
25971
+ exitCallback(wrappedError);
25972
+ }
25973
+ });
25974
+ this.runningCommand = proc;
25975
+ }
25976
+ /**
25977
+ * @private
25978
+ */
25979
+ _dispatchSubcommand(commandName, operands, unknown) {
25980
+ const subCommand = this._findCommand(commandName);
25981
+ if (!subCommand) this.help({ error: true });
25982
+ subCommand._prepareForParse();
25983
+ let promiseChain;
25984
+ promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
25985
+ promiseChain = this._chainOrCall(promiseChain, () => {
25986
+ if (subCommand._executableHandler) this._executeSubCommand(subCommand, operands.concat(unknown));
25987
+ else return subCommand._parseCommand(operands, unknown);
25988
+ });
25989
+ return promiseChain;
25990
+ }
25991
+ /**
25992
+ * Invoke help directly if possible, or dispatch if necessary.
25993
+ * e.g. help foo
25994
+ *
25995
+ * @private
25996
+ */
25997
+ _dispatchHelpCommand(subcommandName) {
25998
+ if (!subcommandName) this.help();
25999
+ const subCommand = this._findCommand(subcommandName);
26000
+ if (subCommand && !subCommand._executableHandler) subCommand.help();
26001
+ return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
26002
+ }
26003
+ /**
26004
+ * Check this.args against expected this.registeredArguments.
26005
+ *
26006
+ * @private
26007
+ */
26008
+ _checkNumberOfArguments() {
26009
+ this.registeredArguments.forEach((arg, i) => {
26010
+ if (arg.required && this.args[i] == null) this.missingArgument(arg.name());
26011
+ });
26012
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) return;
26013
+ if (this.args.length > this.registeredArguments.length) this._excessArguments(this.args);
26014
+ }
26015
+ /**
26016
+ * Process this.args using this.registeredArguments and save as this.processedArgs!
26017
+ *
26018
+ * @private
26019
+ */
26020
+ _processArguments() {
26021
+ const myParseArg = (argument, value, previous) => {
26022
+ let parsedValue = value;
26023
+ if (value !== null && argument.parseArg) {
26024
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
26025
+ parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
26026
+ }
26027
+ return parsedValue;
26028
+ };
26029
+ this._checkNumberOfArguments();
26030
+ const processedArgs = [];
26031
+ this.registeredArguments.forEach((declaredArg, index) => {
26032
+ let value = declaredArg.defaultValue;
26033
+ if (declaredArg.variadic) {
26034
+ if (index < this.args.length) {
26035
+ value = this.args.slice(index);
26036
+ if (declaredArg.parseArg) value = value.reduce((processed, v) => {
26037
+ return myParseArg(declaredArg, v, processed);
26038
+ }, declaredArg.defaultValue);
26039
+ } else if (value === void 0) value = [];
26040
+ } else if (index < this.args.length) {
26041
+ value = this.args[index];
26042
+ if (declaredArg.parseArg) value = myParseArg(declaredArg, value, declaredArg.defaultValue);
26043
+ }
26044
+ processedArgs[index] = value;
26045
+ });
26046
+ this.processedArgs = processedArgs;
26047
+ }
26048
+ /**
26049
+ * Once we have a promise we chain, but call synchronously until then.
26050
+ *
26051
+ * @param {(Promise|undefined)} promise
26052
+ * @param {Function} fn
26053
+ * @return {(Promise|undefined)}
26054
+ * @private
26055
+ */
26056
+ _chainOrCall(promise, fn) {
26057
+ if (promise?.then && typeof promise.then === "function") return promise.then(() => fn());
26058
+ return fn();
26059
+ }
26060
+ /**
26061
+ *
26062
+ * @param {(Promise|undefined)} promise
26063
+ * @param {string} event
26064
+ * @return {(Promise|undefined)}
26065
+ * @private
26066
+ */
26067
+ _chainOrCallHooks(promise, event) {
26068
+ let result = promise;
26069
+ const hooks = [];
26070
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
26071
+ hookedCommand._lifeCycleHooks[event].forEach((callback) => {
26072
+ hooks.push({
26073
+ hookedCommand,
26074
+ callback
26075
+ });
26076
+ });
26077
+ });
26078
+ if (event === "postAction") hooks.reverse();
26079
+ hooks.forEach((hookDetail) => {
26080
+ result = this._chainOrCall(result, () => {
26081
+ return hookDetail.callback(hookDetail.hookedCommand, this);
26082
+ });
26083
+ });
26084
+ return result;
26085
+ }
26086
+ /**
26087
+ *
26088
+ * @param {(Promise|undefined)} promise
26089
+ * @param {Command} subCommand
26090
+ * @param {string} event
26091
+ * @return {(Promise|undefined)}
26092
+ * @private
26093
+ */
26094
+ _chainOrCallSubCommandHook(promise, subCommand, event) {
26095
+ let result = promise;
26096
+ if (this._lifeCycleHooks[event] !== void 0) this._lifeCycleHooks[event].forEach((hook) => {
26097
+ result = this._chainOrCall(result, () => {
26098
+ return hook(this, subCommand);
26099
+ });
26100
+ });
26101
+ return result;
26102
+ }
26103
+ /**
26104
+ * Process arguments in context of this command.
26105
+ * Returns action result, in case it is a promise.
26106
+ *
26107
+ * @private
26108
+ */
26109
+ _parseCommand(operands, unknown) {
26110
+ const parsed = this.parseOptions(unknown);
26111
+ this._parseOptionsEnv();
26112
+ this._parseOptionsImplied();
26113
+ operands = operands.concat(parsed.operands);
26114
+ unknown = parsed.unknown;
26115
+ this.args = operands.concat(unknown);
26116
+ if (operands && this._findCommand(operands[0])) return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
26117
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) return this._dispatchHelpCommand(operands[1]);
26118
+ if (this._defaultCommandName) {
26119
+ this._outputHelpIfRequested(unknown);
26120
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
26121
+ }
26122
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) this.help({ error: true });
26123
+ this._outputHelpIfRequested(parsed.unknown);
26124
+ this._checkForMissingMandatoryOptions();
26125
+ this._checkForConflictingOptions();
26126
+ const checkForUnknownOptions = () => {
26127
+ if (parsed.unknown.length > 0) this.unknownOption(parsed.unknown[0]);
26128
+ };
26129
+ const commandEvent = `command:${this.name()}`;
26130
+ if (this._actionHandler) {
26131
+ checkForUnknownOptions();
26132
+ this._processArguments();
26133
+ let promiseChain;
26134
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
26135
+ promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
26136
+ if (this.parent) promiseChain = this._chainOrCall(promiseChain, () => {
26137
+ this.parent.emit(commandEvent, operands, unknown);
26138
+ });
26139
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
26140
+ return promiseChain;
26141
+ }
26142
+ if (this.parent?.listenerCount(commandEvent)) {
26143
+ checkForUnknownOptions();
26144
+ this._processArguments();
26145
+ this.parent.emit(commandEvent, operands, unknown);
26146
+ } else if (operands.length) {
26147
+ if (this._findCommand("*")) return this._dispatchSubcommand("*", operands, unknown);
26148
+ if (this.listenerCount("command:*")) this.emit("command:*", operands, unknown);
26149
+ else if (this.commands.length) this.unknownCommand();
26150
+ else {
26151
+ checkForUnknownOptions();
26152
+ this._processArguments();
26153
+ }
26154
+ } else if (this.commands.length) {
26155
+ checkForUnknownOptions();
26156
+ this.help({ error: true });
26157
+ } else {
26158
+ checkForUnknownOptions();
26159
+ this._processArguments();
26160
+ }
26161
+ }
26162
+ /**
26163
+ * Find matching command.
26164
+ *
26165
+ * @private
26166
+ * @return {Command | undefined}
26167
+ */
26168
+ _findCommand(name) {
26169
+ if (!name) return void 0;
26170
+ return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
26171
+ }
26172
+ /**
26173
+ * Return an option matching `arg` if any.
26174
+ *
26175
+ * @param {string} arg
26176
+ * @return {Option}
26177
+ * @package
26178
+ */
26179
+ _findOption(arg) {
26180
+ return this.options.find((option) => option.is(arg));
26181
+ }
26182
+ /**
26183
+ * Display an error message if a mandatory option does not have a value.
26184
+ * Called after checking for help flags in leaf subcommand.
26185
+ *
26186
+ * @private
26187
+ */
26188
+ _checkForMissingMandatoryOptions() {
26189
+ this._getCommandAndAncestors().forEach((cmd) => {
26190
+ cmd.options.forEach((anOption) => {
26191
+ if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === void 0) cmd.missingMandatoryOptionValue(anOption);
26192
+ });
26193
+ });
26194
+ }
26195
+ /**
26196
+ * Display an error message if conflicting options are used together in this.
26197
+ *
26198
+ * @private
26199
+ */
26200
+ _checkForConflictingLocalOptions() {
26201
+ const definedNonDefaultOptions = this.options.filter((option) => {
26202
+ const optionKey = option.attributeName();
26203
+ if (this.getOptionValue(optionKey) === void 0) return false;
26204
+ return this.getOptionValueSource(optionKey) !== "default";
26205
+ });
26206
+ definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0).forEach((option) => {
26207
+ const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
26208
+ if (conflictingAndDefined) this._conflictingOption(option, conflictingAndDefined);
26209
+ });
26210
+ }
26211
+ /**
26212
+ * Display an error message if conflicting options are used together.
26213
+ * Called after checking for help flags in leaf subcommand.
26214
+ *
26215
+ * @private
26216
+ */
26217
+ _checkForConflictingOptions() {
26218
+ this._getCommandAndAncestors().forEach((cmd) => {
26219
+ cmd._checkForConflictingLocalOptions();
26220
+ });
26221
+ }
26222
+ /**
26223
+ * Parse options from `argv` removing known options,
26224
+ * and return argv split into operands and unknown arguments.
26225
+ *
26226
+ * Side effects: modifies command by storing options. Does not reset state if called again.
26227
+ *
26228
+ * Examples:
26229
+ *
26230
+ * argv => operands, unknown
26231
+ * --known kkk op => [op], []
26232
+ * op --known kkk => [op], []
26233
+ * sub --unknown uuu op => [sub], [--unknown uuu op]
26234
+ * sub -- --unknown uuu op => [sub --unknown uuu op], []
26235
+ *
26236
+ * @param {string[]} args
26237
+ * @return {{operands: string[], unknown: string[]}}
26238
+ */
26239
+ parseOptions(args) {
26240
+ const operands = [];
26241
+ const unknown = [];
26242
+ let dest = operands;
26243
+ function maybeOption(arg) {
26244
+ return arg.length > 1 && arg[0] === "-";
26245
+ }
26246
+ const negativeNumberArg = (arg) => {
26247
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)) return false;
26248
+ return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
26249
+ };
26250
+ let activeVariadicOption = null;
26251
+ let activeGroup = null;
26252
+ let i = 0;
26253
+ while (i < args.length || activeGroup) {
26254
+ const arg = activeGroup ?? args[i++];
26255
+ activeGroup = null;
26256
+ if (arg === "--") {
26257
+ if (dest === unknown) dest.push(arg);
26258
+ dest.push(...args.slice(i));
26259
+ break;
26260
+ }
26261
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
26262
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
26263
+ continue;
26264
+ }
26265
+ activeVariadicOption = null;
26266
+ if (maybeOption(arg)) {
26267
+ const option = this._findOption(arg);
26268
+ if (option) {
26269
+ if (option.required) {
26270
+ const value = args[i++];
26271
+ if (value === void 0) this.optionMissingArgument(option);
26272
+ this.emit(`option:${option.name()}`, value);
26273
+ } else if (option.optional) {
26274
+ let value = null;
26275
+ if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) value = args[i++];
26276
+ this.emit(`option:${option.name()}`, value);
26277
+ } else this.emit(`option:${option.name()}`);
26278
+ activeVariadicOption = option.variadic ? option : null;
26279
+ continue;
26280
+ }
26281
+ }
26282
+ if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
26283
+ const option = this._findOption(`-${arg[1]}`);
26284
+ if (option) {
26285
+ if (option.required || option.optional && this._combineFlagAndOptionalValue) this.emit(`option:${option.name()}`, arg.slice(2));
26286
+ else {
26287
+ this.emit(`option:${option.name()}`);
26288
+ activeGroup = `-${arg.slice(2)}`;
26289
+ }
26290
+ continue;
26291
+ }
26292
+ }
26293
+ if (/^--[^=]+=/.test(arg)) {
26294
+ const index = arg.indexOf("=");
26295
+ const option = this._findOption(arg.slice(0, index));
26296
+ if (option && (option.required || option.optional)) {
26297
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
26298
+ continue;
26299
+ }
26300
+ }
26301
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) dest = unknown;
26302
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
26303
+ if (this._findCommand(arg)) {
26304
+ operands.push(arg);
26305
+ unknown.push(...args.slice(i));
26306
+ break;
26307
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
26308
+ operands.push(arg, ...args.slice(i));
26309
+ break;
26310
+ } else if (this._defaultCommandName) {
26311
+ unknown.push(arg, ...args.slice(i));
26312
+ break;
26313
+ }
26314
+ }
26315
+ if (this._passThroughOptions) {
26316
+ dest.push(arg, ...args.slice(i));
26317
+ break;
26318
+ }
26319
+ dest.push(arg);
26320
+ }
26321
+ return {
26322
+ operands,
26323
+ unknown
26324
+ };
26325
+ }
26326
+ /**
26327
+ * Return an object containing local option values as key-value pairs.
26328
+ *
26329
+ * @return {object}
26330
+ */
26331
+ opts() {
26332
+ if (this._storeOptionsAsProperties) {
26333
+ const result = {};
26334
+ const len = this.options.length;
26335
+ for (let i = 0; i < len; i++) {
26336
+ const key = this.options[i].attributeName();
26337
+ result[key] = key === this._versionOptionName ? this._version : this[key];
26338
+ }
26339
+ return result;
26340
+ }
26341
+ return this._optionValues;
26342
+ }
26343
+ /**
26344
+ * Return an object containing merged local and global option values as key-value pairs.
26345
+ *
26346
+ * @return {object}
26347
+ */
26348
+ optsWithGlobals() {
26349
+ return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
26350
+ }
26351
+ /**
26352
+ * Display error message and exit (or call exitOverride).
26353
+ *
26354
+ * @param {string} message
26355
+ * @param {object} [errorOptions]
26356
+ * @param {string} [errorOptions.code] - an id string representing the error
26357
+ * @param {number} [errorOptions.exitCode] - used with process.exit
26358
+ */
26359
+ error(message, errorOptions) {
26360
+ this._outputConfiguration.outputError(`${message}\n`, this._outputConfiguration.writeErr);
26361
+ if (typeof this._showHelpAfterError === "string") this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`);
26362
+ else if (this._showHelpAfterError) {
26363
+ this._outputConfiguration.writeErr("\n");
26364
+ this.outputHelp({ error: true });
26365
+ }
26366
+ const config = errorOptions || {};
26367
+ const exitCode = config.exitCode || 1;
26368
+ const code = config.code || "commander.error";
26369
+ this._exit(exitCode, code, message);
26370
+ }
26371
+ /**
26372
+ * Apply any option related environment variables, if option does
26373
+ * not have a value from cli or client code.
26374
+ *
26375
+ * @private
26376
+ */
26377
+ _parseOptionsEnv() {
26378
+ this.options.forEach((option) => {
26379
+ if (option.envVar && option.envVar in process$2.env) {
26380
+ const optionKey = option.attributeName();
26381
+ if (this.getOptionValue(optionKey) === void 0 || [
26382
+ "default",
26383
+ "config",
26384
+ "env"
26385
+ ].includes(this.getOptionValueSource(optionKey))) if (option.required || option.optional) this.emit(`optionEnv:${option.name()}`, process$2.env[option.envVar]);
26386
+ else this.emit(`optionEnv:${option.name()}`);
26387
+ }
26388
+ });
26389
+ }
26390
+ /**
26391
+ * Apply any implied option values, if option is undefined or default value.
26392
+ *
26393
+ * @private
26394
+ */
26395
+ _parseOptionsImplied() {
26396
+ const dualHelper = new DualOptions(this.options);
26397
+ const hasCustomOptionValue = (optionKey) => {
26398
+ return this.getOptionValue(optionKey) !== void 0 && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
26399
+ };
26400
+ this.options.filter((option) => option.implied !== void 0 && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
26401
+ Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
26402
+ this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
26403
+ });
26404
+ });
26405
+ }
26406
+ /**
26407
+ * Argument `name` is missing.
26408
+ *
26409
+ * @param {string} name
26410
+ * @private
26411
+ */
26412
+ missingArgument(name) {
26413
+ const message = `error: missing required argument '${name}'`;
26414
+ this.error(message, { code: "commander.missingArgument" });
26415
+ }
26416
+ /**
26417
+ * `Option` is missing an argument.
26418
+ *
26419
+ * @param {Option} option
26420
+ * @private
26421
+ */
26422
+ optionMissingArgument(option) {
26423
+ const message = `error: option '${option.flags}' argument missing`;
26424
+ this.error(message, { code: "commander.optionMissingArgument" });
26425
+ }
26426
+ /**
26427
+ * `Option` does not have a value, and is a mandatory option.
26428
+ *
26429
+ * @param {Option} option
26430
+ * @private
26431
+ */
26432
+ missingMandatoryOptionValue(option) {
26433
+ const message = `error: required option '${option.flags}' not specified`;
26434
+ this.error(message, { code: "commander.missingMandatoryOptionValue" });
26435
+ }
26436
+ /**
26437
+ * `Option` conflicts with another option.
26438
+ *
26439
+ * @param {Option} option
26440
+ * @param {Option} conflictingOption
26441
+ * @private
26442
+ */
26443
+ _conflictingOption(option, conflictingOption) {
26444
+ const findBestOptionFromValue = (option) => {
26445
+ const optionKey = option.attributeName();
26446
+ const optionValue = this.getOptionValue(optionKey);
26447
+ const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
26448
+ const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
26449
+ if (negativeOption && (negativeOption.presetArg === void 0 && optionValue === false || negativeOption.presetArg !== void 0 && optionValue === negativeOption.presetArg)) return negativeOption;
26450
+ return positiveOption || option;
26451
+ };
26452
+ const getErrorMessage = (option) => {
26453
+ const bestOption = findBestOptionFromValue(option);
26454
+ const optionKey = bestOption.attributeName();
26455
+ if (this.getOptionValueSource(optionKey) === "env") return `environment variable '${bestOption.envVar}'`;
26456
+ return `option '${bestOption.flags}'`;
26457
+ };
26458
+ const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
26459
+ this.error(message, { code: "commander.conflictingOption" });
26460
+ }
26461
+ /**
26462
+ * Unknown option `flag`.
26463
+ *
26464
+ * @param {string} flag
26465
+ * @private
26466
+ */
26467
+ unknownOption(flag) {
26468
+ if (this._allowUnknownOption) return;
26469
+ let suggestion = "";
26470
+ if (flag.startsWith("--") && this._showSuggestionAfterError) {
26471
+ let candidateFlags = [];
26472
+ let command = this;
26473
+ do {
26474
+ const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
26475
+ candidateFlags = candidateFlags.concat(moreFlags);
26476
+ command = command.parent;
26477
+ } while (command && !command._enablePositionalOptions);
26478
+ suggestion = suggestSimilar(flag, candidateFlags);
26479
+ }
26480
+ const message = `error: unknown option '${flag}'${suggestion}`;
26481
+ this.error(message, { code: "commander.unknownOption" });
26482
+ }
26483
+ /**
26484
+ * Excess arguments, more than expected.
26485
+ *
26486
+ * @param {string[]} receivedArgs
26487
+ * @private
26488
+ */
26489
+ _excessArguments(receivedArgs) {
26490
+ if (this._allowExcessArguments) return;
26491
+ const expected = this.registeredArguments.length;
26492
+ const s = expected === 1 ? "" : "s";
26493
+ const message = `error: too many arguments${this.parent ? ` for '${this.name()}'` : ""}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
26494
+ this.error(message, { code: "commander.excessArguments" });
26495
+ }
26496
+ /**
26497
+ * Unknown command.
26498
+ *
26499
+ * @private
26500
+ */
26501
+ unknownCommand() {
26502
+ const unknownName = this.args[0];
26503
+ let suggestion = "";
26504
+ if (this._showSuggestionAfterError) {
26505
+ const candidateNames = [];
26506
+ this.createHelp().visibleCommands(this).forEach((command) => {
26507
+ candidateNames.push(command.name());
26508
+ if (command.alias()) candidateNames.push(command.alias());
26509
+ });
26510
+ suggestion = suggestSimilar(unknownName, candidateNames);
26511
+ }
26512
+ const message = `error: unknown command '${unknownName}'${suggestion}`;
26513
+ this.error(message, { code: "commander.unknownCommand" });
26514
+ }
26515
+ /**
26516
+ * Get or set the program version.
26517
+ *
26518
+ * This method auto-registers the "-V, --version" option which will print the version number.
26519
+ *
26520
+ * You can optionally supply the flags and description to override the defaults.
26521
+ *
26522
+ * @param {string} [str]
26523
+ * @param {string} [flags]
26524
+ * @param {string} [description]
26525
+ * @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments
26526
+ */
26527
+ version(str, flags, description) {
26528
+ if (str === void 0) return this._version;
26529
+ this._version = str;
26530
+ flags = flags || "-V, --version";
26531
+ description = description || "output the version number";
26532
+ const versionOption = this.createOption(flags, description);
26533
+ this._versionOptionName = versionOption.attributeName();
26534
+ this._registerOption(versionOption);
26535
+ this.on("option:" + versionOption.name(), () => {
26536
+ this._outputConfiguration.writeOut(`${str}\n`);
26537
+ this._exit(0, "commander.version", str);
26538
+ });
26539
+ return this;
26540
+ }
26541
+ /**
26542
+ * Set the description.
26543
+ *
26544
+ * @param {string} [str]
26545
+ * @param {object} [argsDescription]
26546
+ * @return {(string|Command)}
26547
+ */
26548
+ description(str, argsDescription) {
26549
+ if (str === void 0 && argsDescription === void 0) return this._description;
26550
+ this._description = str;
26551
+ if (argsDescription) this._argsDescription = argsDescription;
26552
+ return this;
26553
+ }
26554
+ /**
26555
+ * Set the summary. Used when listed as subcommand of parent.
26556
+ *
26557
+ * @param {string} [str]
26558
+ * @return {(string|Command)}
26559
+ */
26560
+ summary(str) {
26561
+ if (str === void 0) return this._summary;
26562
+ this._summary = str;
26563
+ return this;
26564
+ }
26565
+ /**
26566
+ * Set an alias for the command.
26567
+ *
26568
+ * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
26569
+ *
26570
+ * @param {string} [alias]
26571
+ * @return {(string|Command)}
26572
+ */
26573
+ alias(alias) {
26574
+ if (alias === void 0) return this._aliases[0];
26575
+ /** @type {Command} */
26576
+ let command = this;
26577
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) command = this.commands[this.commands.length - 1];
26578
+ if (alias === command._name) throw new Error("Command alias can't be the same as its name");
26579
+ const matchingCommand = this.parent?._findCommand(alias);
26580
+ if (matchingCommand) {
26581
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
26582
+ throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
26583
+ }
26584
+ command._aliases.push(alias);
26585
+ return this;
26586
+ }
26587
+ /**
26588
+ * Set aliases for the command.
26589
+ *
26590
+ * Only the first alias is shown in the auto-generated help.
26591
+ *
26592
+ * @param {string[]} [aliases]
26593
+ * @return {(string[]|Command)}
26594
+ */
26595
+ aliases(aliases) {
26596
+ if (aliases === void 0) return this._aliases;
26597
+ aliases.forEach((alias) => this.alias(alias));
26598
+ return this;
26599
+ }
26600
+ /**
26601
+ * Set / get the command usage `str`.
26602
+ *
26603
+ * @param {string} [str]
26604
+ * @return {(string|Command)}
26605
+ */
26606
+ usage(str) {
26607
+ if (str === void 0) {
26608
+ if (this._usage) return this._usage;
26609
+ const args = this.registeredArguments.map((arg) => {
26610
+ return humanReadableArgName(arg);
26611
+ });
26612
+ return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
26613
+ }
26614
+ this._usage = str;
26615
+ return this;
26616
+ }
26617
+ /**
26618
+ * Get or set the name of the command.
26619
+ *
26620
+ * @param {string} [str]
26621
+ * @return {(string|Command)}
26622
+ */
26623
+ name(str) {
26624
+ if (str === void 0) return this._name;
26625
+ this._name = str;
26626
+ return this;
26627
+ }
26628
+ /**
26629
+ * Set/get the help group heading for this subcommand in parent command's help.
26630
+ *
26631
+ * @param {string} [heading]
26632
+ * @return {Command | string}
26633
+ */
26634
+ helpGroup(heading) {
26635
+ if (heading === void 0) return this._helpGroupHeading ?? "";
26636
+ this._helpGroupHeading = heading;
26637
+ return this;
26638
+ }
26639
+ /**
26640
+ * Set/get the default help group heading for subcommands added to this command.
26641
+ * (This does not override a group set directly on the subcommand using .helpGroup().)
26642
+ *
26643
+ * @example
26644
+ * program.commandsGroup('Development Commands:);
26645
+ * program.command('watch')...
26646
+ * program.command('lint')...
26647
+ * ...
26648
+ *
26649
+ * @param {string} [heading]
26650
+ * @returns {Command | string}
26651
+ */
26652
+ commandsGroup(heading) {
26653
+ if (heading === void 0) return this._defaultCommandGroup ?? "";
26654
+ this._defaultCommandGroup = heading;
26655
+ return this;
26656
+ }
26657
+ /**
26658
+ * Set/get the default help group heading for options added to this command.
26659
+ * (This does not override a group set directly on the option using .helpGroup().)
26660
+ *
26661
+ * @example
26662
+ * program
26663
+ * .optionsGroup('Development Options:')
26664
+ * .option('-d, --debug', 'output extra debugging')
26665
+ * .option('-p, --profile', 'output profiling information')
26666
+ *
26667
+ * @param {string} [heading]
26668
+ * @returns {Command | string}
26669
+ */
26670
+ optionsGroup(heading) {
26671
+ if (heading === void 0) return this._defaultOptionGroup ?? "";
26672
+ this._defaultOptionGroup = heading;
26673
+ return this;
26674
+ }
26675
+ /**
26676
+ * @param {Option} option
26677
+ * @private
26678
+ */
26679
+ _initOptionGroup(option) {
26680
+ if (this._defaultOptionGroup && !option.helpGroupHeading) option.helpGroup(this._defaultOptionGroup);
26681
+ }
26682
+ /**
26683
+ * @param {Command} cmd
26684
+ * @private
26685
+ */
26686
+ _initCommandGroup(cmd) {
26687
+ if (this._defaultCommandGroup && !cmd.helpGroup()) cmd.helpGroup(this._defaultCommandGroup);
26688
+ }
26689
+ /**
26690
+ * Set the name of the command from script filename, such as process.argv[1],
26691
+ * or require.main.filename, or __filename.
26692
+ *
26693
+ * (Used internally and public although not documented in README.)
26694
+ *
26695
+ * @example
26696
+ * program.nameFromFilename(require.main.filename);
26697
+ *
26698
+ * @param {string} filename
26699
+ * @return {Command}
26700
+ */
26701
+ nameFromFilename(filename) {
26702
+ this._name = path.basename(filename, path.extname(filename));
26703
+ return this;
26704
+ }
26705
+ /**
26706
+ * Get or set the directory for searching for executable subcommands of this command.
26707
+ *
26708
+ * @example
26709
+ * program.executableDir(__dirname);
26710
+ * // or
26711
+ * program.executableDir('subcommands');
26712
+ *
26713
+ * @param {string} [path]
26714
+ * @return {(string|null|Command)}
26715
+ */
26716
+ executableDir(path) {
26717
+ if (path === void 0) return this._executableDir;
26718
+ this._executableDir = path;
26719
+ return this;
26720
+ }
26721
+ /**
26722
+ * Return program help documentation.
26723
+ *
26724
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout
26725
+ * @return {string}
26726
+ */
26727
+ helpInformation(contextOptions) {
26728
+ const helper = this.createHelp();
26729
+ const context = this._getOutputContext(contextOptions);
26730
+ helper.prepareContext({
26731
+ error: context.error,
26732
+ helpWidth: context.helpWidth,
26733
+ outputHasColors: context.hasColors
26734
+ });
26735
+ const text = helper.formatHelp(this, helper);
26736
+ if (context.hasColors) return text;
26737
+ return this._outputConfiguration.stripColor(text);
26738
+ }
26739
+ /**
26740
+ * @typedef HelpContext
26741
+ * @type {object}
26742
+ * @property {boolean} error
26743
+ * @property {number} helpWidth
26744
+ * @property {boolean} hasColors
26745
+ * @property {function} write - includes stripColor if needed
26746
+ *
26747
+ * @returns {HelpContext}
26748
+ * @private
26749
+ */
26750
+ _getOutputContext(contextOptions) {
26751
+ contextOptions = contextOptions || {};
26752
+ const error = !!contextOptions.error;
26753
+ let baseWrite;
26754
+ let hasColors;
26755
+ let helpWidth;
26756
+ if (error) {
26757
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
26758
+ hasColors = this._outputConfiguration.getErrHasColors();
26759
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
26760
+ } else {
26761
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
26762
+ hasColors = this._outputConfiguration.getOutHasColors();
26763
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
26764
+ }
26765
+ const write = (str) => {
26766
+ if (!hasColors) str = this._outputConfiguration.stripColor(str);
26767
+ return baseWrite(str);
26768
+ };
26769
+ return {
26770
+ error,
26771
+ write,
26772
+ hasColors,
26773
+ helpWidth
26774
+ };
26775
+ }
26776
+ /**
26777
+ * Output help information for this command.
26778
+ *
26779
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
26780
+ *
26781
+ * @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout
26782
+ */
26783
+ outputHelp(contextOptions) {
26784
+ let deprecatedCallback;
26785
+ if (typeof contextOptions === "function") {
26786
+ deprecatedCallback = contextOptions;
26787
+ contextOptions = void 0;
26788
+ }
26789
+ const outputContext = this._getOutputContext(contextOptions);
26790
+ /** @type {HelpTextEventContext} */
26791
+ const eventContext = {
26792
+ error: outputContext.error,
26793
+ write: outputContext.write,
26794
+ command: this
26795
+ };
26796
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
26797
+ this.emit("beforeHelp", eventContext);
26798
+ let helpInformation = this.helpInformation({ error: outputContext.error });
26799
+ if (deprecatedCallback) {
26800
+ helpInformation = deprecatedCallback(helpInformation);
26801
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) throw new Error("outputHelp callback must return a string or a Buffer");
26802
+ }
26803
+ outputContext.write(helpInformation);
26804
+ if (this._getHelpOption()?.long) this.emit(this._getHelpOption().long);
26805
+ this.emit("afterHelp", eventContext);
26806
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
26807
+ }
26808
+ /**
26809
+ * You can pass in flags and a description to customise the built-in help option.
26810
+ * Pass in false to disable the built-in help option.
26811
+ *
26812
+ * @example
26813
+ * program.helpOption('-?, --help' 'show help'); // customise
26814
+ * program.helpOption(false); // disable
26815
+ *
26816
+ * @param {(string | boolean)} flags
26817
+ * @param {string} [description]
26818
+ * @return {Command} `this` command for chaining
26819
+ */
26820
+ helpOption(flags, description) {
26821
+ if (typeof flags === "boolean") {
26822
+ if (flags) {
26823
+ if (this._helpOption === null) this._helpOption = void 0;
26824
+ if (this._defaultOptionGroup) this._initOptionGroup(this._getHelpOption());
26825
+ } else this._helpOption = null;
26826
+ return this;
26827
+ }
26828
+ this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
26829
+ if (flags || description) this._initOptionGroup(this._helpOption);
26830
+ return this;
26831
+ }
26832
+ /**
26833
+ * Lazy create help option.
26834
+ * Returns null if has been disabled with .helpOption(false).
26835
+ *
26836
+ * @returns {(Option | null)} the help option
26837
+ * @package
26838
+ */
26839
+ _getHelpOption() {
26840
+ if (this._helpOption === void 0) this.helpOption(void 0, void 0);
26841
+ return this._helpOption;
26842
+ }
26843
+ /**
26844
+ * Supply your own option to use for the built-in help option.
26845
+ * This is an alternative to using helpOption() to customise the flags and description etc.
26846
+ *
26847
+ * @param {Option} option
26848
+ * @return {Command} `this` command for chaining
26849
+ */
26850
+ addHelpOption(option) {
26851
+ this._helpOption = option;
26852
+ this._initOptionGroup(option);
26853
+ return this;
26854
+ }
26855
+ /**
26856
+ * Output help information and exit.
26857
+ *
26858
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
26859
+ *
26860
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout
26861
+ */
26862
+ help(contextOptions) {
26863
+ this.outputHelp(contextOptions);
26864
+ let exitCode = Number(process$2.exitCode ?? 0);
26865
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) exitCode = 1;
26866
+ this._exit(exitCode, "commander.help", "(outputHelp)");
26867
+ }
26868
+ /**
26869
+ * // Do a little typing to coordinate emit and listener for the help text events.
26870
+ * @typedef HelpTextEventContext
26871
+ * @type {object}
26872
+ * @property {boolean} error
26873
+ * @property {Command} command
26874
+ * @property {function} write
26875
+ */
26876
+ /**
26877
+ * Add additional text to be displayed with the built-in help.
26878
+ *
26879
+ * Position is 'before' or 'after' to affect just this command,
26880
+ * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
26881
+ *
26882
+ * @param {string} position - before or after built-in help
26883
+ * @param {(string | Function)} text - string to add, or a function returning a string
26884
+ * @return {Command} `this` command for chaining
26885
+ */
26886
+ addHelpText(position, text) {
26887
+ const allowedValues = [
26888
+ "beforeAll",
26889
+ "before",
26890
+ "after",
26891
+ "afterAll"
26892
+ ];
26893
+ if (!allowedValues.includes(position)) throw new Error(`Unexpected value for position to addHelpText.
26894
+ Expecting one of '${allowedValues.join("', '")}'`);
26895
+ const helpEvent = `${position}Help`;
26896
+ this.on(helpEvent, (context) => {
26897
+ let helpStr;
26898
+ if (typeof text === "function") helpStr = text({
26899
+ error: context.error,
26900
+ command: context.command
26901
+ });
26902
+ else helpStr = text;
26903
+ if (helpStr) context.write(`${helpStr}\n`);
26904
+ });
26905
+ return this;
26906
+ }
26907
+ /**
26908
+ * Output help information if help flags specified
26909
+ *
26910
+ * @param {Array} args - array of options to search for help flags
26911
+ * @private
26912
+ */
26913
+ _outputHelpIfRequested(args) {
26914
+ const helpOption = this._getHelpOption();
26915
+ if (helpOption && args.find((arg) => helpOption.is(arg))) {
26916
+ this.outputHelp();
26917
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
26918
+ }
26919
+ }
26920
+ };
26921
+ /**
26922
+ * Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).
26923
+ *
26924
+ * @param {string[]} args - array of arguments from node.execArgv
26925
+ * @returns {string[]}
26926
+ * @private
26927
+ */
26928
+ function incrementNodeInspectorPort(args) {
26929
+ return args.map((arg) => {
26930
+ if (!arg.startsWith("--inspect")) return arg;
26931
+ let debugOption;
26932
+ let debugHost = "127.0.0.1";
26933
+ let debugPort = "9229";
26934
+ let match;
26935
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) debugOption = match[1];
26936
+ else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
26937
+ debugOption = match[1];
26938
+ if (/^\d+$/.test(match[3])) debugPort = match[3];
26939
+ else debugHost = match[3];
26940
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
26941
+ debugOption = match[1];
26942
+ debugHost = match[3];
26943
+ debugPort = match[4];
26944
+ }
26945
+ if (debugOption && debugPort !== "0") return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
26946
+ return arg;
26947
+ });
26948
+ }
26949
+ /**
26950
+ * @returns {boolean | undefined}
26951
+ * @package
26952
+ */
26953
+ function useColor() {
26954
+ if (process$2.env.NO_COLOR || process$2.env.FORCE_COLOR === "0" || process$2.env.FORCE_COLOR === "false") return false;
26955
+ if (process$2.env.FORCE_COLOR || process$2.env.CLICOLOR_FORCE !== void 0) return true;
26956
+ }
26957
+ exports.Command = Command;
26958
+ exports.useColor = useColor;
26959
+ }));
26960
+ const { program, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help } = (/* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
26961
+ const { Argument } = require_argument();
26962
+ const { Command } = require_command();
26963
+ const { CommanderError, InvalidArgumentError } = require_error();
26964
+ const { Help } = require_help();
26965
+ const { Option } = require_option();
26966
+ exports.program = new Command();
26967
+ exports.createCommand = (name) => new Command(name);
26968
+ exports.createOption = (flags, description) => new Option(flags, description);
26969
+ exports.createArgument = (name, description) => new Argument(name, description);
26970
+ /**
26971
+ * Expose classes
26972
+ */
26973
+ exports.Command = Command;
26974
+ exports.Option = Option;
26975
+ exports.Argument = Argument;
26976
+ exports.Help = Help;
26977
+ exports.CommanderError = CommanderError;
26978
+ exports.InvalidArgumentError = InvalidArgumentError;
26979
+ exports.InvalidOptionArgumentError = InvalidArgumentError;
26980
+ })))(), 1)).default;
26981
+ //#endregion
26982
+ //#region src/cli.ts
26983
+ async function runCli(args, io = {}) {
26984
+ const program = createProgram(io);
26985
+ try {
26986
+ await program.parseAsync([
26987
+ "node",
26988
+ "caplets",
26989
+ ...args
26990
+ ]);
26991
+ } catch (error) {
26992
+ if (error instanceof CommanderError) {
26993
+ if (error.code === "commander.helpDisplayed" || error.code === "commander.version") return;
26994
+ throw new CapletsError("REQUEST_INVALID", error.message);
26995
+ }
26996
+ throw error;
26997
+ }
26998
+ }
26999
+ function createProgram(io = {}) {
27000
+ const writeOut = io.writeOut ?? ((value) => process.stdout.write(value));
27001
+ const writeErr = io.writeErr ?? ((value) => process.stderr.write(value));
27002
+ const program = new Command();
27003
+ program.name("caplets").description("Progressive-disclosure gateway for MCP servers.").exitOverride().configureOutput({
27004
+ writeOut,
27005
+ writeErr,
27006
+ outputError: (value, write) => write(value)
27007
+ });
27008
+ program.command("init").description("Create a starter Caplets config file.").option("--force", "overwrite an existing config file").action((options) => {
27009
+ const configPath = envConfigPath();
27010
+ writeOut(`Created Caplets config at ${initConfig({
27011
+ ...configPath ? { path: configPath } : {},
27012
+ force: Boolean(options.force)
27013
+ })}\n`);
27014
+ });
27015
+ const auth = program.command("auth").description("Manage OAuth credentials for remote servers.");
27016
+ auth.command("login").description("Authenticate a configured remote OAuth server.").argument("<server>", "configured server ID").option("--no-open", "print the authorization URL without opening a browser").action(async (serverId, options) => {
27017
+ await loginAuth(serverId, {
27018
+ noOpen: options.open === false,
27019
+ writeOut,
27020
+ writeErr,
27021
+ ...io.authDir ? { authDir: io.authDir } : {}
27022
+ });
27023
+ });
27024
+ auth.command("logout").description("Delete stored OAuth credentials for a server.").argument("<server>", "configured server ID").action((serverId) => {
27025
+ const server = loadConfig(envConfigPath()).mcpServers[serverId];
27026
+ if (!server) throw new CapletsError("SERVER_NOT_FOUND", `Server ${serverId} is not configured`);
27027
+ if (server.transport === "stdio" || server.auth?.type !== "oauth2") throw new CapletsError("REQUEST_INVALID", `Server ${serverId} is not a remote OAuth server`);
27028
+ if (deleteTokenBundle(serverId, io.authDir)) writeOut(`Deleted OAuth credentials for ${serverId}\n`);
27029
+ else writeOut(`No OAuth credentials found for ${serverId}\n`);
27030
+ });
27031
+ auth.command("list").description("List servers with stored OAuth credentials.").action(() => {
27032
+ const config = loadConfig(envConfigPath());
27033
+ const servers = Object.values(config.mcpServers).filter((server) => server.transport !== "stdio" && server.auth?.type === "oauth2").sort((left, right) => left.server.localeCompare(right.server));
27034
+ if (servers.length === 0) {
27035
+ writeOut("No configured remote OAuth servers found.\n");
27036
+ return;
27037
+ }
27038
+ for (const server of servers) {
27039
+ const bundle = readTokenBundle(server.server, io.authDir);
27040
+ const status = !bundle ? "missing" : isTokenBundleExpired(bundle) ? "expired" : "authenticated";
27041
+ writeOut([
27042
+ server.server,
27043
+ status,
27044
+ bundle?.expiresAt ? `expires ${bundle.expiresAt}` : void 0,
27045
+ bundle?.scope ? `scope ${bundle.scope}` : void 0
27046
+ ].filter(Boolean).join(" "));
27047
+ writeOut("\n");
27048
+ }
27049
+ });
27050
+ return program;
27051
+ }
27052
+ async function loginAuth(serverId, options) {
27053
+ const server = loadConfig(envConfigPath()).mcpServers[serverId];
27054
+ if (!server) throw new CapletsError("SERVER_NOT_FOUND", `Server ${serverId} is not configured`);
27055
+ if (server.disabled) throw new CapletsError("SERVER_UNAVAILABLE", `Server ${serverId} is disabled`);
27056
+ if (server.transport === "stdio" || server.auth?.type !== "oauth2") throw new CapletsError("REQUEST_INVALID", `Server ${serverId} is not a remote OAuth server`);
27057
+ try {
27058
+ await runOAuthFlow(server, {
27059
+ noOpen: options.noOpen,
27060
+ ...options.authDir ? { authDir: options.authDir } : {},
27061
+ ...options.noOpen ? { readManualInput: maybeReadManualInput } : {},
27062
+ print: (line) => options.writeOut(`${line}\n`)
27063
+ });
27064
+ options.writeOut(`Authenticated ${serverId}\n`);
27065
+ } catch (error) {
27066
+ options.writeErr(`${JSON.stringify(toSafeError(error, "AUTH_FAILED"), null, 2)}\n`);
27067
+ process.exitCode = 1;
27068
+ }
27069
+ }
27070
+ function initConfig(options = {}) {
27071
+ const path = resolveConfigPath(options.path);
27072
+ if (existsSync(path) && !options.force) throw new CapletsError("CONFIG_EXISTS", `Caplets config already exists at ${path}; pass --force to overwrite it`);
27073
+ mkdirSync(dirname(path), {
27074
+ recursive: true,
27075
+ mode: 448
27076
+ });
27077
+ writeFileSync(path, `${starterConfig()}\n`, {
27078
+ mode: 384,
27079
+ flag: options.force ? "w" : "wx"
27080
+ });
27081
+ try {
27082
+ chmodSync(path, 384);
27083
+ } catch {}
27084
+ return path;
27085
+ }
27086
+ function starterConfig() {
27087
+ return JSON.stringify({
27088
+ $schema: "https://raw.githubusercontent.com/spiritledsoftware/caplets/main/schemas/caplets-config.schema.json",
27089
+ version: 1,
27090
+ defaultSearchLimit: 20,
27091
+ maxSearchLimit: 50,
27092
+ mcpServers: { example: {
27093
+ name: "Example MCP Server",
27094
+ description: "Replace this with a real MCP server and what agents should use it for.",
27095
+ command: "npx",
27096
+ args: ["-y", "@modelcontextprotocol/server-everything"],
27097
+ disabled: true
27098
+ } }
27099
+ }, null, 2);
27100
+ }
27101
+ function envConfigPath() {
27102
+ return process.env.CAPLETS_CONFIG?.trim() || void 0;
23938
27103
  }
23939
27104
  async function maybeReadManualInput() {
23940
27105
  if (!stdin.isTTY) return;