@carllee1983/dbcli 0.4.0-beta → 0.5.0-beta

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/cli.mjs CHANGED
@@ -2064,6 +2064,76 @@ var require_commander = __commonJS((exports) => {
2064
2064
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2065
2065
  });
2066
2066
 
2067
+ // node_modules/picocolors/picocolors.js
2068
+ var require_picocolors = __commonJS((exports, module) => {
2069
+ var p = process || {};
2070
+ var argv = p.argv || [];
2071
+ var env = p.env || {};
2072
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
2073
+ var formatter = (open, close, replace = open) => (input) => {
2074
+ let string = "" + input, index = string.indexOf(close, open.length);
2075
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2076
+ };
2077
+ var replaceClose = (string, close, replace, index) => {
2078
+ let result = "", cursor = 0;
2079
+ do {
2080
+ result += string.substring(cursor, index) + replace;
2081
+ cursor = index + close.length;
2082
+ index = string.indexOf(close, cursor);
2083
+ } while (~index);
2084
+ return result + string.substring(cursor);
2085
+ };
2086
+ var createColors = (enabled = isColorSupported) => {
2087
+ let f = enabled ? formatter : () => String;
2088
+ return {
2089
+ isColorSupported: enabled,
2090
+ reset: f("\x1B[0m", "\x1B[0m"),
2091
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2092
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2093
+ italic: f("\x1B[3m", "\x1B[23m"),
2094
+ underline: f("\x1B[4m", "\x1B[24m"),
2095
+ inverse: f("\x1B[7m", "\x1B[27m"),
2096
+ hidden: f("\x1B[8m", "\x1B[28m"),
2097
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
2098
+ black: f("\x1B[30m", "\x1B[39m"),
2099
+ red: f("\x1B[31m", "\x1B[39m"),
2100
+ green: f("\x1B[32m", "\x1B[39m"),
2101
+ yellow: f("\x1B[33m", "\x1B[39m"),
2102
+ blue: f("\x1B[34m", "\x1B[39m"),
2103
+ magenta: f("\x1B[35m", "\x1B[39m"),
2104
+ cyan: f("\x1B[36m", "\x1B[39m"),
2105
+ white: f("\x1B[37m", "\x1B[39m"),
2106
+ gray: f("\x1B[90m", "\x1B[39m"),
2107
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
2108
+ bgRed: f("\x1B[41m", "\x1B[49m"),
2109
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
2110
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
2111
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
2112
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
2113
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
2114
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
2115
+ blackBright: f("\x1B[90m", "\x1B[39m"),
2116
+ redBright: f("\x1B[91m", "\x1B[39m"),
2117
+ greenBright: f("\x1B[92m", "\x1B[39m"),
2118
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
2119
+ blueBright: f("\x1B[94m", "\x1B[39m"),
2120
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
2121
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
2122
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
2123
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2124
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
2125
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2126
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2127
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2128
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2129
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2130
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2131
+ };
2132
+ };
2133
+ module.exports = createColors();
2134
+ module.exports.createColors = createColors;
2135
+ });
2136
+
2067
2137
  // node_modules/@inquirer/core/dist/esm/lib/key.mjs
2068
2138
  var isUpKey = (key) => key.name === "up" || key.name === "k" || key.ctrl && key.name === "p", isDownKey = (key) => key.name === "down" || key.name === "j" || key.ctrl && key.name === "n", isSpaceKey = (key) => key.name === "space", isBackspaceKey = (key) => key.name === "backspace", isNumberKey = (key) => "123456789".includes(key.name), isEnterKey = (key) => key.name === "enter" || key.name === "return";
2069
2139
 
@@ -2267,49 +2337,49 @@ var require_yoctocolors_cjs = __commonJS((exports, module) => {
2267
2337
  return result;
2268
2338
  };
2269
2339
  };
2270
- var colors = {};
2271
- colors.reset = format(0, 0);
2272
- colors.bold = format(1, 22);
2273
- colors.dim = format(2, 22);
2274
- colors.italic = format(3, 23);
2275
- colors.underline = format(4, 24);
2276
- colors.overline = format(53, 55);
2277
- colors.inverse = format(7, 27);
2278
- colors.hidden = format(8, 28);
2279
- colors.strikethrough = format(9, 29);
2280
- colors.black = format(30, 39);
2281
- colors.red = format(31, 39);
2282
- colors.green = format(32, 39);
2283
- colors.yellow = format(33, 39);
2284
- colors.blue = format(34, 39);
2285
- colors.magenta = format(35, 39);
2286
- colors.cyan = format(36, 39);
2287
- colors.white = format(37, 39);
2288
- colors.gray = format(90, 39);
2289
- colors.bgBlack = format(40, 49);
2290
- colors.bgRed = format(41, 49);
2291
- colors.bgGreen = format(42, 49);
2292
- colors.bgYellow = format(43, 49);
2293
- colors.bgBlue = format(44, 49);
2294
- colors.bgMagenta = format(45, 49);
2295
- colors.bgCyan = format(46, 49);
2296
- colors.bgWhite = format(47, 49);
2297
- colors.bgGray = format(100, 49);
2298
- colors.redBright = format(91, 39);
2299
- colors.greenBright = format(92, 39);
2300
- colors.yellowBright = format(93, 39);
2301
- colors.blueBright = format(94, 39);
2302
- colors.magentaBright = format(95, 39);
2303
- colors.cyanBright = format(96, 39);
2304
- colors.whiteBright = format(97, 39);
2305
- colors.bgRedBright = format(101, 49);
2306
- colors.bgGreenBright = format(102, 49);
2307
- colors.bgYellowBright = format(103, 49);
2308
- colors.bgBlueBright = format(104, 49);
2309
- colors.bgMagentaBright = format(105, 49);
2310
- colors.bgCyanBright = format(106, 49);
2311
- colors.bgWhiteBright = format(107, 49);
2312
- module.exports = colors;
2340
+ var colors2 = {};
2341
+ colors2.reset = format(0, 0);
2342
+ colors2.bold = format(1, 22);
2343
+ colors2.dim = format(2, 22);
2344
+ colors2.italic = format(3, 23);
2345
+ colors2.underline = format(4, 24);
2346
+ colors2.overline = format(53, 55);
2347
+ colors2.inverse = format(7, 27);
2348
+ colors2.hidden = format(8, 28);
2349
+ colors2.strikethrough = format(9, 29);
2350
+ colors2.black = format(30, 39);
2351
+ colors2.red = format(31, 39);
2352
+ colors2.green = format(32, 39);
2353
+ colors2.yellow = format(33, 39);
2354
+ colors2.blue = format(34, 39);
2355
+ colors2.magenta = format(35, 39);
2356
+ colors2.cyan = format(36, 39);
2357
+ colors2.white = format(37, 39);
2358
+ colors2.gray = format(90, 39);
2359
+ colors2.bgBlack = format(40, 49);
2360
+ colors2.bgRed = format(41, 49);
2361
+ colors2.bgGreen = format(42, 49);
2362
+ colors2.bgYellow = format(43, 49);
2363
+ colors2.bgBlue = format(44, 49);
2364
+ colors2.bgMagenta = format(45, 49);
2365
+ colors2.bgCyan = format(46, 49);
2366
+ colors2.bgWhite = format(47, 49);
2367
+ colors2.bgGray = format(100, 49);
2368
+ colors2.redBright = format(91, 39);
2369
+ colors2.greenBright = format(92, 39);
2370
+ colors2.yellowBright = format(93, 39);
2371
+ colors2.blueBright = format(94, 39);
2372
+ colors2.magentaBright = format(95, 39);
2373
+ colors2.cyanBright = format(96, 39);
2374
+ colors2.whiteBright = format(97, 39);
2375
+ colors2.bgRedBright = format(101, 49);
2376
+ colors2.bgGreenBright = format(102, 49);
2377
+ colors2.bgYellowBright = format(103, 49);
2378
+ colors2.bgBlueBright = format(104, 49);
2379
+ colors2.bgMagentaBright = format(105, 49);
2380
+ colors2.bgCyanBright = format(106, 49);
2381
+ colors2.bgWhiteBright = format(107, 49);
2382
+ module.exports = colors2;
2313
2383
  });
2314
2384
 
2315
2385
  // node_modules/@inquirer/figures/dist/esm/index.js
@@ -41827,17 +41897,17 @@ var require_zalgo = __commonJS((exports, module) => {
41827
41897
 
41828
41898
  // node_modules/@colors/colors/lib/maps/america.js
41829
41899
  var require_america = __commonJS((exports, module) => {
41830
- module["exports"] = function(colors8) {
41900
+ module["exports"] = function(colors9) {
41831
41901
  return function(letter, i, exploded) {
41832
41902
  if (letter === " ")
41833
41903
  return letter;
41834
41904
  switch (i % 3) {
41835
41905
  case 0:
41836
- return colors8.red(letter);
41906
+ return colors9.red(letter);
41837
41907
  case 1:
41838
- return colors8.white(letter);
41908
+ return colors9.white(letter);
41839
41909
  case 2:
41840
- return colors8.blue(letter);
41910
+ return colors9.blue(letter);
41841
41911
  }
41842
41912
  };
41843
41913
  };
@@ -41845,22 +41915,22 @@ var require_america = __commonJS((exports, module) => {
41845
41915
 
41846
41916
  // node_modules/@colors/colors/lib/maps/zebra.js
41847
41917
  var require_zebra = __commonJS((exports, module) => {
41848
- module["exports"] = function(colors8) {
41918
+ module["exports"] = function(colors9) {
41849
41919
  return function(letter, i, exploded) {
41850
- return i % 2 === 0 ? letter : colors8.inverse(letter);
41920
+ return i % 2 === 0 ? letter : colors9.inverse(letter);
41851
41921
  };
41852
41922
  };
41853
41923
  });
41854
41924
 
41855
41925
  // node_modules/@colors/colors/lib/maps/rainbow.js
41856
41926
  var require_rainbow = __commonJS((exports, module) => {
41857
- module["exports"] = function(colors8) {
41927
+ module["exports"] = function(colors9) {
41858
41928
  var rainbowColors = ["red", "yellow", "green", "blue", "magenta"];
41859
41929
  return function(letter, i, exploded) {
41860
41930
  if (letter === " ") {
41861
41931
  return letter;
41862
41932
  } else {
41863
- return colors8[rainbowColors[i++ % rainbowColors.length]](letter);
41933
+ return colors9[rainbowColors[i++ % rainbowColors.length]](letter);
41864
41934
  }
41865
41935
  };
41866
41936
  };
@@ -41868,7 +41938,7 @@ var require_rainbow = __commonJS((exports, module) => {
41868
41938
 
41869
41939
  // node_modules/@colors/colors/lib/maps/random.js
41870
41940
  var require_random = __commonJS((exports, module) => {
41871
- module["exports"] = function(colors8) {
41941
+ module["exports"] = function(colors9) {
41872
41942
  var available = [
41873
41943
  "underline",
41874
41944
  "inverse",
@@ -41889,40 +41959,40 @@ var require_random = __commonJS((exports, module) => {
41889
41959
  "brightMagenta"
41890
41960
  ];
41891
41961
  return function(letter, i, exploded) {
41892
- return letter === " " ? letter : colors8[available[Math.round(Math.random() * (available.length - 2))]](letter);
41962
+ return letter === " " ? letter : colors9[available[Math.round(Math.random() * (available.length - 2))]](letter);
41893
41963
  };
41894
41964
  };
41895
41965
  });
41896
41966
 
41897
41967
  // node_modules/@colors/colors/lib/colors.js
41898
41968
  var require_colors = __commonJS((exports, module) => {
41899
- var colors8 = {};
41900
- module["exports"] = colors8;
41901
- colors8.themes = {};
41969
+ var colors9 = {};
41970
+ module["exports"] = colors9;
41971
+ colors9.themes = {};
41902
41972
  var util3 = __require("util");
41903
- var ansiStyles = colors8.styles = require_styles();
41973
+ var ansiStyles = colors9.styles = require_styles();
41904
41974
  var defineProps = Object.defineProperties;
41905
41975
  var newLineRegex = new RegExp(/[\r\n]+/g);
41906
- colors8.supportsColor = require_supports_colors().supportsColor;
41907
- if (typeof colors8.enabled === "undefined") {
41908
- colors8.enabled = colors8.supportsColor() !== false;
41976
+ colors9.supportsColor = require_supports_colors().supportsColor;
41977
+ if (typeof colors9.enabled === "undefined") {
41978
+ colors9.enabled = colors9.supportsColor() !== false;
41909
41979
  }
41910
- colors8.enable = function() {
41911
- colors8.enabled = true;
41980
+ colors9.enable = function() {
41981
+ colors9.enabled = true;
41912
41982
  };
41913
- colors8.disable = function() {
41914
- colors8.enabled = false;
41983
+ colors9.disable = function() {
41984
+ colors9.enabled = false;
41915
41985
  };
41916
- colors8.stripColors = colors8.strip = function(str) {
41986
+ colors9.stripColors = colors9.strip = function(str) {
41917
41987
  return ("" + str).replace(/\x1B\[\d+m/g, "");
41918
41988
  };
41919
- var stylize = colors8.stylize = function stylize2(str, style) {
41920
- if (!colors8.enabled) {
41989
+ var stylize = colors9.stylize = function stylize2(str, style) {
41990
+ if (!colors9.enabled) {
41921
41991
  return str + "";
41922
41992
  }
41923
41993
  var styleMap = ansiStyles[style];
41924
- if (!styleMap && style in colors8) {
41925
- return colors8[style](str);
41994
+ if (!styleMap && style in colors9) {
41995
+ return colors9[style](str);
41926
41996
  }
41927
41997
  return styleMap.open + str + styleMap.close;
41928
41998
  };
@@ -41954,7 +42024,7 @@ var require_colors = __commonJS((exports, module) => {
41954
42024
  });
41955
42025
  return ret;
41956
42026
  }();
41957
- var proto = defineProps(function colors9() {}, styles);
42027
+ var proto = defineProps(function colors10() {}, styles);
41958
42028
  function applyStyle() {
41959
42029
  var args = Array.prototype.slice.call(arguments);
41960
42030
  var str = args.map(function(arg) {
@@ -41964,7 +42034,7 @@ var require_colors = __commonJS((exports, module) => {
41964
42034
  return util3.inspect(arg);
41965
42035
  }
41966
42036
  }).join(" ");
41967
- if (!colors8.enabled || !str) {
42037
+ if (!colors9.enabled || !str) {
41968
42038
  return str;
41969
42039
  }
41970
42040
  var newLinesPresent = str.indexOf(`
@@ -41982,22 +42052,22 @@ var require_colors = __commonJS((exports, module) => {
41982
42052
  }
41983
42053
  return str;
41984
42054
  }
41985
- colors8.setTheme = function(theme) {
42055
+ colors9.setTheme = function(theme) {
41986
42056
  if (typeof theme === "string") {
41987
42057
  console.log("colors.setTheme now only accepts an object, not a string. " + "If you are trying to set a theme from a file, it is now your (the " + "caller's) responsibility to require the file. The old syntax " + "looked like colors.setTheme(__dirname + " + "'/../themes/generic-logging.js'); The new syntax looks like " + "colors.setTheme(require(__dirname + " + "'/../themes/generic-logging.js'));");
41988
42058
  return;
41989
42059
  }
41990
42060
  for (var style in theme) {
41991
42061
  (function(style2) {
41992
- colors8[style2] = function(str) {
42062
+ colors9[style2] = function(str) {
41993
42063
  if (typeof theme[style2] === "object") {
41994
42064
  var out = str;
41995
42065
  for (var i in theme[style2]) {
41996
- out = colors8[theme[style2][i]](out);
42066
+ out = colors9[theme[style2][i]](out);
41997
42067
  }
41998
42068
  return out;
41999
42069
  }
42000
- return colors8[theme[style2]](str);
42070
+ return colors9[theme[style2]](str);
42001
42071
  };
42002
42072
  })(style);
42003
42073
  }
@@ -42018,28 +42088,28 @@ var require_colors = __commonJS((exports, module) => {
42018
42088
  exploded = exploded.map(map2);
42019
42089
  return exploded.join("");
42020
42090
  };
42021
- colors8.trap = require_trap();
42022
- colors8.zalgo = require_zalgo();
42023
- colors8.maps = {};
42024
- colors8.maps.america = require_america()(colors8);
42025
- colors8.maps.zebra = require_zebra()(colors8);
42026
- colors8.maps.rainbow = require_rainbow()(colors8);
42027
- colors8.maps.random = require_random()(colors8);
42028
- for (map in colors8.maps) {
42091
+ colors9.trap = require_trap();
42092
+ colors9.zalgo = require_zalgo();
42093
+ colors9.maps = {};
42094
+ colors9.maps.america = require_america()(colors9);
42095
+ colors9.maps.zebra = require_zebra()(colors9);
42096
+ colors9.maps.rainbow = require_rainbow()(colors9);
42097
+ colors9.maps.random = require_random()(colors9);
42098
+ for (map in colors9.maps) {
42029
42099
  (function(map2) {
42030
- colors8[map2] = function(str) {
42031
- return sequencer(colors8.maps[map2], str);
42100
+ colors9[map2] = function(str) {
42101
+ return sequencer(colors9.maps[map2], str);
42032
42102
  };
42033
42103
  })(map);
42034
42104
  }
42035
42105
  var map;
42036
- defineProps(colors8, init());
42106
+ defineProps(colors9, init());
42037
42107
  });
42038
42108
 
42039
42109
  // node_modules/@colors/colors/safe.js
42040
42110
  var require_safe = __commonJS((exports, module) => {
42041
- var colors8 = require_colors();
42042
- module["exports"] = colors8;
42111
+ var colors9 = require_colors();
42112
+ module["exports"] = colors9;
42043
42113
  });
42044
42114
 
42045
42115
  // node_modules/cli-table3/src/cell.js
@@ -42209,11 +42279,11 @@ var require_cell = __commonJS((exports, module) => {
42209
42279
  wrapWithStyleColors(styleProperty, content) {
42210
42280
  if (this[styleProperty] && this[styleProperty].length) {
42211
42281
  try {
42212
- let colors8 = require_safe();
42282
+ let colors9 = require_safe();
42213
42283
  for (let i = this[styleProperty].length - 1;i >= 0; i--) {
42214
- colors8 = colors8[this[styleProperty][i]];
42284
+ colors9 = colors9[this[styleProperty][i]];
42215
42285
  }
42216
- return colors8(content);
42286
+ return colors9(content);
42217
42287
  } catch (e) {
42218
42288
  return content;
42219
42289
  }
@@ -42758,7 +42828,7 @@ var {
42758
42828
  // package.json
42759
42829
  var package_default = {
42760
42830
  name: "@carllee1983/dbcli",
42761
- version: "0.4.0-beta",
42831
+ version: "0.5.0-beta",
42762
42832
  description: "Database CLI for AI agents",
42763
42833
  type: "module",
42764
42834
  publishConfig: {
@@ -42796,6 +42866,7 @@ var package_default = {
42796
42866
  dotenv: "^16.3.1",
42797
42867
  mysql2: "^3.20.0",
42798
42868
  pg: "^8.20.0",
42869
+ picocolors: "^1.1.1",
42799
42870
  zod: "^3.22.4"
42800
42871
  },
42801
42872
  devDependencies: {
@@ -43101,6 +43172,47 @@ var messageLoader = MessageLoader.getInstance();
43101
43172
  var t = (key) => messageLoader.t(key);
43102
43173
  var t_vars = (key, vars) => messageLoader.interpolate(key, vars);
43103
43174
 
43175
+ // src/utils/colors.ts
43176
+ var import_picocolors = __toESM(require_picocolors(), 1);
43177
+ var colors = {
43178
+ success: (text) => import_picocolors.default.green(text),
43179
+ error: (text) => import_picocolors.default.red(text),
43180
+ warn: (text) => import_picocolors.default.yellow(text),
43181
+ info: (text) => import_picocolors.default.blue(text),
43182
+ dim: (text) => import_picocolors.default.dim(text),
43183
+ bold: (text) => import_picocolors.default.bold(text),
43184
+ keyword: (text) => import_picocolors.default.blue(import_picocolors.default.bold(text))
43185
+ };
43186
+
43187
+ // src/utils/logger.ts
43188
+ function formatArgs(args) {
43189
+ return args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
43190
+ }
43191
+ function createLogger(level = 1 /* NORMAL */) {
43192
+ const write = (minLevel, prefix, args) => {
43193
+ if (level < minLevel)
43194
+ return;
43195
+ const message = `${prefix} ${formatArgs(args)}
43196
+ `;
43197
+ process.stderr.write(message);
43198
+ };
43199
+ return {
43200
+ error: (...args) => write(0 /* QUIET */, colors.error("[ERROR]"), args),
43201
+ warn: (...args) => write(1 /* NORMAL */, colors.warn("[WARN]"), args),
43202
+ info: (...args) => write(1 /* NORMAL */, colors.info("[INFO]"), args),
43203
+ verbose: (...args) => write(2 /* VERBOSE */, colors.dim("[VERBOSE]"), args),
43204
+ debug: (...args) => write(3 /* DEBUG */, colors.dim("[DEBUG]"), args),
43205
+ level
43206
+ };
43207
+ }
43208
+ var globalLogger = createLogger(1 /* NORMAL */);
43209
+ function setGlobalLogger(logger) {
43210
+ globalLogger = logger;
43211
+ }
43212
+ function getLogger() {
43213
+ return globalLogger;
43214
+ }
43215
+
43104
43216
  // src/utils/errors.ts
43105
43217
  class EnvParseError extends Error {
43106
43218
  constructor(message) {
@@ -48210,7 +48322,7 @@ var Table = require_table();
48210
48322
  class TableFormatter {
48211
48323
  format(columns) {
48212
48324
  const table = new Table({
48213
- head: ["Column", "Type", "Nullable", "Default", "Key"],
48325
+ head: ["Column", "Type", "Nullable", "Default", "Key"].map((h) => colors.bold(h)),
48214
48326
  style: { compact: false, "padding-left": 1, "padding-right": 1 },
48215
48327
  colWidths: [25, 25, 10, 25, 20]
48216
48328
  });
@@ -48236,7 +48348,7 @@ class TableFormatter {
48236
48348
  class TableListFormatter {
48237
48349
  format(tables) {
48238
48350
  const table = new Table({
48239
- head: ["Table", "Columns", "Rows", "Engine"],
48351
+ head: ["Table", "Columns", "Rows", "Engine"].map((h) => colors.bold(h)),
48240
48352
  style: { compact: false, "padding-left": 1, "padding-right": 1 },
48241
48353
  colWidths: [30, 12, 15, 15]
48242
48354
  });
@@ -50824,8 +50936,637 @@ var statusCommand = new Command("status").description("Show current configuratio
50824
50936
  }
50825
50937
  });
50826
50938
 
50939
+ // src/commands/doctor.ts
50940
+ import { join as join3 } from "path";
50941
+ var SENSITIVE_PATTERNS = [
50942
+ "password",
50943
+ "passwd",
50944
+ "secret",
50945
+ "token",
50946
+ "api_key",
50947
+ "apikey",
50948
+ "access_key",
50949
+ "private_key",
50950
+ "credential",
50951
+ "auth_token",
50952
+ "refresh_token",
50953
+ "session_token",
50954
+ "ssn",
50955
+ "credit_card"
50956
+ ];
50957
+ function compareSemver(a, b) {
50958
+ const pa = a.split(".").map(Number);
50959
+ const pb = b.split(".").map(Number);
50960
+ for (let i = 0;i < 3; i++) {
50961
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
50962
+ if (diff !== 0)
50963
+ return diff;
50964
+ }
50965
+ return 0;
50966
+ }
50967
+ var runDoctorChecks = {
50968
+ checkBunVersion(current, required) {
50969
+ const passes = compareSemver(current, required) >= 0;
50970
+ return {
50971
+ group: "Environment",
50972
+ label: "Bun version",
50973
+ status: passes ? "pass" : "error",
50974
+ message: passes ? `Bun v${current} (meets >= ${required})` : `Bun v${current} is below required >= ${required}`
50975
+ };
50976
+ },
50977
+ async checkLatestVersion(currentVersion) {
50978
+ try {
50979
+ const response = await fetch("https://registry.npmjs.org/@carllee1983/dbcli/latest", { signal: AbortSignal.timeout(5000) });
50980
+ if (!response.ok)
50981
+ throw new Error(`HTTP ${response.status}`);
50982
+ const data = await response.json();
50983
+ const latest = data.version;
50984
+ const isLatest = currentVersion === latest;
50985
+ return {
50986
+ group: "Environment",
50987
+ label: "dbcli version",
50988
+ status: isLatest ? "pass" : "warn",
50989
+ message: isLatest ? `dbcli v${currentVersion} (latest)` : `dbcli v${currentVersion} (latest: ${latest})`
50990
+ };
50991
+ } catch {
50992
+ return {
50993
+ group: "Environment",
50994
+ label: "dbcli version",
50995
+ status: "pass",
50996
+ message: `dbcli v${currentVersion} (version check skipped)`
50997
+ };
50998
+ }
50999
+ },
51000
+ async checkConfigExists(configPath, existsFn) {
51001
+ const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(join3(configPath, "config.json")).exists();
51002
+ return {
51003
+ group: "Configuration",
51004
+ label: "Config exists",
51005
+ status: exists ? "pass" : "error",
51006
+ message: exists ? `Config found: ${configPath}` : `No config found at ${configPath}. Run "dbcli init" first.`
51007
+ };
51008
+ },
51009
+ checkBlacklistCompleteness(tableColumns, blacklistedColumns) {
51010
+ const unprotected = [];
51011
+ for (const [table, columns] of tableColumns) {
51012
+ const blacklisted = blacklistedColumns.get(table) ?? new Set;
51013
+ for (const col of columns) {
51014
+ const colLower = col.toLowerCase();
51015
+ const isSensitive = SENSITIVE_PATTERNS.some((p) => colLower.includes(p));
51016
+ if (isSensitive && !blacklisted.has(col)) {
51017
+ unprotected.push(`${table}.${col}`);
51018
+ }
51019
+ }
51020
+ }
51021
+ if (unprotected.length === 0) {
51022
+ return {
51023
+ group: "Configuration",
51024
+ label: "Blacklist completeness",
51025
+ status: "pass",
51026
+ message: "All detected sensitive columns are protected"
51027
+ };
51028
+ }
51029
+ return {
51030
+ group: "Configuration",
51031
+ label: "Blacklist completeness",
51032
+ status: "warn",
51033
+ message: `Consider protecting: ${unprotected.join(", ")}`
51034
+ };
51035
+ },
51036
+ checkSchemaCacheFreshness(lastUpdated) {
51037
+ if (!lastUpdated) {
51038
+ return {
51039
+ group: "Connection & Data",
51040
+ label: "Schema cache",
51041
+ status: "warn",
51042
+ message: 'No schema cache found \u2014 run "dbcli schema --refresh"'
51043
+ };
51044
+ }
51045
+ const ageMs = Date.now() - new Date(lastUpdated).getTime();
51046
+ const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1000));
51047
+ if (ageDays > 7) {
51048
+ return {
51049
+ group: "Connection & Data",
51050
+ label: "Schema cache",
51051
+ status: "warn",
51052
+ message: `Schema cache is ${ageDays} days old \u2014 run "dbcli schema --refresh"`
51053
+ };
51054
+ }
51055
+ return {
51056
+ group: "Connection & Data",
51057
+ label: "Schema cache",
51058
+ status: "pass",
51059
+ message: `Schema cache is ${ageDays} day(s) old`
51060
+ };
51061
+ },
51062
+ checkLargeTables(tables) {
51063
+ const large = tables.filter((t7) => (t7.estimatedRowCount ?? 0) > 1e6);
51064
+ if (large.length === 0) {
51065
+ return {
51066
+ group: "Connection & Data",
51067
+ label: "Large tables",
51068
+ status: "pass",
51069
+ message: "No tables exceed 1M rows"
51070
+ };
51071
+ }
51072
+ const list = large.map((t7) => `${t7.name} (${((t7.estimatedRowCount ?? 0) / 1e6).toFixed(1)}M rows)`).join(", ");
51073
+ return {
51074
+ group: "Connection & Data",
51075
+ label: "Large tables",
51076
+ status: "warn",
51077
+ message: `Large tables: ${list}`
51078
+ };
51079
+ },
51080
+ formatTextOutput(results, version) {
51081
+ const lines2 = [`dbcli doctor v${version}`, ""];
51082
+ const groups = ["Environment", "Configuration", "Connection & Data"];
51083
+ for (const group of groups) {
51084
+ const groupResults = results.filter((r) => r.group === group);
51085
+ if (groupResults.length === 0)
51086
+ continue;
51087
+ lines2.push(group);
51088
+ for (const r of groupResults) {
51089
+ const icon = r.status === "pass" ? colors.success("\u2713") : r.status === "warn" ? colors.warn("\u26A0") : colors.error("\u2717");
51090
+ lines2.push(` ${icon} ${r.message}`);
51091
+ }
51092
+ lines2.push("");
51093
+ }
51094
+ const passed = results.filter((r) => r.status === "pass").length;
51095
+ const warnings = results.filter((r) => r.status === "warn").length;
51096
+ const errors3 = results.filter((r) => r.status === "error").length;
51097
+ lines2.push(`Summary: ${passed} passed, ${warnings} warning(s), ${errors3} error(s)`);
51098
+ return lines2.join(`
51099
+ `);
51100
+ }
51101
+ };
51102
+ var doctorCommand = new Command("doctor").description("Run diagnostic checks on dbcli configuration, environment, and connection").option("--format <type>", "Output format: text, json", "text").action(async (options) => {
51103
+ const logger = getLogger();
51104
+ const results = [];
51105
+ const configPath = doctorCommand.parent?.opts().config ?? ".dbcli";
51106
+ const bunVersion = process.versions.bun ?? "unknown";
51107
+ const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.3.3";
51108
+ results.push(runDoctorChecks.checkBunVersion(bunVersion, requiredBun));
51109
+ results.push(await runDoctorChecks.checkLatestVersion(package_default.version));
51110
+ const configExists = await runDoctorChecks.checkConfigExists(configPath);
51111
+ results.push(configExists);
51112
+ if (configExists.status !== "error") {
51113
+ try {
51114
+ const config = await configModule.read(configPath);
51115
+ results.push({
51116
+ group: "Configuration",
51117
+ label: "Config valid",
51118
+ status: "pass",
51119
+ message: "Config valid"
51120
+ });
51121
+ results.push({
51122
+ group: "Configuration",
51123
+ label: "Permission",
51124
+ status: "pass",
51125
+ message: `Permission: ${config.permission}`
51126
+ });
51127
+ const blacklistedColumns = new Map;
51128
+ if (config.blacklist?.columns) {
51129
+ for (const [table, cols] of Object.entries(config.blacklist.columns)) {
51130
+ blacklistedColumns.set(table, new Set(cols));
51131
+ }
51132
+ }
51133
+ try {
51134
+ const adapter = AdapterFactory.createAdapter(config.connection);
51135
+ await adapter.connect();
51136
+ results.push({
51137
+ group: "Connection & Data",
51138
+ label: "Connection",
51139
+ status: "pass",
51140
+ message: `Connected to ${config.connection.system} ${config.connection.database}@${config.connection.host}:${config.connection.port}`
51141
+ });
51142
+ try {
51143
+ const tables = await adapter.listTables();
51144
+ const tableColumns = new Map;
51145
+ for (const t7 of tables) {
51146
+ tableColumns.set(t7.name, t7.columns.map((c) => c.name));
51147
+ }
51148
+ results.push(runDoctorChecks.checkBlacklistCompleteness(tableColumns, blacklistedColumns));
51149
+ results.push(runDoctorChecks.checkLargeTables(tables));
51150
+ } catch {
51151
+ logger.debug("Could not list tables for blacklist/large table check");
51152
+ }
51153
+ try {
51154
+ const indexPath = join3(configPath, "schemas", "index.json");
51155
+ const indexFile = Bun.file(indexPath);
51156
+ if (await indexFile.exists()) {
51157
+ const indexContent = await indexFile.text();
51158
+ const index = JSON.parse(indexContent);
51159
+ results.push(runDoctorChecks.checkSchemaCacheFreshness(index.updatedAt ?? null));
51160
+ } else {
51161
+ results.push(runDoctorChecks.checkSchemaCacheFreshness(null));
51162
+ }
51163
+ } catch {
51164
+ results.push(runDoctorChecks.checkSchemaCacheFreshness(null));
51165
+ }
51166
+ await adapter.disconnect();
51167
+ } catch (error) {
51168
+ results.push({
51169
+ group: "Connection & Data",
51170
+ label: "Connection",
51171
+ status: "error",
51172
+ message: `Connection failed: ${error.message}`
51173
+ });
51174
+ }
51175
+ } catch (error) {
51176
+ results.push({
51177
+ group: "Configuration",
51178
+ label: "Config valid",
51179
+ status: "error",
51180
+ message: `Config invalid: ${error.message}`
51181
+ });
51182
+ }
51183
+ }
51184
+ const hasError = results.some((r) => r.status === "error");
51185
+ if (options.format === "json") {
51186
+ console.log(JSON.stringify({ results, hasError }, null, 2));
51187
+ } else {
51188
+ console.log(runDoctorChecks.formatTextOutput(results, package_default.version));
51189
+ }
51190
+ if (hasError) {
51191
+ process.exit(1);
51192
+ }
51193
+ });
51194
+
51195
+ // src/commands/completion.ts
51196
+ import { join as join4 } from "path";
51197
+ import { homedir as homedir2 } from "os";
51198
+ function extractCommands(program2) {
51199
+ return program2.commands.map((cmd) => ({
51200
+ name: cmd.name(),
51201
+ options: cmd.options.map((o) => o.long ?? o.short ?? "").filter(Boolean)
51202
+ }));
51203
+ }
51204
+ function extractGlobalOptions(program2) {
51205
+ return program2.options.map((o) => o.long ?? o.short ?? "").filter(Boolean);
51206
+ }
51207
+ function generateBashCompletion(commands, globalOptions) {
51208
+ const cmdNames = commands.map((c) => c.name).join(" ");
51209
+ const globalOpts = globalOptions.join(" ");
51210
+ const caseEntries = commands.map((c) => ` ${c.name})
51211
+ COMPREPLY=( $(compgen -W "${c.options.join(" ")}" -- "\${cur}") )
51212
+ ;;`).join(`
51213
+ `);
51214
+ return `#!/bin/bash
51215
+ # dbcli bash completion \u2014 auto-generated, do not edit
51216
+ _dbcli_completions() {
51217
+ local cur prev commands
51218
+ cur="\${COMP_WORDS[COMP_CWORD]}"
51219
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
51220
+ commands="${cmdNames}"
51221
+
51222
+ if [[ \${COMP_CWORD} -eq 1 ]]; then
51223
+ COMPREPLY=( $(compgen -W "\${commands} ${globalOpts}" -- "\${cur}") )
51224
+ return 0
51225
+ fi
51226
+
51227
+ case "\${COMP_WORDS[1]}" in
51228
+ ${caseEntries}
51229
+ *)
51230
+ COMPREPLY=( $(compgen -W "${globalOpts}" -- "\${cur}") )
51231
+ ;;
51232
+ esac
51233
+ }
51234
+ complete -F _dbcli_completions dbcli
51235
+ `;
51236
+ }
51237
+ function generateZshCompletion(commands, globalOptions) {
51238
+ const cmdLines = commands.map((c) => ` '${c.name}:${c.name} command'`).join(`
51239
+ `);
51240
+ const subcmdCases = commands.map((c) => {
51241
+ const opts = c.options.map((o) => `'${o}[${o}]'`).join(" ");
51242
+ return ` ${c.name})
51243
+ _arguments ${opts}
51244
+ ;;`;
51245
+ }).join(`
51246
+ `);
51247
+ const globalOpts = globalOptions.map((o) => `'${o}[${o}]'`).join(" ");
51248
+ return `#compdef dbcli
51249
+ # dbcli zsh completion \u2014 auto-generated, do not edit
51250
+ _dbcli() {
51251
+ local -a commands
51252
+ commands=(
51253
+ ${cmdLines}
51254
+ )
51255
+
51256
+ _arguments -C \\
51257
+ ${globalOpts} \\
51258
+ '1:command:->cmd' \\
51259
+ '*::arg:->args'
51260
+
51261
+ case "$state" in
51262
+ cmd)
51263
+ _describe 'command' commands
51264
+ ;;
51265
+ args)
51266
+ case "$words[1]" in
51267
+ ${subcmdCases}
51268
+ esac
51269
+ ;;
51270
+ esac
51271
+ }
51272
+ _dbcli
51273
+ `;
51274
+ }
51275
+ function generateFishCompletion(commands, globalOptions) {
51276
+ const lines2 = [
51277
+ "# dbcli fish completion \u2014 auto-generated, do not edit",
51278
+ ""
51279
+ ];
51280
+ for (const opt of globalOptions) {
51281
+ const longName = opt.replace(/^--/, "");
51282
+ lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -l ${longName} -d '${opt}'`);
51283
+ }
51284
+ for (const cmd of commands) {
51285
+ lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -a ${cmd.name} -d '${cmd.name} command'`);
51286
+ }
51287
+ for (const cmd of commands) {
51288
+ for (const opt of cmd.options) {
51289
+ const longName = opt.replace(/^--/, "");
51290
+ lines2.push(`complete -c dbcli -n '__fish_seen_subcommand_from ${cmd.name}' -l ${longName} -d '${opt}'`);
51291
+ }
51292
+ }
51293
+ return lines2.join(`
51294
+ `) + `
51295
+ `;
51296
+ }
51297
+ function getInstallPath2(shell) {
51298
+ const home = homedir2();
51299
+ switch (shell) {
51300
+ case "bash":
51301
+ return join4(home, ".bashrc");
51302
+ case "zsh":
51303
+ return join4(home, ".zshrc");
51304
+ case "fish":
51305
+ return join4(home, ".config", "fish", "completions", "dbcli.fish");
51306
+ default:
51307
+ throw new Error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
51308
+ }
51309
+ }
51310
+ function detectShell() {
51311
+ const shellEnv = process.env.SHELL ?? "";
51312
+ if (shellEnv.includes("zsh"))
51313
+ return "zsh";
51314
+ if (shellEnv.includes("bash"))
51315
+ return "bash";
51316
+ if (shellEnv.includes("fish"))
51317
+ return "fish";
51318
+ return "bash";
51319
+ }
51320
+ var MARKER_START = "# >>> dbcli completion >>>";
51321
+ var MARKER_END = "# <<< dbcli completion <<<";
51322
+ async function installCompletion(shell, script) {
51323
+ const targetPath = getInstallPath2(shell);
51324
+ if (shell === "fish") {
51325
+ const dir = join4(homedir2(), ".config", "fish", "completions");
51326
+ await Bun.$`mkdir -p ${dir}`.quiet();
51327
+ await Bun.file(targetPath).write(script);
51328
+ console.log(colors.success(`\u2713 Fish completion installed to ${targetPath}`));
51329
+ return;
51330
+ }
51331
+ const file = Bun.file(targetPath);
51332
+ let content = "";
51333
+ if (await file.exists()) {
51334
+ content = await file.text();
51335
+ }
51336
+ const markerRegex = new RegExp(`${MARKER_START}[\\s\\S]*?${MARKER_END}\\n?`, "g");
51337
+ content = content.replace(markerRegex, "");
51338
+ const block = `
51339
+ ${MARKER_START}
51340
+ eval "$(dbcli completion ${shell})"
51341
+ ${MARKER_END}
51342
+ `;
51343
+ content = content.trimEnd() + `
51344
+ ` + block;
51345
+ await Bun.file(targetPath).write(content);
51346
+ console.log(colors.success(`\u2713 Completion installed to ${targetPath}`));
51347
+ console.log(colors.info(` Run: source ${targetPath}`));
51348
+ }
51349
+ var completionCommand = new Command("completion").description("Generate shell completion scripts (bash, zsh, fish)").argument("[shell]", "Shell type: bash, zsh, fish").option("--install [shell]", "Auto-install completion to shell rc file").action(async (shellArg, options) => {
51350
+ const parentProgram = completionCommand.parent;
51351
+ if (!parentProgram) {
51352
+ console.error(colors.error("Error: completion command must be registered to a program"));
51353
+ process.exit(1);
51354
+ }
51355
+ const commands = extractCommands(parentProgram);
51356
+ const globalOptions = extractGlobalOptions(parentProgram);
51357
+ if (options.install !== undefined) {
51358
+ const shell2 = typeof options.install === "string" ? options.install : shellArg ?? detectShell();
51359
+ const generators2 = {
51360
+ bash: generateBashCompletion,
51361
+ zsh: generateZshCompletion,
51362
+ fish: generateFishCompletion
51363
+ };
51364
+ const generate2 = generators2[shell2];
51365
+ if (!generate2) {
51366
+ console.error(colors.error(`Unsupported shell: ${shell2}. Supported: bash, zsh, fish`));
51367
+ process.exit(1);
51368
+ }
51369
+ const script = generate2(commands, globalOptions);
51370
+ await installCompletion(shell2, script);
51371
+ return;
51372
+ }
51373
+ const shell = shellArg ?? detectShell();
51374
+ const generators = {
51375
+ bash: generateBashCompletion,
51376
+ zsh: generateZshCompletion,
51377
+ fish: generateFishCompletion
51378
+ };
51379
+ const generate = generators[shell];
51380
+ if (!generate) {
51381
+ console.error(colors.error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`));
51382
+ process.exit(1);
51383
+ }
51384
+ process.stdout.write(generate(commands, globalOptions));
51385
+ });
51386
+
51387
+ // src/utils/version-check.ts
51388
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@carllee1983/dbcli/latest";
51389
+ var STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
51390
+ var FETCH_TIMEOUT_MS = 3000;
51391
+ function compareVersions(a, b) {
51392
+ const stripSuffix = (v) => v.replace(/-.*$/, "");
51393
+ const pa = stripSuffix(a).split(".").map(Number);
51394
+ const pb = stripSuffix(b).split(".").map(Number);
51395
+ for (let i = 0;i < 3; i++) {
51396
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
51397
+ if (diff !== 0)
51398
+ return diff;
51399
+ }
51400
+ if (a === b)
51401
+ return 0;
51402
+ const aHasSuffix = a.includes("-");
51403
+ const bHasSuffix = b.includes("-");
51404
+ if (!aHasSuffix && bHasSuffix)
51405
+ return 1;
51406
+ if (aHasSuffix && !bHasSuffix)
51407
+ return -1;
51408
+ return a.localeCompare(b);
51409
+ }
51410
+ function isStale(checkedAt) {
51411
+ const checked = new Date(checkedAt).getTime();
51412
+ if (isNaN(checked))
51413
+ return true;
51414
+ return Date.now() - checked >= STALE_THRESHOLD_MS;
51415
+ }
51416
+ async function fetchLatestVersion() {
51417
+ try {
51418
+ const response = await fetch(NPM_REGISTRY_URL, {
51419
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
51420
+ });
51421
+ if (!response.ok)
51422
+ return null;
51423
+ const data = await response.json();
51424
+ return data.version ?? null;
51425
+ } catch {
51426
+ return null;
51427
+ }
51428
+ }
51429
+ async function checkForUpdate(currentVersion, cachePath, existingCache) {
51430
+ let cache = existingCache ?? null;
51431
+ if (cache === undefined && cachePath) {
51432
+ try {
51433
+ const cacheFile = Bun.file(`${cachePath}/version-check.json`);
51434
+ if (await cacheFile.exists()) {
51435
+ cache = await cacheFile.json();
51436
+ }
51437
+ } catch {
51438
+ cache = null;
51439
+ }
51440
+ }
51441
+ if (cache && !isStale(cache.checkedAt)) {
51442
+ return {
51443
+ hasUpdate: compareVersions(cache.latestVersion, currentVersion) > 0,
51444
+ latestVersion: cache.latestVersion
51445
+ };
51446
+ }
51447
+ const latestVersion = await fetchLatestVersion();
51448
+ if (!latestVersion)
51449
+ return null;
51450
+ if (cachePath) {
51451
+ try {
51452
+ const newCache = {
51453
+ latestVersion,
51454
+ checkedAt: new Date().toISOString()
51455
+ };
51456
+ await Bun.write(`${cachePath}/version-check.json`, JSON.stringify(newCache, null, 2));
51457
+ } catch {}
51458
+ }
51459
+ return {
51460
+ hasUpdate: compareVersions(latestVersion, currentVersion) > 0,
51461
+ latestVersion
51462
+ };
51463
+ }
51464
+
51465
+ // src/commands/upgrade.ts
51466
+ function formatAlreadyUpToDate(version) {
51467
+ return colors.success(`\u2713 Already up to date (v${version})`);
51468
+ }
51469
+ function formatUpgradeMessage(currentVersion, latestVersion) {
51470
+ return [
51471
+ colors.info(` Current version : v${currentVersion}`),
51472
+ colors.success(` Latest version : v${latestVersion}`)
51473
+ ].join(`
51474
+ `);
51475
+ }
51476
+ function formatUpdateHint(latestVersion) {
51477
+ return colors.warn(`[INFO] dbcli v${latestVersion} available. Run "dbcli upgrade" to upgrade.`);
51478
+ }
51479
+ var upgradeCommand = new Command("upgrade").description("Check for updates and upgrade dbcli to the latest version").option("--check", "Only check for updates, do not upgrade").action(async (options) => {
51480
+ const configPath = upgradeCommand.parent?.opts().config ?? ".dbcli";
51481
+ const currentVersion = package_default.version;
51482
+ console.log(colors.bold("Checking for updates..."));
51483
+ let cachePath = null;
51484
+ try {
51485
+ const file = Bun.file(configPath);
51486
+ const isDir = !configPath.includes(".") || await file.exists() === false;
51487
+ if (isDir) {
51488
+ cachePath = configPath;
51489
+ }
51490
+ } catch {
51491
+ cachePath = null;
51492
+ }
51493
+ const result = await checkForUpdate(currentVersion, cachePath);
51494
+ if (!result) {
51495
+ console.error(colors.warn("\u26A0 Could not check for updates (network error or registry unavailable)"));
51496
+ process.exit(0);
51497
+ }
51498
+ if (!result.hasUpdate) {
51499
+ console.log(formatAlreadyUpToDate(currentVersion));
51500
+ process.exit(0);
51501
+ }
51502
+ console.log(colors.warn(`
51503
+ New version available: v${result.latestVersion}`));
51504
+ console.log(formatUpgradeMessage(currentVersion, result.latestVersion));
51505
+ console.log();
51506
+ if (options.check) {
51507
+ console.log(colors.dim(' Run "dbcli upgrade" to install the update.'));
51508
+ process.exit(0);
51509
+ }
51510
+ console.log(colors.bold("Upgrading..."));
51511
+ console.log(colors.dim(` bun add -g @carllee1983/dbcli@latest`));
51512
+ console.log();
51513
+ const proc = Bun.$`bun add -g @carllee1983/dbcli@latest`.nothrow();
51514
+ const result2 = await proc;
51515
+ if (result2.exitCode === 0) {
51516
+ console.log(colors.success(`
51517
+ \u2713 Successfully upgraded to v${result.latestVersion}`));
51518
+ } else {
51519
+ console.error(colors.error(`
51520
+ \u2717 Upgrade failed. Try running manually:`));
51521
+ console.error(colors.dim(" bun add -g @carllee1983/dbcli@latest"));
51522
+ process.exit(1);
51523
+ }
51524
+ });
51525
+
50827
51526
  // src/cli.ts
50828
- var program2 = new Command().name("dbcli").description("Database CLI for AI agents").version(package_default.version).option("--config <path>", "Path to .dbcli config file", ".dbcli");
51527
+ import { join as join5 } from "path";
51528
+ var _bgVersionCheckResult;
51529
+ var program2 = new Command().name("dbcli").description("Database CLI for AI agents").version(package_default.version).option("--no-color", "Disable colored output").option("-v, --verbose", "Increase verbosity (-v verbose, -vv debug)", (_, prev) => prev + 1, 0).option("-q, --quiet", "Suppress non-essential output").option("--config <path>", "Path to .dbcli config file", ".dbcli");
51530
+ program2.hook("preAction", (thisCommand, actionCommand) => {
51531
+ const opts = thisCommand.opts();
51532
+ if (opts.color === false) {
51533
+ process.env.NO_COLOR = "1";
51534
+ }
51535
+ let level = 1 /* NORMAL */;
51536
+ if (opts.quiet) {
51537
+ level = 0 /* QUIET */;
51538
+ } else if (opts.verbose >= 2) {
51539
+ level = 3 /* DEBUG */;
51540
+ } else if (opts.verbose >= 1) {
51541
+ level = 2 /* VERBOSE */;
51542
+ }
51543
+ setGlobalLogger(createLogger(level));
51544
+ const isUpgradeCommand = actionCommand.name() === "upgrade";
51545
+ if (!opts.quiet && !isUpgradeCommand) {
51546
+ const configPath = opts.config ?? ".dbcli";
51547
+ (async () => {
51548
+ try {
51549
+ let cache = null;
51550
+ try {
51551
+ const cacheFile = Bun.file(join5(configPath, "version-check.json"));
51552
+ if (await cacheFile.exists()) {
51553
+ cache = await cacheFile.json();
51554
+ }
51555
+ } catch {}
51556
+ const result = await checkForUpdate(package_default.version, configPath, cache);
51557
+ _bgVersionCheckResult = result;
51558
+ } catch {
51559
+ _bgVersionCheckResult = null;
51560
+ }
51561
+ })();
51562
+ }
51563
+ });
51564
+ program2.hook("postAction", () => {
51565
+ if (_bgVersionCheckResult?.hasUpdate) {
51566
+ process.stderr.write(formatUpdateHint(_bgVersionCheckResult.latestVersion) + `
51567
+ `);
51568
+ }
51569
+ });
50829
51570
  program2.addCommand(initCommand);
50830
51571
  program2.addCommand(listCommand);
50831
51572
  program2.addCommand(schemaCommand);
@@ -50885,6 +51626,9 @@ program2.addCommand(blacklistCommand);
50885
51626
  program2.addCommand(checkCommand);
50886
51627
  program2.addCommand(diffCommand);
50887
51628
  program2.addCommand(statusCommand);
51629
+ program2.addCommand(doctorCommand);
51630
+ program2.addCommand(completionCommand);
51631
+ program2.addCommand(upgradeCommand);
50888
51632
  if (!process.argv.slice(2).length) {
50889
51633
  program2.outputHelp();
50890
51634
  }