claudish 6.2.0 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +86 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -30721,6 +30721,9 @@ function loadConfig() {
30721
30721
  if (config3.endpoints !== undefined) {
30722
30722
  merged.endpoints = config3.endpoints;
30723
30723
  }
30724
+ if (config3.autoApproveConfirmedAt !== undefined) {
30725
+ merged.autoApproveConfirmedAt = config3.autoApproveConfirmedAt;
30726
+ }
30724
30727
  return merged;
30725
30728
  } catch (error46) {
30726
30729
  console.error(`Warning: Failed to load config, using defaults: ${error46}`);
@@ -35530,6 +35533,12 @@ async function parseArgs(args) {
35530
35533
  if (envSummarizeTools === "true" || envSummarizeTools === "1") {
35531
35534
  config3.summarizeTools = true;
35532
35535
  }
35536
+ try {
35537
+ const fileConfig = loadConfig();
35538
+ if (fileConfig.diagMode && ["auto", "pty", "tmux", "logfile", "off"].includes(fileConfig.diagMode)) {
35539
+ config3.diagMode = fileConfig.diagMode;
35540
+ }
35541
+ } catch {}
35533
35542
  const envDiagMode = process.env[ENV.CLAUDISH_DIAG_MODE]?.toLowerCase();
35534
35543
  if (envDiagMode && ["auto", "pty", "tmux", "logfile", "off"].includes(envDiagMode)) {
35535
35544
  config3.diagMode = envDiagMode;
@@ -36615,6 +36624,7 @@ OPTIONS:
36615
36624
  -d, --debug Enable debug logging to file (logs/claudish_*.log)
36616
36625
  --no-logs Disable always-on structural logging (~/.claudish/logs/)
36617
36626
  --diag-mode <mode> Diagnostic output: auto (default), pty, tmux, logfile, off
36627
+ Also: CLAUDISH_DIAG_MODE env var or "diagMode" in config.json
36618
36628
  --log-level <level> Log verbosity: debug (full), info (truncated), minimal (labels only)
36619
36629
  -q, --quiet Suppress [claudish] log messages (default in single-shot mode)
36620
36630
  -v, --verbose Show [claudish] log messages (default in interactive mode)
@@ -37093,7 +37103,7 @@ async function fetchGLMCodingModels() {
37093
37103
  return [];
37094
37104
  }
37095
37105
  }
37096
- var __filename4, __dirname4, VERSION = "6.2.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
37106
+ var __filename4, __dirname4, VERSION = "6.2.1", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
37097
37107
  var init_cli = __esm(() => {
37098
37108
  init_config();
37099
37109
  init_model_loader();
@@ -100552,12 +100562,33 @@ class MtmDiagRunner {
100552
100562
  if (parsed.provider)
100553
100563
  this.provider = parsed.provider;
100554
100564
  }
100565
+ if (msg.includes("HANDLER STARTED") || msg.includes("=== Request")) {
100566
+ this.requestCount++;
100567
+ }
100568
+ const rtMatch = msg.match(/(\d+)ms\b/);
100569
+ if (rtMatch && msg.includes("Response")) {
100570
+ const ms = parseInt(rtMatch[1], 10);
100571
+ this.roundtripSamples.push(ms);
100572
+ if (this.roundtripSamples.length > 20)
100573
+ this.roundtripSamples.shift();
100574
+ this.avgRoundtripMs = Math.round(this.roundtripSamples.reduce((a, b2) => a + b2, 0) / this.roundtripSamples.length);
100575
+ }
100576
+ if (msg.includes("Format:") || msg.includes("Transport:") || msg.includes("Translator:")) {
100577
+ const parts = msg.split(":").slice(1).join(":").trim();
100578
+ if (parts)
100579
+ this.adapters = parts;
100580
+ }
100555
100581
  this.refreshStatusBar();
100556
100582
  }
100557
100583
  modelName = "";
100558
100584
  provider = "";
100559
100585
  lastError = "";
100560
100586
  errorCount = 0;
100587
+ requestCount = 0;
100588
+ totalCost = 0;
100589
+ avgRoundtripMs = 0;
100590
+ roundtripSamples = [];
100591
+ adapters = "";
100561
100592
  setModel(name) {
100562
100593
  this.modelName = name.includes("/") ? name.split("/").pop() : name;
100563
100594
  if (name.includes("@")) {
@@ -100572,7 +100603,9 @@ class MtmDiagRunner {
100572
100603
  model: this.modelName,
100573
100604
  provider: this.provider,
100574
100605
  errorCount: this.errorCount,
100575
- lastError: this.lastError
100606
+ lastError: this.lastError,
100607
+ requestCount: this.requestCount,
100608
+ avgRoundtripMs: this.avgRoundtripMs
100576
100609
  });
100577
100610
  try {
100578
100611
  appendFileSync(this.statusPath, bar + `
@@ -100607,31 +100640,47 @@ class MtmDiagRunner {
100607
100640
  const thisDir = dirname6(thisFile);
100608
100641
  const platform3 = process.platform;
100609
100642
  const arch = process.arch;
100610
- const bundledPlatform = join23(thisDir, "..", "..", "native", "mtm", `mtm-${platform3}-${arch}`);
100643
+ const pkgRoot = join23(thisDir, "..");
100644
+ const bundledPlatform = join23(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
100611
100645
  if (existsSync21(bundledPlatform))
100612
100646
  return bundledPlatform;
100613
- const builtDev = join23(thisDir, "..", "native", "mtm", "mtm");
100647
+ const builtDev = join23(pkgRoot, "native", "mtm", "mtm");
100614
100648
  if (existsSync21(builtDev))
100615
100649
  return builtDev;
100616
100650
  try {
100617
100651
  const result = execSync3("which mtm", { encoding: "utf-8" }).trim();
100618
- if (result)
100652
+ if (result && this.isMtmFork(result))
100619
100653
  return result;
100620
100654
  } catch {}
100621
100655
  throw new Error("mtm binary not found. Build it with: cd packages/cli/native/mtm && make");
100622
100656
  }
100657
+ isMtmFork(binPath) {
100658
+ try {
100659
+ const output = execSync3(`"${binPath}" --help 2>&1 || true`, {
100660
+ encoding: "utf-8",
100661
+ timeout: 2000
100662
+ });
100663
+ return output.includes("-e ");
100664
+ } catch {
100665
+ return false;
100666
+ }
100667
+ }
100623
100668
  }
100624
100669
  function shellQuote(s) {
100625
100670
  return "'" + s.replace(/'/g, "'\\''") + "'";
100626
100671
  }
100627
100672
  function renderStatusBar(state) {
100628
- const { model, provider, errorCount, lastError } = state;
100673
+ const { model, provider, errorCount, lastError, requestCount, avgRoundtripMs } = state;
100629
100674
  const parts = [];
100630
100675
  parts.push("M: claudish ");
100631
100676
  if (model)
100632
100677
  parts.push(`C: ${model} `);
100633
100678
  if (provider)
100634
100679
  parts.push(`D: ${provider} `);
100680
+ if (requestCount > 0) {
100681
+ const rt = avgRoundtripMs > 0 ? ` ~${avgRoundtripMs}ms` : "";
100682
+ parts.push(`D: ${requestCount} req${rt} `);
100683
+ }
100635
100684
  if (errorCount > 0) {
100636
100685
  const errLabel = errorCount === 1 ? " \u26A0 1 error " : ` \u26A0 ${errorCount} errors `;
100637
100686
  parts.push(`R:${errLabel}`);
@@ -106318,24 +106367,38 @@ class OpenAIProviderTransport {
106318
106367
  return headers;
106319
106368
  }
106320
106369
  async enqueueRequest(fetchFn) {
106321
- const controller = new AbortController;
106322
- const timeoutId = setTimeout(() => controller.abort(), 30000);
106323
- try {
106324
- const response = await fetchFn();
106325
- return response;
106326
- } catch (fetchError) {
106327
- if (fetchError.name === "AbortError") {
106328
- log(`[${this.displayName}] Request timed out after 30s`);
106329
- throw new OpenAITimeoutError(this.provider.baseUrl);
106330
- }
106331
- if (fetchError.cause?.code === "UND_ERR_CONNECT_TIMEOUT") {
106332
- log(`[${this.displayName}] Connection timeout: ${fetchError.message}`);
106333
- throw new OpenAIConnectionError(this.provider.baseUrl, fetchError.cause?.code);
106334
- }
106335
- throw fetchError;
106336
- } finally {
106337
- clearTimeout(timeoutId);
106370
+ const maxRetries = 5;
106371
+ let lastResponse = null;
106372
+ for (let attempt = 0;attempt <= maxRetries; attempt++) {
106373
+ try {
106374
+ const response = await fetchFn();
106375
+ if (response.status === 429 && attempt < maxRetries) {
106376
+ lastResponse = response;
106377
+ const retryAfter = response.headers.get("Retry-After");
106378
+ let delayMs;
106379
+ if (retryAfter && !Number.isNaN(Number(retryAfter))) {
106380
+ delayMs = Math.min(Number(retryAfter) * 1000, 30000);
106381
+ } else {
106382
+ delayMs = Math.min(2000 * Math.pow(2, attempt), 30000);
106383
+ }
106384
+ log(`[${this.displayName}] 429 rate limited, retry ${attempt + 1}/${maxRetries} in ${(delayMs / 1000).toFixed(1)}s`);
106385
+ await new Promise((resolve4) => setTimeout(resolve4, delayMs));
106386
+ continue;
106387
+ }
106388
+ return response;
106389
+ } catch (fetchError) {
106390
+ if (fetchError.name === "AbortError") {
106391
+ log(`[${this.displayName}] Request timed out after 30s`);
106392
+ throw new OpenAITimeoutError(this.provider.baseUrl);
106393
+ }
106394
+ if (fetchError.cause?.code === "UND_ERR_CONNECT_TIMEOUT") {
106395
+ log(`[${this.displayName}] Connection timeout: ${fetchError.message}`);
106396
+ throw new OpenAIConnectionError(this.provider.baseUrl, fetchError.cause?.code);
106397
+ }
106398
+ throw fetchError;
106399
+ }
106338
106400
  }
106401
+ return lastResponse;
106339
106402
  }
106340
106403
  static formatDisplayName(name) {
106341
106404
  if (name === "opencode-zen")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "6.2.0",
3
+ "version": "6.2.1",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",