@dosu/cli 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/dosu.js +485 -203
  2. package/package.json +1 -1
package/bin/dosu.js CHANGED
@@ -2118,6 +2118,192 @@ function emptyConfig() {
2118
2118
  var MODE_OSS = "oss";
2119
2119
  var init_config = () => {};
2120
2120
 
2121
+ // node_modules/picocolors/picocolors.js
2122
+ var require_picocolors = __commonJS((exports, module) => {
2123
+ var p = process || {};
2124
+ var argv = p.argv || [];
2125
+ var env = p.env || {};
2126
+ 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);
2127
+ var formatter = (open, close, replace = open) => (input) => {
2128
+ let string = "" + input, index = string.indexOf(close, open.length);
2129
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2130
+ };
2131
+ var replaceClose = (string, close, replace, index) => {
2132
+ let result = "", cursor = 0;
2133
+ do {
2134
+ result += string.substring(cursor, index) + replace;
2135
+ cursor = index + close.length;
2136
+ index = string.indexOf(close, cursor);
2137
+ } while (~index);
2138
+ return result + string.substring(cursor);
2139
+ };
2140
+ var createColors = (enabled = isColorSupported) => {
2141
+ let f = enabled ? formatter : () => String;
2142
+ return {
2143
+ isColorSupported: enabled,
2144
+ reset: f("\x1B[0m", "\x1B[0m"),
2145
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2146
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2147
+ italic: f("\x1B[3m", "\x1B[23m"),
2148
+ underline: f("\x1B[4m", "\x1B[24m"),
2149
+ inverse: f("\x1B[7m", "\x1B[27m"),
2150
+ hidden: f("\x1B[8m", "\x1B[28m"),
2151
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
2152
+ black: f("\x1B[30m", "\x1B[39m"),
2153
+ red: f("\x1B[31m", "\x1B[39m"),
2154
+ green: f("\x1B[32m", "\x1B[39m"),
2155
+ yellow: f("\x1B[33m", "\x1B[39m"),
2156
+ blue: f("\x1B[34m", "\x1B[39m"),
2157
+ magenta: f("\x1B[35m", "\x1B[39m"),
2158
+ cyan: f("\x1B[36m", "\x1B[39m"),
2159
+ white: f("\x1B[37m", "\x1B[39m"),
2160
+ gray: f("\x1B[90m", "\x1B[39m"),
2161
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
2162
+ bgRed: f("\x1B[41m", "\x1B[49m"),
2163
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
2164
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
2165
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
2166
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
2167
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
2168
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
2169
+ blackBright: f("\x1B[90m", "\x1B[39m"),
2170
+ redBright: f("\x1B[91m", "\x1B[39m"),
2171
+ greenBright: f("\x1B[92m", "\x1B[39m"),
2172
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
2173
+ blueBright: f("\x1B[94m", "\x1B[39m"),
2174
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
2175
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
2176
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
2177
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2178
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
2179
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2180
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2181
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2182
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2183
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2184
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2185
+ };
2186
+ };
2187
+ module.exports = createColors();
2188
+ module.exports.createColors = createColors;
2189
+ });
2190
+
2191
+ // src/version/version.ts
2192
+ function getVersionString() {
2193
+ return `v${VERSION}`;
2194
+ }
2195
+ var VERSION = "0.9.0";
2196
+
2197
+ // src/debug/logger.ts
2198
+ import {
2199
+ appendFileSync,
2200
+ existsSync as existsSync2,
2201
+ mkdirSync as mkdirSync2,
2202
+ readFileSync as readFileSync2,
2203
+ statSync,
2204
+ writeFileSync as writeFileSync2
2205
+ } from "node:fs";
2206
+ import { join as join2 } from "node:path";
2207
+ function ensureInit() {
2208
+ if (!initialized) {
2209
+ initLogger({});
2210
+ }
2211
+ }
2212
+ function resolveLogPath() {
2213
+ if (!logFilePath) {
2214
+ const dir = getConfigDir();
2215
+ if (!existsSync2(dir)) {
2216
+ mkdirSync2(dir, { recursive: true, mode: 448 });
2217
+ }
2218
+ logFilePath = join2(dir, LOG_FILENAME);
2219
+ }
2220
+ return logFilePath;
2221
+ }
2222
+ function truncateIfNeeded() {
2223
+ try {
2224
+ const path = resolveLogPath();
2225
+ if (!existsSync2(path))
2226
+ return;
2227
+ const stat = statSync(path);
2228
+ if (stat.size <= MAX_LOG_SIZE)
2229
+ return;
2230
+ const content = readFileSync2(path);
2231
+ const start = content.length - TRUNCATE_KEEP;
2232
+ let lineStart = start;
2233
+ while (lineStart < content.length && content[lineStart] !== 10) {
2234
+ lineStart++;
2235
+ }
2236
+ lineStart = Math.min(lineStart + 1, content.length);
2237
+ writeFileSync2(path, content.subarray(lineStart), { mode: 384 });
2238
+ } catch {}
2239
+ }
2240
+ function writeSessionHeader() {
2241
+ try {
2242
+ const now = new Date().toISOString();
2243
+ const header = `
2244
+ ════════════════════════════════════════
2245
+ ` + `Session: ${now} | v${VERSION} | ${process.platform} ${process.arch} | node ${process.version}
2246
+ ` + `════════════════════════════════════════
2247
+ `;
2248
+ appendFileSync(resolveLogPath(), header, { mode: 384 });
2249
+ } catch {}
2250
+ }
2251
+ function initLogger(opts) {
2252
+ debugToConsole = opts.debug ?? false;
2253
+ try {
2254
+ resolveLogPath();
2255
+ truncateIfNeeded();
2256
+ writeSessionHeader();
2257
+ } catch {}
2258
+ initialized = true;
2259
+ }
2260
+ function writeEntry(level, mod, message) {
2261
+ ensureInit();
2262
+ const timestamp = new Date().toISOString();
2263
+ const line = `[${timestamp}] [${level}] [${mod}] ${message}
2264
+ `;
2265
+ try {
2266
+ appendFileSync(resolveLogPath(), line, { mode: 384 });
2267
+ } catch {}
2268
+ if (debugToConsole) {
2269
+ const colorize = {
2270
+ DEBUG: import_picocolors.default.dim,
2271
+ INFO: import_picocolors.default.cyan,
2272
+ WARN: import_picocolors.default.yellow,
2273
+ ERROR: import_picocolors.default.red
2274
+ }[level];
2275
+ console.error(colorize(line.trimEnd()));
2276
+ }
2277
+ }
2278
+ var import_picocolors, MAX_LOG_SIZE = 1048576, TRUNCATE_KEEP = 524288, LOG_FILENAME = "debug.log", initialized = false, debugToConsole = false, logFilePath = null, logger;
2279
+ var init_logger = __esm(() => {
2280
+ init_config();
2281
+ import_picocolors = __toESM(require_picocolors(), 1);
2282
+ logger = {
2283
+ init: initLogger,
2284
+ getLogPath() {
2285
+ return resolveLogPath();
2286
+ },
2287
+ debug(mod, message) {
2288
+ writeEntry("DEBUG", mod, message);
2289
+ },
2290
+ info(mod, message) {
2291
+ writeEntry("INFO", mod, message);
2292
+ },
2293
+ warn(mod, message) {
2294
+ writeEntry("WARN", mod, message);
2295
+ },
2296
+ error(mod, message) {
2297
+ writeEntry("ERROR", mod, message);
2298
+ },
2299
+ _resetForTesting() {
2300
+ initialized = false;
2301
+ debugToConsole = false;
2302
+ logFilePath = null;
2303
+ }
2304
+ };
2305
+ });
2306
+
2121
2307
  // src/config/constants.ts
2122
2308
  function getWebAppURL() {
2123
2309
  return "https://app.dosu.dev";
@@ -2133,7 +2319,7 @@ function getSupabaseAnonKey() {
2133
2319
  }
2134
2320
 
2135
2321
  // src/mcp/config-helpers.ts
2136
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
2322
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
2137
2323
  import { dirname } from "node:path";
2138
2324
  function mcpURL(deploymentID) {
2139
2325
  return `${getBackendURL()}/v1/mcp/deployments/${deploymentID}`;
@@ -2145,9 +2331,9 @@ function mcpHeaders(apiKey) {
2145
2331
  return { "X-Dosu-API-Key": apiKey };
2146
2332
  }
2147
2333
  function loadJSONConfig(path) {
2148
- if (!existsSync2(path))
2334
+ if (!existsSync3(path))
2149
2335
  return {};
2150
- let data = readFileSync2(path, "utf-8").trim();
2336
+ let data = readFileSync3(path, "utf-8").trim();
2151
2337
  if (!data)
2152
2338
  return {};
2153
2339
  if (path.endsWith(".jsonc")) {
@@ -2207,10 +2393,10 @@ function stripJSONComments(data) {
2207
2393
  }
2208
2394
  function saveJSONConfig(path, cfg) {
2209
2395
  const dir = dirname(path);
2210
- if (!existsSync2(dir)) {
2211
- mkdirSync2(dir, { recursive: true });
2396
+ if (!existsSync3(dir)) {
2397
+ mkdirSync3(dir, { recursive: true });
2212
2398
  }
2213
- writeFileSync2(path, JSON.stringify(cfg, null, 2));
2399
+ writeFileSync3(path, JSON.stringify(cfg, null, 2));
2214
2400
  }
2215
2401
  function isJSONKeyConfigured(configPath, topLevelKey) {
2216
2402
  const cfg = loadJSONConfig(configPath);
@@ -2245,21 +2431,21 @@ function removeJSONServer(configPath, topKey) {
2245
2431
  var init_config_helpers = () => {};
2246
2432
 
2247
2433
  // src/mcp/detect.ts
2248
- import { existsSync as existsSync3 } from "node:fs";
2434
+ import { existsSync as existsSync4 } from "node:fs";
2249
2435
  import { homedir, platform } from "node:os";
2250
- import { join as join2 } from "node:path";
2436
+ import { join as join3 } from "node:path";
2251
2437
  function isInstalled(paths) {
2252
- return paths.some((p) => existsSync3(expandHome(p)));
2438
+ return paths.some((p) => existsSync4(expandHome(p)));
2253
2439
  }
2254
2440
  function expandHome(path) {
2255
2441
  if (!path.startsWith("~"))
2256
2442
  return path;
2257
- return join2(homedir(), path.slice(1));
2443
+ return join3(homedir(), path.slice(1));
2258
2444
  }
2259
2445
  function appSupportDir() {
2260
2446
  switch (platform()) {
2261
2447
  case "darwin": {
2262
- return join2(homedir(), "Library", "Application Support");
2448
+ return join3(homedir(), "Library", "Application Support");
2263
2449
  }
2264
2450
  case "win32": {
2265
2451
  return process.env.APPDATA ?? "";
@@ -2268,7 +2454,7 @@ function appSupportDir() {
2268
2454
  const xdg = process.env.XDG_CONFIG_HOME;
2269
2455
  if (xdg)
2270
2456
  return xdg;
2271
- return join2(homedir(), ".config");
2457
+ return join3(homedir(), ".config");
2272
2458
  }
2273
2459
  }
2274
2460
  }
@@ -2349,7 +2535,7 @@ var init_antigravity = __esm(() => {
2349
2535
  });
2350
2536
 
2351
2537
  // src/mcp/providers/claude.ts
2352
- import { join as join3 } from "node:path";
2538
+ import { join as join4 } from "node:path";
2353
2539
  var ClaudeProvider = () => createJSONProvider({
2354
2540
  providerName: "Claude Code",
2355
2541
  providerID: "claude",
@@ -2358,22 +2544,22 @@ var ClaudeProvider = () => createJSONProvider({
2358
2544
  paths: ["~/.claude"],
2359
2545
  globalPath: "~/.claude.json",
2360
2546
  topKey: "mcpServers",
2361
- localConfigPath: (cwd) => join3(cwd, ".mcp.json")
2547
+ localConfigPath: (cwd) => join4(cwd, ".mcp.json")
2362
2548
  });
2363
2549
  var init_claude = __esm(() => {
2364
2550
  init_base();
2365
2551
  });
2366
2552
 
2367
2553
  // src/mcp/providers/claude-desktop.ts
2368
- import { join as join4 } from "node:path";
2554
+ import { join as join5 } from "node:path";
2369
2555
  var ClaudeDesktopProvider = () => ({
2370
2556
  name: () => "Claude Desktop",
2371
2557
  id: () => "claude-desktop",
2372
2558
  supportsLocal: () => false,
2373
2559
  priority: () => 2,
2374
- detectPaths: () => [join4(appSupportDir(), "Claude")],
2375
- isInstalled: () => isInstalled([join4(appSupportDir(), "Claude")]),
2376
- globalConfigPath: () => join4(appSupportDir(), "Claude", "claude_desktop_config.json"),
2560
+ detectPaths: () => [join5(appSupportDir(), "Claude")],
2561
+ isInstalled: () => isInstalled([join5(appSupportDir(), "Claude")]),
2562
+ globalConfigPath: () => join5(appSupportDir(), "Claude", "claude_desktop_config.json"),
2377
2563
  isConfigured: () => false,
2378
2564
  install() {
2379
2565
  throw new Error("this tool only supports local (stdio) servers and cannot be configured for remote MCP");
@@ -2387,14 +2573,14 @@ var init_claude_desktop = __esm(() => {
2387
2573
  });
2388
2574
 
2389
2575
  // src/mcp/providers/cline.ts
2390
- import { join as join5 } from "node:path";
2391
- var extensionDir = () => join5(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
2576
+ import { join as join6 } from "node:path";
2577
+ var extensionDir = () => join6(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
2392
2578
  providerName: "Cline",
2393
2579
  providerID: "cline",
2394
2580
  local: false,
2395
2581
  priorityValue: 11,
2396
2582
  paths: [extensionDir()],
2397
- globalPath: join5(extensionDir(), "settings", "cline_mcp_settings.json"),
2583
+ globalPath: join6(extensionDir(), "settings", "cline_mcp_settings.json"),
2398
2584
  topKey: "mcpServers",
2399
2585
  buildServer: (cfg) => ({
2400
2586
  url: mcpURL(cfg.deployment_id),
@@ -2410,7 +2596,7 @@ var init_cline = __esm(() => {
2410
2596
  });
2411
2597
 
2412
2598
  // src/mcp/providers/cline-cli.ts
2413
- import { join as join6 } from "node:path";
2599
+ import { join as join7 } from "node:path";
2414
2600
  function clineDir() {
2415
2601
  return process.env.CLINE_DIR ?? expandHome("~/.cline");
2416
2602
  }
@@ -2420,7 +2606,7 @@ var ClineCliProvider = () => createJSONProvider({
2420
2606
  local: false,
2421
2607
  priorityValue: 12,
2422
2608
  paths: [clineDir()],
2423
- globalPath: join6(clineDir(), "data", "settings", "cline_mcp_settings.json"),
2609
+ globalPath: join7(clineDir(), "data", "settings", "cline_mcp_settings.json"),
2424
2610
  topKey: "mcpServers",
2425
2611
  buildServer: (cfg) => ({
2426
2612
  url: mcpURL(cfg.deployment_id),
@@ -2436,26 +2622,26 @@ var init_cline_cli = __esm(() => {
2436
2622
  });
2437
2623
 
2438
2624
  // src/mcp/providers/codex.ts
2439
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
2440
- import { dirname as dirname2, join as join7 } from "node:path";
2625
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
2626
+ import { dirname as dirname2, join as join8 } from "node:path";
2441
2627
  function codexHome() {
2442
2628
  return process.env.CODEX_HOME ?? expandHome("~/.codex");
2443
2629
  }
2444
2630
  function getConfigPath2(global) {
2445
2631
  if (global)
2446
- return join7(codexHome(), "config.toml");
2447
- return join7(process.cwd(), ".codex", "config.toml");
2632
+ return join8(codexHome(), "config.toml");
2633
+ return join8(process.cwd(), ".codex", "config.toml");
2448
2634
  }
2449
2635
  function readTOML(path) {
2450
- if (!existsSync4(path))
2636
+ if (!existsSync5(path))
2451
2637
  return "";
2452
- return readFileSync3(path, "utf-8");
2638
+ return readFileSync4(path, "utf-8");
2453
2639
  }
2454
2640
  function writeTOML(path, content) {
2455
2641
  const dir = dirname2(path);
2456
- if (!existsSync4(dir))
2457
- mkdirSync3(dir, { recursive: true });
2458
- writeFileSync3(path, content);
2642
+ if (!existsSync5(dir))
2643
+ mkdirSync4(dir, { recursive: true });
2644
+ writeFileSync4(path, content);
2459
2645
  }
2460
2646
  function installDosuToTOML(path, cfg) {
2461
2647
  let content = readTOML(path);
@@ -2503,9 +2689,9 @@ var CodexProvider = () => ({
2503
2689
  priority: () => 8,
2504
2690
  detectPaths: () => ["~/.codex"],
2505
2691
  isInstalled: () => isInstalled(["~/.codex"]),
2506
- globalConfigPath: () => join7(codexHome(), "config.toml"),
2692
+ globalConfigPath: () => join8(codexHome(), "config.toml"),
2507
2693
  isConfigured: () => {
2508
- const content = readTOML(join7(codexHome(), "config.toml"));
2694
+ const content = readTOML(join8(codexHome(), "config.toml"));
2509
2695
  return content.includes("[mcp_servers.dosu]");
2510
2696
  },
2511
2697
  install(cfg, global) {
@@ -2527,10 +2713,10 @@ var init_codex = __esm(() => {
2527
2713
  });
2528
2714
 
2529
2715
  // src/mcp/providers/copilot.ts
2530
- import { join as join8 } from "node:path";
2716
+ import { join as join9 } from "node:path";
2531
2717
  function globalPath() {
2532
2718
  if (process.env.XDG_CONFIG_HOME) {
2533
- return join8(process.env.XDG_CONFIG_HOME, "mcp-config.json");
2719
+ return join9(process.env.XDG_CONFIG_HOME, "mcp-config.json");
2534
2720
  }
2535
2721
  return expandHome("~/.copilot/mcp-config.json");
2536
2722
  }
@@ -2556,7 +2742,7 @@ var CopilotProvider = () => ({
2556
2742
  };
2557
2743
  installJSONServer(globalPath(), "mcpServers", server);
2558
2744
  } else {
2559
- const configPath = join8(process.cwd(), ".vscode", "mcp.json");
2745
+ const configPath = join9(process.cwd(), ".vscode", "mcp.json");
2560
2746
  const server = {
2561
2747
  type: "http",
2562
2748
  url,
@@ -2569,7 +2755,7 @@ var CopilotProvider = () => ({
2569
2755
  if (global) {
2570
2756
  removeJSONServer(globalPath(), "mcpServers");
2571
2757
  } else {
2572
- const configPath = join8(process.cwd(), ".vscode", "mcp.json");
2758
+ const configPath = join9(process.cwd(), ".vscode", "mcp.json");
2573
2759
  removeJSONServer(configPath, "servers");
2574
2760
  }
2575
2761
  }
@@ -2581,7 +2767,7 @@ var init_copilot = __esm(() => {
2581
2767
  });
2582
2768
 
2583
2769
  // src/mcp/providers/cursor.ts
2584
- import { join as join9 } from "node:path";
2770
+ import { join as join10 } from "node:path";
2585
2771
  var CursorProvider = () => createJSONProvider({
2586
2772
  providerName: "Cursor",
2587
2773
  providerID: "cursor",
@@ -2594,7 +2780,7 @@ var CursorProvider = () => createJSONProvider({
2594
2780
  url: mcpURL(cfg.deployment_id),
2595
2781
  headers: mcpHeaders(cfg.api_key)
2596
2782
  }),
2597
- localConfigPath: (cwd) => join9(cwd, ".cursor", "mcp.json")
2783
+ localConfigPath: (cwd) => join10(cwd, ".cursor", "mcp.json")
2598
2784
  });
2599
2785
  var init_cursor = __esm(() => {
2600
2786
  init_config_helpers();
@@ -2602,7 +2788,7 @@ var init_cursor = __esm(() => {
2602
2788
  });
2603
2789
 
2604
2790
  // src/mcp/providers/gemini.ts
2605
- import { join as join10 } from "node:path";
2791
+ import { join as join11 } from "node:path";
2606
2792
  var GeminiProvider = () => createJSONProvider({
2607
2793
  providerName: "Gemini CLI",
2608
2794
  providerID: "gemini",
@@ -2611,7 +2797,7 @@ var GeminiProvider = () => createJSONProvider({
2611
2797
  paths: ["~/.gemini"],
2612
2798
  globalPath: "~/.gemini/settings.json",
2613
2799
  topKey: "mcpServers",
2614
- localConfigPath: (cwd) => join10(cwd, ".gemini", "settings.json")
2800
+ localConfigPath: (cwd) => join11(cwd, ".gemini", "settings.json")
2615
2801
  });
2616
2802
  var init_gemini = __esm(() => {
2617
2803
  init_base();
@@ -2642,14 +2828,14 @@ var init_manual = __esm(() => {
2642
2828
  });
2643
2829
 
2644
2830
  // src/mcp/providers/mcporter.ts
2645
- import { existsSync as existsSync5 } from "node:fs";
2646
- import { join as join11 } from "node:path";
2831
+ import { existsSync as existsSync6 } from "node:fs";
2832
+ import { join as join12 } from "node:path";
2647
2833
  function resolveGlobalConfigPath() {
2648
2834
  const jsonPath = expandHome("~/.mcporter/mcporter.json");
2649
- if (existsSync5(jsonPath))
2835
+ if (existsSync6(jsonPath))
2650
2836
  return jsonPath;
2651
2837
  const jsoncPath = expandHome("~/.mcporter/mcporter.jsonc");
2652
- if (existsSync5(jsoncPath))
2838
+ if (existsSync6(jsoncPath))
2653
2839
  return jsoncPath;
2654
2840
  return jsonPath;
2655
2841
  }
@@ -2665,7 +2851,7 @@ var MCPorterProvider = () => ({
2665
2851
  install(cfg, global) {
2666
2852
  if (cfg.mode !== MODE_OSS && !cfg.deployment_id)
2667
2853
  throw new Error("deployment ID is required");
2668
- const configPath = global ? resolveGlobalConfigPath() : join11(process.cwd(), "config", "mcporter.json");
2854
+ const configPath = global ? resolveGlobalConfigPath() : join12(process.cwd(), "config", "mcporter.json");
2669
2855
  const server = {
2670
2856
  type: "http",
2671
2857
  url: cfg.mode === MODE_OSS ? mcpBaseURL() : mcpURL(cfg.deployment_id),
@@ -2674,7 +2860,7 @@ var MCPorterProvider = () => ({
2674
2860
  installJSONServer(configPath, "mcpServers", server);
2675
2861
  },
2676
2862
  remove(global) {
2677
- const configPath = global ? resolveGlobalConfigPath() : join11(process.cwd(), "config", "mcporter.json");
2863
+ const configPath = global ? resolveGlobalConfigPath() : join12(process.cwd(), "config", "mcporter.json");
2678
2864
  removeJSONServer(configPath, "mcpServers");
2679
2865
  }
2680
2866
  });
@@ -2685,7 +2871,7 @@ var init_mcporter = __esm(() => {
2685
2871
  });
2686
2872
 
2687
2873
  // src/mcp/providers/opencode.ts
2688
- import { join as join12 } from "node:path";
2874
+ import { join as join13 } from "node:path";
2689
2875
  var OpenCodeProvider = () => createJSONProvider({
2690
2876
  providerName: "OpenCode",
2691
2877
  providerID: "opencode",
@@ -2700,7 +2886,7 @@ var OpenCodeProvider = () => createJSONProvider({
2700
2886
  enabled: true,
2701
2887
  headers: mcpHeaders(cfg.api_key)
2702
2888
  }),
2703
- localConfigPath: (cwd) => join12(cwd, "opencode.json")
2889
+ localConfigPath: (cwd) => join13(cwd, "opencode.json")
2704
2890
  });
2705
2891
  var init_opencode = __esm(() => {
2706
2892
  init_config_helpers();
@@ -2708,16 +2894,16 @@ var init_opencode = __esm(() => {
2708
2894
  });
2709
2895
 
2710
2896
  // src/mcp/providers/vscode.ts
2711
- import { join as join13 } from "node:path";
2897
+ import { join as join14 } from "node:path";
2712
2898
  var VSCodeProvider = () => createJSONProvider({
2713
2899
  providerName: "VS Code",
2714
2900
  providerID: "vscode",
2715
2901
  local: true,
2716
2902
  priorityValue: 6,
2717
- paths: [join13(appSupportDir(), "Code")],
2718
- globalPath: join13(appSupportDir(), "Code", "User", "mcp.json"),
2903
+ paths: [join14(appSupportDir(), "Code")],
2904
+ globalPath: join14(appSupportDir(), "Code", "User", "mcp.json"),
2719
2905
  topKey: "servers",
2720
- localConfigPath: (cwd) => join13(cwd, ".vscode", "mcp.json")
2906
+ localConfigPath: (cwd) => join14(cwd, ".vscode", "mcp.json")
2721
2907
  });
2722
2908
  var init_vscode = __esm(() => {
2723
2909
  init_detect();
@@ -2726,14 +2912,14 @@ var init_vscode = __esm(() => {
2726
2912
 
2727
2913
  // src/mcp/providers/windsurf.ts
2728
2914
  import { homedir as homedir2 } from "node:os";
2729
- import { join as join14 } from "node:path";
2915
+ import { join as join15 } from "node:path";
2730
2916
  var WindsurfProvider = () => createJSONProvider({
2731
2917
  providerName: "Windsurf",
2732
2918
  providerID: "windsurf",
2733
2919
  local: false,
2734
2920
  priorityValue: 9,
2735
- paths: [join14(homedir2(), ".codeium", "windsurf")],
2736
- globalPath: join14(homedir2(), ".codeium", "windsurf", "mcp_config.json"),
2921
+ paths: [join15(homedir2(), ".codeium", "windsurf")],
2922
+ globalPath: join15(homedir2(), ".codeium", "windsurf", "mcp_config.json"),
2737
2923
  topKey: "mcpServers"
2738
2924
  });
2739
2925
  var init_windsurf = __esm(() => {
@@ -2742,12 +2928,12 @@ var init_windsurf = __esm(() => {
2742
2928
 
2743
2929
  // src/mcp/providers/zed.ts
2744
2930
  import { platform as platform2 } from "node:os";
2745
- import { join as join15 } from "node:path";
2931
+ import { join as join16 } from "node:path";
2746
2932
  function zedConfigDir() {
2747
2933
  const os = platform2();
2748
2934
  if (os === "darwin" || os === "win32")
2749
- return join15(appSupportDir(), "Zed");
2750
- return join15(appSupportDir(), "zed");
2935
+ return join16(appSupportDir(), "Zed");
2936
+ return join16(appSupportDir(), "zed");
2751
2937
  }
2752
2938
  var ZedProvider = () => createJSONProvider({
2753
2939
  providerName: "Zed",
@@ -2755,7 +2941,7 @@ var ZedProvider = () => createJSONProvider({
2755
2941
  local: true,
2756
2942
  priorityValue: 10,
2757
2943
  paths: [zedConfigDir()],
2758
- globalPath: join15(zedConfigDir(), "settings.json"),
2944
+ globalPath: join16(zedConfigDir(), "settings.json"),
2759
2945
  topKey: "context_servers",
2760
2946
  buildServer: (cfg) => ({
2761
2947
  source: "custom",
@@ -2763,7 +2949,7 @@ var ZedProvider = () => createJSONProvider({
2763
2949
  url: mcpURL(cfg.deployment_id),
2764
2950
  headers: mcpHeaders(cfg.api_key)
2765
2951
  }),
2766
- localConfigPath: (cwd) => join15(cwd, ".zed", "settings.json")
2952
+ localConfigPath: (cwd) => join16(cwd, ".zed", "settings.json")
2767
2953
  });
2768
2954
  var init_zed = __esm(() => {
2769
2955
  init_config_helpers();
@@ -2877,76 +3063,6 @@ var require_src = __commonJS((exports, module) => {
2877
3063
  module.exports = { cursor, scroll, erase, beep };
2878
3064
  });
2879
3065
 
2880
- // node_modules/picocolors/picocolors.js
2881
- var require_picocolors = __commonJS((exports, module) => {
2882
- var p = process || {};
2883
- var argv = p.argv || [];
2884
- var env = p.env || {};
2885
- 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);
2886
- var formatter = (open, close, replace = open) => (input) => {
2887
- let string = "" + input, index = string.indexOf(close, open.length);
2888
- return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2889
- };
2890
- var replaceClose = (string, close, replace, index) => {
2891
- let result = "", cursor = 0;
2892
- do {
2893
- result += string.substring(cursor, index) + replace;
2894
- cursor = index + close.length;
2895
- index = string.indexOf(close, cursor);
2896
- } while (~index);
2897
- return result + string.substring(cursor);
2898
- };
2899
- var createColors = (enabled = isColorSupported) => {
2900
- let f = enabled ? formatter : () => String;
2901
- return {
2902
- isColorSupported: enabled,
2903
- reset: f("\x1B[0m", "\x1B[0m"),
2904
- bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2905
- dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2906
- italic: f("\x1B[3m", "\x1B[23m"),
2907
- underline: f("\x1B[4m", "\x1B[24m"),
2908
- inverse: f("\x1B[7m", "\x1B[27m"),
2909
- hidden: f("\x1B[8m", "\x1B[28m"),
2910
- strikethrough: f("\x1B[9m", "\x1B[29m"),
2911
- black: f("\x1B[30m", "\x1B[39m"),
2912
- red: f("\x1B[31m", "\x1B[39m"),
2913
- green: f("\x1B[32m", "\x1B[39m"),
2914
- yellow: f("\x1B[33m", "\x1B[39m"),
2915
- blue: f("\x1B[34m", "\x1B[39m"),
2916
- magenta: f("\x1B[35m", "\x1B[39m"),
2917
- cyan: f("\x1B[36m", "\x1B[39m"),
2918
- white: f("\x1B[37m", "\x1B[39m"),
2919
- gray: f("\x1B[90m", "\x1B[39m"),
2920
- bgBlack: f("\x1B[40m", "\x1B[49m"),
2921
- bgRed: f("\x1B[41m", "\x1B[49m"),
2922
- bgGreen: f("\x1B[42m", "\x1B[49m"),
2923
- bgYellow: f("\x1B[43m", "\x1B[49m"),
2924
- bgBlue: f("\x1B[44m", "\x1B[49m"),
2925
- bgMagenta: f("\x1B[45m", "\x1B[49m"),
2926
- bgCyan: f("\x1B[46m", "\x1B[49m"),
2927
- bgWhite: f("\x1B[47m", "\x1B[49m"),
2928
- blackBright: f("\x1B[90m", "\x1B[39m"),
2929
- redBright: f("\x1B[91m", "\x1B[39m"),
2930
- greenBright: f("\x1B[92m", "\x1B[39m"),
2931
- yellowBright: f("\x1B[93m", "\x1B[39m"),
2932
- blueBright: f("\x1B[94m", "\x1B[39m"),
2933
- magentaBright: f("\x1B[95m", "\x1B[39m"),
2934
- cyanBright: f("\x1B[96m", "\x1B[39m"),
2935
- whiteBright: f("\x1B[97m", "\x1B[39m"),
2936
- bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2937
- bgRedBright: f("\x1B[101m", "\x1B[49m"),
2938
- bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2939
- bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2940
- bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2941
- bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2942
- bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2943
- bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2944
- };
2945
- };
2946
- module.exports = createColors();
2947
- module.exports.createColors = createColors;
2948
- });
2949
-
2950
3066
  // node_modules/@clack/core/dist/index.mjs
2951
3067
  import { stdin as j, stdout as M } from "node:process";
2952
3068
  import * as g from "node:readline";
@@ -3369,17 +3485,17 @@ import y2 from "node:process";
3369
3485
  function ce() {
3370
3486
  return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
3371
3487
  }
3372
- var import_picocolors, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2, W2, C2, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2 = (t) => {
3488
+ var import_picocolors3, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2, W2, C2, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2 = (t) => {
3373
3489
  switch (t) {
3374
3490
  case "initial":
3375
3491
  case "active":
3376
- return import_picocolors.default.cyan(le);
3492
+ return import_picocolors3.default.cyan(le);
3377
3493
  case "cancel":
3378
- return import_picocolors.default.red(L2);
3494
+ return import_picocolors3.default.red(L2);
3379
3495
  case "error":
3380
- return import_picocolors.default.yellow(W2);
3496
+ return import_picocolors3.default.yellow(W2);
3381
3497
  case "submit":
3382
- return import_picocolors.default.green(C2);
3498
+ return import_picocolors3.default.green(C2);
3383
3499
  }
3384
3500
  }, G2 = (t) => {
3385
3501
  const { cursor: n, options: r, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
@@ -3388,23 +3504,23 @@ var import_picocolors, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2,
3388
3504
  const $2 = a < r.length && l2 > 0, g2 = a < r.length && l2 + a < r.length;
3389
3505
  return r.slice(l2, l2 + a).map((p2, v, f) => {
3390
3506
  const j2 = v === 0 && $2, E = v === f.length - 1 && g2;
3391
- return j2 || E ? import_picocolors.default.dim("...") : i(p2, v + l2 === n);
3507
+ return j2 || E ? import_picocolors3.default.dim("...") : i(p2, v + l2 === n);
3392
3508
  });
3393
3509
  }, ye = (t) => {
3394
3510
  const n = t.active ?? "Yes", r = t.inactive ?? "No";
3395
3511
  return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
3396
- const i = `${import_picocolors.default.gray(o)}
3512
+ const i = `${import_picocolors3.default.gray(o)}
3397
3513
  ${b2(this.state)} ${t.message}
3398
3514
  `, s = this.value ? n : r;
3399
3515
  switch (this.state) {
3400
3516
  case "submit":
3401
- return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.dim(s)}`;
3517
+ return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.dim(s)}`;
3402
3518
  case "cancel":
3403
- return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}
3404
- ${import_picocolors.default.gray(o)}`;
3519
+ return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}
3520
+ ${import_picocolors3.default.gray(o)}`;
3405
3521
  default:
3406
- return `${i}${import_picocolors.default.cyan(o)} ${this.value ? `${import_picocolors.default.green(k2)} ${n}` : `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(r)}` : `${import_picocolors.default.green(k2)} ${r}`}
3407
- ${import_picocolors.default.cyan(d2)}
3522
+ return `${i}${import_picocolors3.default.cyan(o)} ${this.value ? `${import_picocolors3.default.green(k2)} ${n}` : `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(n)}`} ${import_picocolors3.default.dim("/")} ${this.value ? `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(r)}` : `${import_picocolors3.default.green(k2)} ${r}`}
3523
+ ${import_picocolors3.default.cyan(d2)}
3408
3524
  `;
3409
3525
  }
3410
3526
  } }).prompt();
@@ -3413,43 +3529,43 @@ ${import_picocolors.default.cyan(d2)}
3413
3529
  const s = r.label ?? String(r.value);
3414
3530
  switch (i) {
3415
3531
  case "selected":
3416
- return `${import_picocolors.default.dim(s)}`;
3532
+ return `${import_picocolors3.default.dim(s)}`;
3417
3533
  case "active":
3418
- return `${import_picocolors.default.green(k2)} ${s} ${r.hint ? import_picocolors.default.dim(`(${r.hint})`) : ""}`;
3534
+ return `${import_picocolors3.default.green(k2)} ${s} ${r.hint ? import_picocolors3.default.dim(`(${r.hint})`) : ""}`;
3419
3535
  case "cancelled":
3420
- return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}`;
3536
+ return `${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}`;
3421
3537
  default:
3422
- return `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(s)}`;
3538
+ return `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(s)}`;
3423
3539
  }
3424
3540
  };
3425
3541
  return new LD({ options: t.options, initialValue: t.initialValue, render() {
3426
- const r = `${import_picocolors.default.gray(o)}
3542
+ const r = `${import_picocolors3.default.gray(o)}
3427
3543
  ${b2(this.state)} ${t.message}
3428
3544
  `;
3429
3545
  switch (this.state) {
3430
3546
  case "submit":
3431
- return `${r}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
3547
+ return `${r}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
3432
3548
  case "cancel":
3433
- return `${r}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
3434
- ${import_picocolors.default.gray(o)}`;
3549
+ return `${r}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
3550
+ ${import_picocolors3.default.gray(o)}`;
3435
3551
  default:
3436
- return `${r}${import_picocolors.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
3437
- ${import_picocolors.default.cyan(o)} `)}
3438
- ${import_picocolors.default.cyan(d2)}
3552
+ return `${r}${import_picocolors3.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
3553
+ ${import_picocolors3.default.cyan(o)} `)}
3554
+ ${import_picocolors3.default.cyan(d2)}
3439
3555
  `;
3440
3556
  }
3441
3557
  } }).prompt();
3442
3558
  }, fe = (t) => {
3443
3559
  const n = (r, i) => {
3444
3560
  const s = r.label ?? String(r.value);
3445
- return i === "active" ? `${import_picocolors.default.cyan(A2)} ${s} ${r.hint ? import_picocolors.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors.default.green(T)} ${import_picocolors.default.dim(s)} ${r.hint ? import_picocolors.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}` : i === "active-selected" ? `${import_picocolors.default.green(T)} ${s} ${r.hint ? import_picocolors.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors.default.dim(s)}` : `${import_picocolors.default.dim(F)} ${import_picocolors.default.dim(s)}`;
3561
+ return i === "active" ? `${import_picocolors3.default.cyan(A2)} ${s} ${r.hint ? import_picocolors3.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors3.default.green(T)} ${import_picocolors3.default.dim(s)} ${r.hint ? import_picocolors3.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}` : i === "active-selected" ? `${import_picocolors3.default.green(T)} ${s} ${r.hint ? import_picocolors3.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors3.default.dim(s)}` : `${import_picocolors3.default.dim(F)} ${import_picocolors3.default.dim(s)}`;
3446
3562
  };
3447
3563
  return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r) {
3448
3564
  if (this.required && r.length === 0)
3449
3565
  return `Please select at least one option.
3450
- ${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
3566
+ ${import_picocolors3.default.reset(import_picocolors3.default.dim(`Press ${import_picocolors3.default.gray(import_picocolors3.default.bgWhite(import_picocolors3.default.inverse(" space ")))} to select, ${import_picocolors3.default.gray(import_picocolors3.default.bgWhite(import_picocolors3.default.inverse(" enter ")))} to submit`))}`;
3451
3567
  }, render() {
3452
- const r = `${import_picocolors.default.gray(o)}
3568
+ const r = `${import_picocolors3.default.gray(o)}
3453
3569
  ${b2(this.state)} ${t.message}
3454
3570
  `, i = (s, c) => {
3455
3571
  const a = this.value.includes(s.value);
@@ -3457,34 +3573,34 @@ ${b2(this.state)} ${t.message}
3457
3573
  };
3458
3574
  switch (this.state) {
3459
3575
  case "submit":
3460
- return `${r}${import_picocolors.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors.default.dim(", ")) || import_picocolors.default.dim("none")}`;
3576
+ return `${r}${import_picocolors3.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors3.default.dim(", ")) || import_picocolors3.default.dim("none")}`;
3461
3577
  case "cancel": {
3462
- const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors.default.dim(", "));
3463
- return `${r}${import_picocolors.default.gray(o)} ${s.trim() ? `${s}
3464
- ${import_picocolors.default.gray(o)}` : ""}`;
3578
+ const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors3.default.dim(", "));
3579
+ return `${r}${import_picocolors3.default.gray(o)} ${s.trim() ? `${s}
3580
+ ${import_picocolors3.default.gray(o)}` : ""}`;
3465
3581
  }
3466
3582
  case "error": {
3467
3583
  const s = this.error.split(`
3468
- `).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
3584
+ `).map((c, a) => a === 0 ? `${import_picocolors3.default.yellow(d2)} ${import_picocolors3.default.yellow(c)}` : ` ${c}`).join(`
3469
3585
  `);
3470
- return `${r + import_picocolors.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
3471
- ${import_picocolors.default.yellow(o)} `)}
3586
+ return `${r + import_picocolors3.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
3587
+ ${import_picocolors3.default.yellow(o)} `)}
3472
3588
  ${s}
3473
3589
  `;
3474
3590
  }
3475
3591
  default:
3476
- return `${r}${import_picocolors.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
3477
- ${import_picocolors.default.cyan(o)} `)}
3478
- ${import_picocolors.default.cyan(d2)}
3592
+ return `${r}${import_picocolors3.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
3593
+ ${import_picocolors3.default.cyan(o)} `)}
3594
+ ${import_picocolors3.default.cyan(d2)}
3479
3595
  `;
3480
3596
  }
3481
3597
  } }).prompt();
3482
3598
  }, Ie = (t = "") => {
3483
- process.stdout.write(`${import_picocolors.default.gray(ue)} ${t}
3599
+ process.stdout.write(`${import_picocolors3.default.gray(ue)} ${t}
3484
3600
  `);
3485
3601
  }, Se = (t = "") => {
3486
- process.stdout.write(`${import_picocolors.default.gray(o)}
3487
- ${import_picocolors.default.gray(d2)} ${t}
3602
+ process.stdout.write(`${import_picocolors3.default.gray(o)}
3603
+ ${import_picocolors3.default.gray(d2)} ${t}
3488
3604
 
3489
3605
  `);
3490
3606
  }, M2, J2, Y2 = ({ indicator: t = "dots" } = {}) => {
@@ -3509,14 +3625,14 @@ ${import_picocolors.default.gray(d2)} ${t}
3509
3625
  const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
3510
3626
  return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
3511
3627
  }, H2 = (m2 = "") => {
3512
- a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors.default.gray(o)}
3628
+ a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors3.default.gray(o)}
3513
3629
  `);
3514
3630
  let h2 = 0, w2 = 0;
3515
3631
  j2(), c = setInterval(() => {
3516
3632
  if (i && l2 === $2)
3517
3633
  return;
3518
3634
  B2(), $2 = l2;
3519
- const I2 = import_picocolors.default.magenta(n[h2]);
3635
+ const I2 = import_picocolors3.default.magenta(n[h2]);
3520
3636
  if (i)
3521
3637
  process.stdout.write(`${I2} ${l2}...`);
3522
3638
  else if (t === "timer")
@@ -3529,7 +3645,7 @@ ${import_picocolors.default.gray(d2)} ${t}
3529
3645
  }, r);
3530
3646
  }, N2 = (m2 = "", h2 = 0) => {
3531
3647
  a = false, clearInterval(c), B2();
3532
- const w2 = h2 === 0 ? import_picocolors.default.green(C2) : h2 === 1 ? import_picocolors.default.red(L2) : import_picocolors.default.red(W2);
3648
+ const w2 = h2 === 0 ? import_picocolors3.default.green(C2) : h2 === 1 ? import_picocolors3.default.red(L2) : import_picocolors3.default.red(W2);
3533
3649
  l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
3534
3650
  `) : process.stdout.write(`${w2} ${l2}
3535
3651
  `), E(), s();
@@ -3541,7 +3657,7 @@ ${import_picocolors.default.gray(d2)} ${t}
3541
3657
  var init_dist2 = __esm(() => {
3542
3658
  init_dist();
3543
3659
  init_dist();
3544
- import_picocolors = __toESM(require_picocolors(), 1);
3660
+ import_picocolors3 = __toESM(require_picocolors(), 1);
3545
3661
  import_sisteransi2 = __toESM(require_src(), 1);
3546
3662
  V2 = ce();
3547
3663
  le = u("◆", "*");
@@ -3565,30 +3681,30 @@ var init_dist2 = __esm(() => {
3565
3681
  D = u("◆", "*");
3566
3682
  U = u("▲", "!");
3567
3683
  K2 = u("■", "x");
3568
- M2 = { message: (t = "", { symbol: n = import_picocolors.default.gray(o) } = {}) => {
3569
- const r = [`${import_picocolors.default.gray(o)}`];
3684
+ M2 = { message: (t = "", { symbol: n = import_picocolors3.default.gray(o) } = {}) => {
3685
+ const r = [`${import_picocolors3.default.gray(o)}`];
3570
3686
  if (t) {
3571
3687
  const [i, ...s] = t.split(`
3572
3688
  `);
3573
- r.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors.default.gray(o)} ${c}`));
3689
+ r.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors3.default.gray(o)} ${c}`));
3574
3690
  }
3575
3691
  process.stdout.write(`${r.join(`
3576
3692
  `)}
3577
3693
  `);
3578
3694
  }, info: (t) => {
3579
- M2.message(t, { symbol: import_picocolors.default.blue(q) });
3695
+ M2.message(t, { symbol: import_picocolors3.default.blue(q) });
3580
3696
  }, success: (t) => {
3581
- M2.message(t, { symbol: import_picocolors.default.green(D) });
3697
+ M2.message(t, { symbol: import_picocolors3.default.green(D) });
3582
3698
  }, step: (t) => {
3583
- M2.message(t, { symbol: import_picocolors.default.green(C2) });
3699
+ M2.message(t, { symbol: import_picocolors3.default.green(C2) });
3584
3700
  }, warn: (t) => {
3585
- M2.message(t, { symbol: import_picocolors.default.yellow(U) });
3701
+ M2.message(t, { symbol: import_picocolors3.default.yellow(U) });
3586
3702
  }, warning: (t) => {
3587
3703
  M2.warn(t);
3588
3704
  }, error: (t) => {
3589
- M2.message(t, { symbol: import_picocolors.default.red(K2) });
3705
+ M2.message(t, { symbol: import_picocolors3.default.red(K2) });
3590
3706
  } };
3591
- J2 = `${import_picocolors.default.gray(o)} `;
3707
+ J2 = `${import_picocolors3.default.gray(o)} `;
3592
3708
  });
3593
3709
 
3594
3710
  // src/client/client.ts
@@ -3743,14 +3859,14 @@ var init_client = __esm(() => {
3743
3859
 
3744
3860
  // src/setup/styles.ts
3745
3861
  function dim(msg) {
3746
- return import_picocolors2.default.dim(msg);
3862
+ return import_picocolors4.default.dim(msg);
3747
3863
  }
3748
3864
  function info(msg) {
3749
- return import_picocolors2.default.cyan(msg);
3865
+ return import_picocolors4.default.cyan(msg);
3750
3866
  }
3751
- var import_picocolors2;
3867
+ var import_picocolors4;
3752
3868
  var init_styles = __esm(() => {
3753
- import_picocolors2 = __toESM(require_picocolors(), 1);
3869
+ import_picocolors4 = __toESM(require_picocolors(), 1);
3754
3870
  });
3755
3871
 
3756
3872
  // src/auth/server.ts
@@ -3840,7 +3956,11 @@ async function startCallbackServer() {
3840
3956
  const http = __require("node:http");
3841
3957
  const httpServer = http.createServer((req, res) => {
3842
3958
  const url = new URL(req.url ?? "/", `http://localhost`);
3959
+ const cookieLen = (req.headers.cookie ?? "").length;
3960
+ const ua = req.headers["user-agent"] ?? "none";
3961
+ logger.debug("auth.server", `Request: ${req.method} ${req.url} cookie-len=${cookieLen} ua=${ua} has-token=${url.searchParams.has("access_token")}`);
3843
3962
  if (url.pathname !== "/callback") {
3963
+ logger.debug("auth.server", `404: ${url.pathname}`);
3844
3964
  res.writeHead(404, { "Content-Type": "text/plain" });
3845
3965
  res.end("Not Found");
3846
3966
  return;
@@ -3851,6 +3971,7 @@ async function startCallbackServer() {
3851
3971
  const email = url.searchParams.get("email");
3852
3972
  const mode = url.searchParams.get("mode");
3853
3973
  if (!accessToken) {
3974
+ logger.debug("auth.server", "Served extract HTML (no token in query)");
3854
3975
  res.writeHead(200, { "Content-Type": "text/html" });
3855
3976
  res.end(CALLBACK_HTML_EXTRACT);
3856
3977
  return;
@@ -3861,6 +3982,7 @@ async function startCallbackServer() {
3861
3982
  if (!Number.isNaN(parsed))
3862
3983
  expiresInInt = parsed;
3863
3984
  }
3985
+ logger.info("auth.server", `Token resolved, email=${email ?? "none"}`);
3864
3986
  resolveToken?.({
3865
3987
  access_token: accessToken,
3866
3988
  refresh_token: refreshToken && refreshToken !== "null" ? refreshToken : "",
@@ -3868,6 +3990,7 @@ async function startCallbackServer() {
3868
3990
  email: email ?? undefined,
3869
3991
  ...mode === MODE_OSS && { mode: MODE_OSS }
3870
3992
  });
3993
+ logger.info("auth.server", "Served success HTML");
3871
3994
  res.writeHead(200, { "Content-Type": "text/html" });
3872
3995
  res.end(buildSuccessHtml(email ?? undefined));
3873
3996
  });
@@ -3875,6 +3998,7 @@ async function startCallbackServer() {
3875
3998
  httpServer.listen(0, "localhost", () => resolve());
3876
3999
  });
3877
4000
  const addr = httpServer.address();
4001
+ logger.info("auth.server", `Callback server listening on port ${addr.port}`);
3878
4002
  return {
3879
4003
  server: {
3880
4004
  port: addr.port,
@@ -3950,6 +4074,7 @@ if (hash) {
3950
4074
  </html>`;
3951
4075
  var init_server = __esm(() => {
3952
4076
  init_config();
4077
+ init_logger();
3953
4078
  });
3954
4079
 
3955
4080
  // node_modules/is-docker/index.js
@@ -4502,19 +4627,31 @@ async function startOAuthFlow(signal, path2 = "/cli/auth") {
4502
4627
  let timeoutId;
4503
4628
  try {
4504
4629
  const callbackURL = `http://localhost:${server.port}/callback`;
4630
+ logger.debug("auth.flow", `Callback URL: ${callbackURL}`);
4505
4631
  const authURL = buildAuthURL(callbackURL, path2);
4632
+ logger.info("auth.flow", `Auth URL: ${authURL}`);
4506
4633
  const open2 = await Promise.resolve().then(() => (init_open(), exports_open));
4507
4634
  await open2.default(authURL);
4635
+ logger.info("auth.flow", "Browser open command executed");
4508
4636
  const timeout = new Promise((_3, reject) => {
4509
- timeoutId = setTimeout(() => reject(new Error("authentication timeout - please try again")), 900000);
4637
+ timeoutId = setTimeout(() => {
4638
+ logger.warn("auth.flow", "Authentication timed out (15min)");
4639
+ reject(new Error("authentication timeout - please try again"));
4640
+ }, 900000);
4510
4641
  });
4511
4642
  const abort = signal ? new Promise((_3, reject) => {
4512
- signal.addEventListener("abort", () => reject(new Error("authentication cancelled")));
4643
+ signal.addEventListener("abort", () => {
4644
+ logger.warn("auth.flow", "Authentication cancelled via abort");
4645
+ reject(new Error("authentication cancelled"));
4646
+ });
4513
4647
  }) : new Promise(() => {});
4514
- return await Promise.race([tokenPromise, timeout, abort]);
4648
+ const token = await Promise.race([tokenPromise, timeout, abort]);
4649
+ logger.info("auth.flow", "Token received");
4650
+ return token;
4515
4651
  } finally {
4516
4652
  clearTimeout(timeoutId);
4517
4653
  server.close();
4654
+ logger.debug("auth.flow", "Cleaning up: timeout cleared, server closed");
4518
4655
  }
4519
4656
  }
4520
4657
  function buildAuthURL(callbackURL, path2) {
@@ -4526,6 +4663,7 @@ function buildAuthURL(callbackURL, path2) {
4526
4663
  return `${webAppURL}${path2}?${params}`;
4527
4664
  }
4528
4665
  var init_flow = __esm(() => {
4666
+ init_logger();
4529
4667
  init_server();
4530
4668
  });
4531
4669
 
@@ -4539,6 +4677,7 @@ __export(exports_flow2, {
4539
4677
  isStdioOnly: () => isStdioOnly
4540
4678
  });
4541
4679
  async function runSetup(opts = {}) {
4680
+ logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}`);
4542
4681
  Ie("Dosu CLI Setup");
4543
4682
  const cfg = await stepAuthenticate(opts);
4544
4683
  if (!cfg)
@@ -4592,6 +4731,7 @@ Run ${info("dosu mcp add <tool>")} to manually configure a tool.`);
4592
4731
  }
4593
4732
  }
4594
4733
  async function stepAuthenticate(opts) {
4734
+ logger.info("setup", "Step: authenticate");
4595
4735
  const cfg = loadConfig();
4596
4736
  if (cfg.access_token) {
4597
4737
  const s = Y2();
@@ -4600,6 +4740,7 @@ async function stepAuthenticate(opts) {
4600
4740
  const apiClient = new Client(cfg);
4601
4741
  const resp = await apiClient.doRequestRaw("GET", "/v1/mcp/deployments");
4602
4742
  if (resp.status === 200) {
4743
+ logger.info("setup", `Session verified, status=${resp.status}`);
4603
4744
  s.stop("Authenticated");
4604
4745
  if (!opts.deploymentID && cfg.mode === MODE_OSS) {
4605
4746
  const modeLabel = "open-source libraries only";
@@ -4619,6 +4760,7 @@ async function stepAuthenticate(opts) {
4619
4760
  return cfg;
4620
4761
  }
4621
4762
  try {
4763
+ logger.debug("setup", "Attempting token refresh");
4622
4764
  await apiClient.refreshToken();
4623
4765
  const resp2 = await apiClient.doRequestRaw("GET", "/v1/mcp/deployments");
4624
4766
  if (resp2.status === 200) {
@@ -4627,6 +4769,7 @@ async function stepAuthenticate(opts) {
4627
4769
  }
4628
4770
  } catch {}
4629
4771
  s.stop("Session expired");
4772
+ logger.warn("setup", "Session expired");
4630
4773
  M2.warn("Session expired.");
4631
4774
  } catch {
4632
4775
  s.stop("Session verification failed");
@@ -4645,6 +4788,7 @@ async function openBrowserForSetup(cfg, opts) {
4645
4788
  const authPath = opts.deploymentID ? "/cli/auth" : "/cli/setup";
4646
4789
  const token = await startOAuthFlow2(undefined, authPath);
4647
4790
  s.stop("Authenticated");
4791
+ logger.info("setup", `Browser auth completed, mode=${token.mode ?? "cloud"}`);
4648
4792
  cfg.access_token = token.access_token;
4649
4793
  cfg.refresh_token = token.refresh_token;
4650
4794
  cfg.expires_at = Math.floor(Date.now() / 1000) + token.expires_in;
@@ -4652,6 +4796,8 @@ async function openBrowserForSetup(cfg, opts) {
4652
4796
  saveConfig(cfg);
4653
4797
  return cfg;
4654
4798
  } catch (err) {
4799
+ const msg = err instanceof Error ? err.stack ?? err.message : String(err);
4800
+ logger.error("setup", `Auth failed: ${msg}`);
4655
4801
  M2.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
4656
4802
  return null;
4657
4803
  }
@@ -4671,6 +4817,7 @@ async function stepSelectOrg(apiClient) {
4671
4817
  return null;
4672
4818
  }
4673
4819
  if (orgs.length === 1) {
4820
+ logger.info("setup", `Selected org: ${orgs[0].name} (auto, only one)`);
4674
4821
  M2.success(`Organization
4675
4822
  ${dim(orgs[0].name)}`);
4676
4823
  return orgs[0];
@@ -4681,7 +4828,10 @@ ${dim(orgs[0].name)}`);
4681
4828
  });
4682
4829
  if (pD(selected))
4683
4830
  return null;
4684
- return orgs.find((o2) => o2.org_id === selected) ?? null;
4831
+ const org = orgs.find((o2) => o2.org_id === selected) ?? null;
4832
+ if (org)
4833
+ logger.info("setup", `Selected org: ${org.name}`);
4834
+ return org;
4685
4835
  } catch (err) {
4686
4836
  if (err instanceof SessionExpiredError) {
4687
4837
  M2.warn(`Session expired. Please run ${info("dosu setup")} again.`);
@@ -4696,9 +4846,11 @@ async function stepResolveDeployment(apiClient, id) {
4696
4846
  const deployments = await apiClient.getDeployments();
4697
4847
  const d3 = deployments.find((d4) => d4.deployment_id === id);
4698
4848
  if (!d3) {
4849
+ logger.warn("setup", `Deployment ${id} not found`);
4699
4850
  M2.error(`Deployment ${id} not found`);
4700
4851
  return null;
4701
4852
  }
4853
+ logger.info("setup", `Resolved deployment: ${d3.name}`);
4702
4854
  M2.success(`Using deployment
4703
4855
  ${dim(d3.name)}`);
4704
4856
  return d3;
@@ -4710,23 +4862,27 @@ ${dim(d3.name)}`);
4710
4862
  async function stepSelectDeployment(apiClient, org) {
4711
4863
  try {
4712
4864
  const allDeployments = await apiClient.getDeployments();
4713
- const deployments = allDeployments.filter((d3) => d3.org_id === org.org_id);
4865
+ const deployments = allDeployments.filter((d4) => d4.org_id === org.org_id);
4714
4866
  if (deployments.length === 0) {
4715
4867
  M2.error(`No deployments found for ${org.name}`);
4716
4868
  return null;
4717
4869
  }
4718
4870
  if (deployments.length === 1) {
4871
+ logger.info("setup", `Selected deployment: ${deployments[0].name} (auto, only one)`);
4719
4872
  M2.success(`Using deployment
4720
4873
  ${dim(deployments[0].name)}`);
4721
4874
  return deployments[0];
4722
4875
  }
4723
4876
  const selected = await ve({
4724
4877
  message: "Select an MCP",
4725
- options: deployments.map((d3) => ({ label: d3.name, value: d3.deployment_id }))
4878
+ options: deployments.map((d4) => ({ label: d4.name, value: d4.deployment_id }))
4726
4879
  });
4727
4880
  if (pD(selected))
4728
4881
  return null;
4729
- return deployments.find((d3) => d3.deployment_id === selected) ?? null;
4882
+ const d3 = deployments.find((d4) => d4.deployment_id === selected) ?? null;
4883
+ if (d3)
4884
+ logger.info("setup", `Selected deployment: ${d3.name}`);
4885
+ return d3;
4730
4886
  } catch (err) {
4731
4887
  M2.error(`Deployment selection failed: ${err instanceof Error ? err.message : String(err)}`);
4732
4888
  return null;
@@ -4739,6 +4895,7 @@ async function stepMintAPIKey(apiClient, cfg) {
4739
4895
  }
4740
4896
  if (cfg.api_key) {
4741
4897
  const valid = await apiClient.validateAPIKey(cfg.api_key, cfg.deployment_id);
4898
+ logger.debug("setup", `Existing API key valid=${valid}`);
4742
4899
  if (valid) {
4743
4900
  M2.success(`API key
4744
4901
  ${dim("using existing")}`);
@@ -4748,6 +4905,7 @@ ${dim("using existing")}`);
4748
4905
  }
4749
4906
  try {
4750
4907
  const resp = await apiClient.createAPIKey(cfg.deployment_id, "dosu-cli");
4908
+ logger.info("setup", "API key created");
4751
4909
  M2.success(`API key
4752
4910
  ${dim("created")}`);
4753
4911
  return resp.api_key;
@@ -4800,9 +4958,11 @@ function stepConfigureTools(cfg, selection) {
4800
4958
  for (const provider of selection.toInstall) {
4801
4959
  try {
4802
4960
  provider.install(cfg, true);
4961
+ logger.info("setup", `Configured ${provider.name()}`);
4803
4962
  results.push({ provider, action: "install" });
4804
4963
  } catch (err) {
4805
4964
  const error = err instanceof Error ? err : new Error(String(err));
4965
+ logger.error("setup", `Config failed for ${provider.name()}: ${error.stack ?? error.message}`);
4806
4966
  M2.error(`Failed to configure ${provider.name()}: ${error.message}`);
4807
4967
  results.push({ provider, action: "install", error });
4808
4968
  }
@@ -4810,9 +4970,11 @@ function stepConfigureTools(cfg, selection) {
4810
4970
  for (const provider of selection.toRemove) {
4811
4971
  try {
4812
4972
  provider.remove(true);
4973
+ logger.info("setup", `Removed ${provider.name()}`);
4813
4974
  results.push({ provider, action: "remove" });
4814
4975
  } catch (err) {
4815
4976
  const error = err instanceof Error ? err : new Error(String(err));
4977
+ logger.error("setup", `Remove failed for ${provider.name()}: ${error.stack ?? error.message}`);
4816
4978
  M2.error(`Failed to remove ${provider.name()}: ${error.message}`);
4817
4979
  results.push({ provider, action: "remove", error });
4818
4980
  }
@@ -4854,6 +5016,7 @@ var init_flow2 = __esm(() => {
4854
5016
  init_dist2();
4855
5017
  init_client();
4856
5018
  init_config();
5019
+ init_logger();
4857
5020
  init_providers();
4858
5021
  init_styles();
4859
5022
  });
@@ -4865,7 +5028,7 @@ __export(exports_tui, {
4865
5028
  handleLogout: () => handleLogout
4866
5029
  });
4867
5030
  async function runTUI() {
4868
- console.log(import_picocolors3.default.magenta(LOGO));
5031
+ console.log(import_picocolors5.default.magenta(LOGO));
4869
5032
  const cfg = loadConfig();
4870
5033
  if (!isAuthenticated(cfg)) {
4871
5034
  await handleAuthenticate(cfg);
@@ -4962,7 +5125,7 @@ function handleLogout(cfg) {
4962
5125
  saveConfig(cfg);
4963
5126
  M2.success("Credentials cleared.");
4964
5127
  }
4965
- var import_picocolors3, LOGO = `
5128
+ var import_picocolors5, LOGO = `
4966
5129
  /$$$$$$$
4967
5130
  | $$__ $$
4968
5131
  | $$ \\ $$ /$$$$$$ /$$$$$$$ /$$ /$$
@@ -4977,9 +5140,12 @@ var init_tui = __esm(() => {
4977
5140
  init_client();
4978
5141
  init_config();
4979
5142
  init_flow2();
4980
- import_picocolors3 = __toESM(require_picocolors(), 1);
5143
+ import_picocolors5 = __toESM(require_picocolors(), 1);
4981
5144
  });
4982
5145
 
5146
+ // src/cli/cli.ts
5147
+ import { readFileSync as readFileSync6, unlinkSync } from "node:fs";
5148
+
4983
5149
  // node_modules/commander/esm.mjs
4984
5150
  var import__ = __toESM(require_commander(), 1);
4985
5151
  var {
@@ -4998,18 +5164,108 @@ var {
4998
5164
 
4999
5165
  // src/cli/cli.ts
5000
5166
  init_config();
5167
+ init_logger();
5001
5168
  init_providers();
5002
5169
 
5003
- // src/version/version.ts
5004
- var VERSION = "0.7.0";
5005
- function getVersionString() {
5006
- return `v${VERSION}`;
5170
+ // src/version/update-check.ts
5171
+ init_config();
5172
+ init_logger();
5173
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
5174
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
5175
+ import { join as join17 } from "node:path";
5176
+ var CACHE_FILENAME = "update-check.json";
5177
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
5178
+ var FETCH_TIMEOUT_MS = 5000;
5179
+ var REGISTRY_URL = "https://registry.npmjs.org/-/package/@dosu/cli/dist-tags";
5180
+ function isNewerVersion(latest, current) {
5181
+ const a = latest.split(".").map(Number);
5182
+ const b = current.split(".").map(Number);
5183
+ const len = Math.max(a.length, b.length);
5184
+ for (let i = 0;i < len; i++) {
5185
+ const av = a[i] ?? 0;
5186
+ const bv = b[i] ?? 0;
5187
+ if (av > bv)
5188
+ return true;
5189
+ if (av < bv)
5190
+ return false;
5191
+ }
5192
+ return false;
5193
+ }
5194
+ function getCachePath() {
5195
+ return join17(getConfigDir(), CACHE_FILENAME);
5196
+ }
5197
+ function readCache() {
5198
+ try {
5199
+ const path = getCachePath();
5200
+ if (!existsSync7(path))
5201
+ return null;
5202
+ const data = JSON.parse(readFileSync5(path, "utf-8"));
5203
+ if (typeof data.lastCheck === "number" && typeof data.latestVersion === "string") {
5204
+ return data;
5205
+ }
5206
+ return null;
5207
+ } catch {
5208
+ return null;
5209
+ }
5210
+ }
5211
+ function writeCache(cache) {
5212
+ try {
5213
+ writeFileSync5(getCachePath(), JSON.stringify(cache), { mode: 384 });
5214
+ } catch {}
5215
+ }
5216
+ async function fetchLatestVersion() {
5217
+ const controller = new AbortController;
5218
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
5219
+ try {
5220
+ const resp = await fetch(REGISTRY_URL, { signal: controller.signal });
5221
+ if (!resp.ok)
5222
+ return null;
5223
+ const data = await resp.json();
5224
+ const latest = data.latest;
5225
+ return typeof latest === "string" ? latest : null;
5226
+ } catch {
5227
+ return null;
5228
+ } finally {
5229
+ clearTimeout(timeout);
5230
+ }
5231
+ }
5232
+ function displayNotice(current, latest) {
5233
+ const msg = `
5234
+ ${import_picocolors2.default.yellow(` Update available: ${current} → ${latest}`)}
5235
+ ` + `${import_picocolors2.default.dim(' Run "npm update -g @dosu/cli" or visit https://github.com/dosu-ai/dosu-cli/releases')}
5236
+ `;
5237
+ console.error(msg);
5238
+ }
5239
+ function checkForUpdates() {
5240
+ try {
5241
+ const cache = readCache();
5242
+ if (cache && isNewerVersion(cache.latestVersion, VERSION)) {
5243
+ displayNotice(VERSION, cache.latestVersion);
5244
+ }
5245
+ const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS;
5246
+ if (isStale) {
5247
+ fetchLatestVersion().then((latest) => {
5248
+ if (latest) {
5249
+ writeCache({ lastCheck: Date.now(), latestVersion: latest });
5250
+ logger.debug("update-check", `Cached latest version: ${latest}`);
5251
+ }
5252
+ }).catch((err) => {
5253
+ logger.error("update-check", `Background fetch failed: ${err}`);
5254
+ });
5255
+ }
5256
+ } catch (err) {
5257
+ logger.error("update-check", `Update check failed: ${err}`);
5258
+ }
5007
5259
  }
5008
5260
 
5009
5261
  // src/cli/cli.ts
5010
5262
  function createProgram() {
5011
5263
  const program2 = new Command;
5012
- program2.name("dosu").description("Dosu CLI - Manage MCP servers for AI tools").version(getVersionString(), "-v, --version").action(async () => {
5264
+ program2.name("dosu").description("Dosu CLI - Manage MCP servers for AI tools").version(getVersionString(), "-v, --version").option("--debug", "Enable debug logging to stderr", false).hook("preAction", (thisCommand) => {
5265
+ const opts = thisCommand.optsWithGlobals();
5266
+ logger.init({ debug: opts.debug });
5267
+ checkForUpdates();
5268
+ }).action(async () => {
5013
5269
  const { runTUI: runTUI2 } = await Promise.resolve().then(() => (init_tui(), exports_tui));
5014
5270
  await runTUI2();
5015
5271
  });
@@ -5128,6 +5384,32 @@ Use 'dosu mcp add <tool>' to add Dosu MCP to a tool.`);
5128
5384
  const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_flow2(), exports_flow2));
5129
5385
  await runSetup2({ deploymentID: opts.deployment });
5130
5386
  });
5387
+ program2.command("logs").description("View or manage debug logs").option("-t, --tail [n]", "Show last N lines (default: 50)").option("--clear", "Delete the log file").action((opts) => {
5388
+ const logPath = logger.getLogPath();
5389
+ if (opts.clear) {
5390
+ try {
5391
+ unlinkSync(logPath);
5392
+ console.log("Log file deleted.");
5393
+ } catch {
5394
+ console.log("No log file to delete.");
5395
+ }
5396
+ return;
5397
+ }
5398
+ if (opts.tail !== undefined) {
5399
+ const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
5400
+ try {
5401
+ const content = readFileSync6(logPath, "utf-8");
5402
+ const lines = content.split(`
5403
+ `);
5404
+ console.log(lines.slice(-n).join(`
5405
+ `));
5406
+ } catch {
5407
+ console.log(`No log file found at ${logPath}`);
5408
+ }
5409
+ return;
5410
+ }
5411
+ console.log(logPath);
5412
+ });
5131
5413
  return program2;
5132
5414
  }
5133
5415
  async function execute() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",