claudish 5.3.1 → 5.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -28469,11 +28469,15 @@ function loadConfig() {
28469
28469
  try {
28470
28470
  const content = readFileSync4(CONFIG_FILE, "utf-8");
28471
28471
  const config3 = JSON.parse(content);
28472
- return {
28472
+ const merged = {
28473
28473
  version: config3.version || DEFAULT_CONFIG.version,
28474
28474
  defaultProfile: config3.defaultProfile || DEFAULT_CONFIG.defaultProfile,
28475
28475
  profiles: config3.profiles || DEFAULT_CONFIG.profiles
28476
28476
  };
28477
+ if (config3.telemetry !== undefined) {
28478
+ merged.telemetry = config3.telemetry;
28479
+ }
28480
+ return merged;
28477
28481
  } catch (error46) {
28478
28482
  console.error(`Warning: Failed to load config, using defaults: ${error46}`);
28479
28483
  return { ...DEFAULT_CONFIG };
@@ -32641,6 +32645,433 @@ var init_profile_commands = __esm(() => {
32641
32645
  init_dist8();
32642
32646
  });
32643
32647
 
32648
+ // src/telemetry.ts
32649
+ var exports_telemetry = {};
32650
+ __export(exports_telemetry, {
32651
+ sanitizeMessage: () => sanitizeMessage,
32652
+ runConsentPrompt: () => runConsentPrompt,
32653
+ reportError: () => reportError,
32654
+ initTelemetry: () => initTelemetry,
32655
+ handleTelemetryCommand: () => handleTelemetryCommand,
32656
+ enforceReportSize: () => enforceReportSize,
32657
+ detectRuntime: () => detectRuntime,
32658
+ detectInstallMethod: () => detectInstallMethod,
32659
+ classifyError: () => classifyError,
32660
+ buildReport: () => buildReport
32661
+ });
32662
+ import { randomBytes as randomBytes3 } from "node:crypto";
32663
+ import { createRequire as createRequire2 } from "node:module";
32664
+ function getVersion() {
32665
+ try {
32666
+ const require2 = createRequire2(import.meta.url);
32667
+ const pkg = require2("../package.json");
32668
+ return pkg.version ?? "unknown";
32669
+ } catch {
32670
+ return "unknown";
32671
+ }
32672
+ }
32673
+ function detectRuntime() {
32674
+ if (process.versions.bun) {
32675
+ const major2 = process.versions.bun.split(".").slice(0, 2).join(".");
32676
+ return `bun-${major2}`;
32677
+ }
32678
+ const major = process.versions.node?.split(".")[0] ?? "unknown";
32679
+ return `node-${major}`;
32680
+ }
32681
+ function detectInstallMethod() {
32682
+ const scriptPath = process.argv[1] || "";
32683
+ if (scriptPath.includes("/.bun/"))
32684
+ return "bun";
32685
+ if (scriptPath.includes("/Cellar/") || scriptPath.includes("/homebrew/"))
32686
+ return "homebrew";
32687
+ if (scriptPath.includes("/node_modules/") || scriptPath.includes("/.nvm/") || scriptPath.includes("/npm/"))
32688
+ return "npm";
32689
+ return "binary";
32690
+ }
32691
+ function sanitizeMessage(msg) {
32692
+ if (typeof msg !== "string")
32693
+ return "<non-string>";
32694
+ let s = msg;
32695
+ s = s.replace(/\?[^\s"'`]*/g, "?<redacted>");
32696
+ s = s.replace(/\/(?:home|Users)\/[^\s"'`]+/g, "<path>");
32697
+ s = s.replace(/[A-Za-z]:\\[Uu]sers\\[^\s"'`]+/g, "<path>");
32698
+ s = s.replace(/\/(?:var|tmp|private|opt|etc)\/[^\s"'`]+/g, "<path>");
32699
+ s = s.replace(/~\/[^\s]*/g, "<path>");
32700
+ s = s.replace(/localhost:(\d+)/g, "localhost:<port>");
32701
+ s = s.replace(/127\.0\.0\.1:(\d+)/g, "localhost:<port>");
32702
+ s = s.replace(/\b(?!127\.0\.0\.1)(\d{1,3}\.){3}\d{1,3}\b/g, "<host>");
32703
+ s = s.replace(/\[[0-9a-fA-F:]{4,}\]/g, "<host>");
32704
+ s = s.replace(/https?:\/\/([a-zA-Z0-9.-]+)(:\d+)?/g, (match, host) => {
32705
+ const lowerHost = host.toLowerCase();
32706
+ for (const pub of KNOWN_PUBLIC_HOSTS) {
32707
+ if (lowerHost === pub || lowerHost.endsWith("." + pub)) {
32708
+ return match;
32709
+ }
32710
+ }
32711
+ return "https://<host>";
32712
+ });
32713
+ s = s.replace(/Bearer\s+[^\s"']+/gi, "Bearer <credential>");
32714
+ s = s.replace(/[Aa]uthorization:\s*[^\s"']+/g, "Authorization: <credential>");
32715
+ s = s.replace(/\beyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g, "<credential>");
32716
+ s = s.replace(/\bsk-[a-zA-Z0-9_\-]{10,}/g, "<credential>");
32717
+ s = s.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "<email>");
32718
+ s = s.replace(/[a-zA-Z0-9+\-_]{20,}={0,2}/g, "<credential>");
32719
+ if (s.length > 500) {
32720
+ s = s.slice(0, 497) + "...";
32721
+ }
32722
+ return s;
32723
+ }
32724
+ function sanitizeModelId(modelId, providerName) {
32725
+ if (PUBLIC_PROVIDERS.has(providerName)) {
32726
+ return modelId;
32727
+ }
32728
+ const atIdx = modelId.indexOf("@");
32729
+ if (atIdx !== -1) {
32730
+ return modelId.slice(0, atIdx + 1) + "<custom>";
32731
+ }
32732
+ return "<local-model>";
32733
+ }
32734
+ function classifyError(error46, httpStatus, errorText) {
32735
+ if (error46 && typeof error46 === "object") {
32736
+ const code = error46.code ?? error46.cause?.code;
32737
+ if (code === "ECONNREFUSED")
32738
+ return { error_class: "connection", error_code: "econnrefused" };
32739
+ if (code === "ECONNRESET")
32740
+ return { error_class: "connection", error_code: "econnreset" };
32741
+ if (code === "ETIMEDOUT")
32742
+ return { error_class: "connection", error_code: "timeout" };
32743
+ }
32744
+ if (error46 instanceof Error && error46.name === "AbortError") {
32745
+ return { error_class: "connection", error_code: "timeout" };
32746
+ }
32747
+ if (httpStatus !== undefined) {
32748
+ if (httpStatus === 400) {
32749
+ const lower = errorText?.toLowerCase() ?? "";
32750
+ if (lower.includes("context") || lower.includes("too long") || lower.includes("token")) {
32751
+ return { error_class: "http_error", error_code: "context_length_exceeded" };
32752
+ }
32753
+ if (lower.includes("unsupported content type") || lower.includes("unsupported_content_type")) {
32754
+ return { error_class: "http_error", error_code: "unsupported_content_type" };
32755
+ }
32756
+ return { error_class: "http_error", error_code: "bad_request_400" };
32757
+ }
32758
+ if (httpStatus === 401)
32759
+ return { error_class: "auth", error_code: "unauthorized_401" };
32760
+ if (httpStatus === 403)
32761
+ return { error_class: "auth", error_code: "forbidden_403" };
32762
+ if (httpStatus === 404)
32763
+ return { error_class: "http_error", error_code: "not_found_404" };
32764
+ if (httpStatus === 429)
32765
+ return { error_class: "rate_limit", error_code: "rate_limited_429" };
32766
+ if (httpStatus === 503)
32767
+ return { error_class: "overload", error_code: "service_unavailable_503" };
32768
+ if (httpStatus >= 500)
32769
+ return { error_class: "http_error", error_code: "server_error_5xx" };
32770
+ if (httpStatus >= 400)
32771
+ return { error_class: "http_error", error_code: `http_error_${httpStatus}` };
32772
+ }
32773
+ const msg = error46 instanceof Error ? error46.message.toLowerCase() : "";
32774
+ if (msg.includes("oauth") || msg.includes("token expired") || msg.includes("invalid token") || msg.includes("refresh token") || msg.includes("auth")) {
32775
+ return { error_class: "auth", error_code: "oauth_refresh_failed" };
32776
+ }
32777
+ if (msg.includes("json") || msg.includes("parse")) {
32778
+ return { error_class: "stream", error_code: "json_parse_error" };
32779
+ }
32780
+ if (msg.includes("stream")) {
32781
+ return { error_class: "stream", error_code: "stream_parse_error" };
32782
+ }
32783
+ if (msg.includes("config") || msg.includes("missing") || msg.includes("api key")) {
32784
+ return { error_class: "config", error_code: "config_error" };
32785
+ }
32786
+ return { error_class: "unknown", error_code: "unknown_error" };
32787
+ }
32788
+ function buildReport(ctx) {
32789
+ const { error_class, error_code } = classifyError(ctx.error, ctx.httpStatus, ctx.error instanceof Error ? ctx.error.message : String(ctx.error));
32790
+ let rawMessage;
32791
+ if (ctx.error instanceof Error) {
32792
+ rawMessage = ctx.error.message;
32793
+ } else if (typeof ctx.error === "string") {
32794
+ rawMessage = ctx.error;
32795
+ } else {
32796
+ rawMessage = String(ctx.error);
32797
+ }
32798
+ const report = {
32799
+ schema_version: 1,
32800
+ claudish_version: claudishVersion,
32801
+ install_method: installMethod,
32802
+ error_class,
32803
+ error_code,
32804
+ error_message_template: sanitizeMessage(rawMessage),
32805
+ provider_name: ctx.providerName,
32806
+ model_id: sanitizeModelId(ctx.modelId, ctx.providerName),
32807
+ stream_format: ctx.streamFormat,
32808
+ http_status: ctx.httpStatus ?? null,
32809
+ is_streaming: ctx.isStreaming,
32810
+ retry_attempted: ctx.retryAttempted,
32811
+ session_id: sessionId,
32812
+ timestamp: new Date().toISOString(),
32813
+ platform: process.platform,
32814
+ node_runtime: detectRuntime()
32815
+ };
32816
+ if (ctx.modelMappingRole !== undefined)
32817
+ report.model_mapping_role = ctx.modelMappingRole;
32818
+ if (ctx.concurrency !== undefined)
32819
+ report.concurrency = ctx.concurrency;
32820
+ if (ctx.adapterName !== undefined)
32821
+ report.adapter_name = ctx.adapterName;
32822
+ if (ctx.authType !== undefined)
32823
+ report.auth_type = ctx.authType;
32824
+ if (ctx.contextWindow !== undefined)
32825
+ report.context_window = ctx.contextWindow;
32826
+ if (ctx.providerErrorType !== undefined)
32827
+ report.provider_error_type = ctx.providerErrorType;
32828
+ return report;
32829
+ }
32830
+ function enforceReportSize(report) {
32831
+ let serialized = JSON.stringify(report);
32832
+ if (serialized.length <= MAX_REPORT_BYTES)
32833
+ return serialized;
32834
+ let msg = report.error_message_template;
32835
+ while (serialized.length > MAX_REPORT_BYTES && msg.length > 0) {
32836
+ msg = msg.slice(0, Math.max(0, msg.length - 50));
32837
+ const trimmed = { ...report, error_message_template: msg + "..." };
32838
+ serialized = JSON.stringify(trimmed);
32839
+ }
32840
+ return serialized.length <= MAX_REPORT_BYTES ? serialized : null;
32841
+ }
32842
+ async function sendReport(report) {
32843
+ try {
32844
+ const serialized = enforceReportSize(report);
32845
+ if (serialized === null)
32846
+ return;
32847
+ const controller = new AbortController;
32848
+ const timeout = setTimeout(() => controller.abort(), 3000);
32849
+ try {
32850
+ await fetch(TELEMETRY_ENDPOINT, {
32851
+ method: "POST",
32852
+ headers: { "Content-Type": "application/json" },
32853
+ body: serialized,
32854
+ signal: controller.signal
32855
+ });
32856
+ } finally {
32857
+ clearTimeout(timeout);
32858
+ }
32859
+ } catch {
32860
+ log("[Telemetry] Failed to send report (silently discarded)");
32861
+ }
32862
+ }
32863
+ function showConsentPromptAsync(ctx) {
32864
+ if (consentPromptActive)
32865
+ return;
32866
+ try {
32867
+ const profileConfig = loadConfig();
32868
+ if (profileConfig.telemetry?.askedAt !== undefined)
32869
+ return;
32870
+ } catch {
32871
+ return;
32872
+ }
32873
+ consentPromptActive = true;
32874
+ runConsentPrompt(ctx).catch(() => {
32875
+ consentPromptActive = false;
32876
+ });
32877
+ }
32878
+ async function runConsentPrompt(ctx) {
32879
+ const { createInterface: createInterface2 } = await import("node:readline");
32880
+ const errorSummary = classifyError(ctx.error, ctx.httpStatus);
32881
+ process.stderr.write(`
32882
+ [claudish] An error occurred: ` + errorSummary.error_code + `
32883
+ `);
32884
+ process.stderr.write(`Help improve claudish by sending an anonymous error report?
32885
+ Sends: version, error type, provider, model, platform.
32886
+ Does NOT send: prompts, paths, API keys, or credentials.
32887
+ Disable anytime: claudish telemetry off
32888
+ `);
32889
+ const answer = await new Promise((resolve) => {
32890
+ const rl = createInterface2({ input: process.stdin, output: process.stderr });
32891
+ rl.question("Send anonymous error report? [y/N] ", (ans) => {
32892
+ rl.close();
32893
+ resolve(ans.trim().toLowerCase());
32894
+ });
32895
+ });
32896
+ const accepted = answer === "y" || answer === "yes";
32897
+ try {
32898
+ const profileConfig = loadConfig();
32899
+ profileConfig.telemetry = {
32900
+ enabled: accepted,
32901
+ askedAt: new Date().toISOString(),
32902
+ promptedVersion: claudishVersion
32903
+ };
32904
+ saveConfig(profileConfig);
32905
+ consentEnabled = accepted;
32906
+ } catch {}
32907
+ if (accepted) {
32908
+ process.stderr.write(`[claudish] Error reporting enabled. Thank you!
32909
+ `);
32910
+ try {
32911
+ const report = buildReport(ctx);
32912
+ sendReport(report);
32913
+ } catch {}
32914
+ } else {
32915
+ process.stderr.write(`[claudish] Error reporting disabled. You can enable it later: claudish telemetry on
32916
+ `);
32917
+ }
32918
+ consentPromptActive = false;
32919
+ }
32920
+ function initTelemetry(config3) {
32921
+ if (initialized)
32922
+ return;
32923
+ initialized = true;
32924
+ const envOverride = process.env.CLAUDISH_TELEMETRY;
32925
+ if (envOverride === "0" || envOverride === "false" || envOverride === "off") {
32926
+ consentEnabled = false;
32927
+ return;
32928
+ }
32929
+ try {
32930
+ const profileConfig = loadConfig();
32931
+ consentEnabled = profileConfig.telemetry?.enabled ?? false;
32932
+ } catch {
32933
+ consentEnabled = false;
32934
+ }
32935
+ sessionId = randomBytes3(8).toString("hex");
32936
+ claudishVersion = getVersion();
32937
+ installMethod = detectInstallMethod();
32938
+ }
32939
+ function reportError(ctx) {
32940
+ if (!initialized || !consentEnabled) {
32941
+ if (initialized && !consentEnabled && ctx.isInteractive && process.stderr.isTTY) {
32942
+ showConsentPromptAsync(ctx);
32943
+ }
32944
+ return;
32945
+ }
32946
+ const envOverride = process.env.CLAUDISH_TELEMETRY;
32947
+ if (envOverride === "0" || envOverride === "false" || envOverride === "off") {
32948
+ return;
32949
+ }
32950
+ try {
32951
+ const report = buildReport(ctx);
32952
+ sendReport(report);
32953
+ } catch {
32954
+ log("[Telemetry] Error building report (silently discarded)");
32955
+ }
32956
+ }
32957
+ async function handleTelemetryCommand(subcommand) {
32958
+ switch (subcommand) {
32959
+ case "on": {
32960
+ const cfg = loadConfig();
32961
+ cfg.telemetry = {
32962
+ ...cfg.telemetry ?? {},
32963
+ enabled: true,
32964
+ askedAt: cfg.telemetry?.askedAt ?? new Date().toISOString(),
32965
+ promptedVersion: claudishVersion || getVersion()
32966
+ };
32967
+ saveConfig(cfg);
32968
+ process.stderr.write(`[claudish] Telemetry enabled. Anonymous error reports will be sent.
32969
+ `);
32970
+ process.exit(0);
32971
+ }
32972
+ case "off": {
32973
+ const cfg = loadConfig();
32974
+ cfg.telemetry = {
32975
+ ...cfg.telemetry ?? {},
32976
+ enabled: false,
32977
+ askedAt: cfg.telemetry?.askedAt ?? new Date().toISOString()
32978
+ };
32979
+ saveConfig(cfg);
32980
+ process.stderr.write(`[claudish] Telemetry disabled. No error reports will be sent.
32981
+ `);
32982
+ process.exit(0);
32983
+ }
32984
+ case "status": {
32985
+ const cfg = loadConfig();
32986
+ const t = cfg.telemetry;
32987
+ const envOverride = process.env.CLAUDISH_TELEMETRY;
32988
+ const envDisabled = envOverride === "0" || envOverride === "false" || envOverride === "off";
32989
+ if (envDisabled) {
32990
+ process.stderr.write(`[claudish] Telemetry: DISABLED (CLAUDISH_TELEMETRY env var override)
32991
+ `);
32992
+ } else if (!t) {
32993
+ process.stderr.write(`[claudish] Telemetry: NOT YET CONFIGURED (will prompt on first error)
32994
+ `);
32995
+ } else {
32996
+ const state = t.enabled ? "ENABLED" : "DISABLED";
32997
+ const asked = t.askedAt ? `(configured ${t.askedAt})` : "(never prompted)";
32998
+ process.stderr.write(`[claudish] Telemetry: ${state} ${asked}
32999
+ `);
33000
+ }
33001
+ process.stderr.write(`
33002
+ Data collected when enabled:
33003
+ `);
33004
+ process.stderr.write(` - Claudish version, error type, provider name, model ID
33005
+ `);
33006
+ process.stderr.write(` - Platform (darwin/linux/win32), runtime, install method
33007
+ `);
33008
+ process.stderr.write(` - Sanitized error message (no paths, no credentials)
33009
+ `);
33010
+ process.stderr.write(` - Ephemeral session ID (not stored, not correlatable)
33011
+ `);
33012
+ process.stderr.write(`
33013
+ Data NEVER collected:
33014
+ `);
33015
+ process.stderr.write(` - Prompt content, AI responses, tool names
33016
+ `);
33017
+ process.stderr.write(` - API keys, credentials, file paths, hostnames
33018
+ `);
33019
+ process.stderr.write(` - Your name, email, or IP address
33020
+ `);
33021
+ process.stderr.write(`
33022
+ Manage: claudish telemetry on|off|reset
33023
+ `);
33024
+ process.exit(0);
33025
+ }
33026
+ case "reset": {
33027
+ const cfg = loadConfig();
33028
+ if (cfg.telemetry) {
33029
+ delete cfg.telemetry.askedAt;
33030
+ cfg.telemetry.enabled = false;
33031
+ saveConfig(cfg);
33032
+ }
33033
+ process.stderr.write(`[claudish] Telemetry consent reset. You will be asked again on the next error.
33034
+ `);
33035
+ process.exit(0);
33036
+ }
33037
+ default:
33038
+ process.stderr.write(`[claudish] Unknown telemetry subcommand: "${subcommand}"
33039
+ Usage: claudish telemetry on|off|status|reset
33040
+ `);
33041
+ process.exit(1);
33042
+ }
33043
+ }
33044
+ var TELEMETRY_ENDPOINT = "https://claudish.com/v1/report", MAX_REPORT_BYTES = 4096, KNOWN_PUBLIC_HOSTS, PUBLIC_PROVIDERS, consentEnabled = false, sessionId = "", initialized = false, claudishVersion = "", installMethod = "unknown", consentPromptActive = false;
33045
+ var init_telemetry = __esm(() => {
33046
+ init_profile_config();
33047
+ init_logger();
33048
+ KNOWN_PUBLIC_HOSTS = new Set([
33049
+ "api.openai.com",
33050
+ "openrouter.ai",
33051
+ "generativelanguage.googleapis.com",
33052
+ "api.anthropic.com",
33053
+ "aip.googleapis.com",
33054
+ "api.mistral.ai",
33055
+ "api.cohere.ai"
33056
+ ]);
33057
+ PUBLIC_PROVIDERS = new Set([
33058
+ "openrouter",
33059
+ "gemini",
33060
+ "gemini-codeassist",
33061
+ "openai",
33062
+ "vertex",
33063
+ "ollamacloud",
33064
+ "anthropic",
33065
+ "minimax",
33066
+ "kimi",
33067
+ "glm",
33068
+ "zai",
33069
+ "minimax-coding",
33070
+ "kimi-coding",
33071
+ "glm-coding"
33072
+ ]);
33073
+ });
33074
+
32644
33075
  // src/config.ts
32645
33076
  var exports_config = {};
32646
33077
  __export(exports_config, {
@@ -34039,7 +34470,7 @@ __export(exports_cli, {
34039
34470
  requiresOpenRouterKey: () => requiresOpenRouterKey,
34040
34471
  parseArgs: () => parseArgs,
34041
34472
  isLocalModel: () => isLocalModel,
34042
- getVersion: () => getVersion,
34473
+ getVersion: () => getVersion2,
34043
34474
  getMissingKeysError: () => getMissingKeysError,
34044
34475
  getMissingKeyResolutions: () => getMissingKeyResolutions,
34045
34476
  getMissingKeyError: () => getMissingKeyError
@@ -34048,7 +34479,7 @@ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsS
34048
34479
  import { fileURLToPath as fileURLToPath4 } from "node:url";
34049
34480
  import { dirname as dirname4, join as join11 } from "node:path";
34050
34481
  import { homedir as homedir10 } from "node:os";
34051
- function getVersion() {
34482
+ function getVersion2() {
34052
34483
  return VERSION;
34053
34484
  }
34054
34485
  function clearAllModelCaches() {
@@ -35393,7 +35824,7 @@ async function fetchGLMCodingModels2() {
35393
35824
  return [];
35394
35825
  }
35395
35826
  }
35396
- var __filename5, __dirname5, VERSION = "5.3.1", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2;
35827
+ var __filename5, __dirname5, VERSION = "5.4.1", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2;
35397
35828
  var init_cli = __esm(() => {
35398
35829
  init_config();
35399
35830
  init_model_loader();
@@ -35568,7 +35999,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
35568
35999
  }
35569
36000
  async function runClaudeWithProxy(config3, proxyUrl) {
35570
36001
  const hasProfileMappings = config3.modelOpus || config3.modelSonnet || config3.modelHaiku || config3.modelSubagent;
35571
- const modelId = config3.model || (hasProfileMappings ? undefined : "unknown");
36002
+ const modelId = config3.model || (hasProfileMappings || config3.monitor ? undefined : "unknown");
35572
36003
  const portMatch = proxyUrl.match(/:(\d+)/);
35573
36004
  const port = portMatch ? portMatch[1] : "unknown";
35574
36005
  const { path: tempSettingsPath, statusLine } = createTempSettingsFile(modelId, port);
@@ -63123,21 +63554,30 @@ class ComposedHandler {
63123
63554
  provider;
63124
63555
  adapterManager;
63125
63556
  explicitAdapter;
63557
+ modelAdapter;
63126
63558
  middlewareManager;
63127
63559
  tokenTracker;
63128
63560
  targetModel;
63129
63561
  options;
63562
+ isInteractive;
63130
63563
  constructor(provider, targetModel, modelName, port, options = {}) {
63131
63564
  this.provider = provider;
63132
63565
  this.targetModel = targetModel;
63133
63566
  this.options = options;
63134
63567
  this.explicitAdapter = options.adapter;
63568
+ this.isInteractive = options.isInteractive ?? false;
63135
63569
  this.adapterManager = new AdapterManager(targetModel);
63570
+ const resolvedModelAdapter = this.adapterManager.getAdapter();
63571
+ if (resolvedModelAdapter.getName() !== "DefaultAdapter") {
63572
+ this.modelAdapter = resolvedModelAdapter;
63573
+ }
63136
63574
  this.middlewareManager = new MiddlewareManager;
63137
- this.middlewareManager.register(new GeminiThoughtSignatureMiddleware);
63575
+ if (targetModel.includes("gemini") || targetModel.includes("google/")) {
63576
+ this.middlewareManager.register(new GeminiThoughtSignatureMiddleware);
63577
+ }
63138
63578
  this.middlewareManager.initialize().catch((err) => log(`[ComposedHandler:${targetModel}] Middleware init error: ${err}`));
63139
63579
  this.tokenTracker = new TokenTracker(port, {
63140
- contextWindow: this.getAdapter().getContextWindow(),
63580
+ contextWindow: this.getModelContextWindow(),
63141
63581
  providerName: provider.name,
63142
63582
  modelName,
63143
63583
  providerDisplayName: provider.displayName
@@ -63146,6 +63586,12 @@ class ComposedHandler {
63146
63586
  getAdapter() {
63147
63587
  return this.explicitAdapter || this.adapterManager.getAdapter();
63148
63588
  }
63589
+ getModelContextWindow() {
63590
+ return this.modelAdapter?.getContextWindow() ?? this.getAdapter().getContextWindow();
63591
+ }
63592
+ getModelSupportsVision() {
63593
+ return this.modelAdapter?.supportsVision() ?? this.getAdapter().supportsVision();
63594
+ }
63149
63595
  async handle(c, payload) {
63150
63596
  const { claudeRequest, droppedParams } = transformOpenAIToClaude(payload);
63151
63597
  const adapter = this.getAdapter();
@@ -63153,7 +63599,7 @@ class ComposedHandler {
63153
63599
  adapter.reset();
63154
63600
  const messages = adapter.convertMessages(claudeRequest, filterIdentity);
63155
63601
  const tools = adapter.convertTools(claudeRequest, this.options.summarizeTools);
63156
- if (!adapter.supportsVision()) {
63602
+ if (!this.getModelSupportsVision()) {
63157
63603
  const imageBlocks = [];
63158
63604
  for (let msgIdx = 0;msgIdx < messages.length; msgIdx++) {
63159
63605
  const msg = messages[msgIdx];
@@ -63220,6 +63666,9 @@ class ComposedHandler {
63220
63666
  Object.assign(requestPayload, extraFields);
63221
63667
  }
63222
63668
  adapter.prepareRequest(requestPayload, claudeRequest);
63669
+ if (this.modelAdapter && this.modelAdapter !== adapter) {
63670
+ this.modelAdapter.prepareRequest(requestPayload, claudeRequest);
63671
+ }
63223
63672
  const toolNameMap = adapter.getToolNameMap();
63224
63673
  if (this.provider.refreshAuth) {
63225
63674
  try {
@@ -63227,6 +63676,18 @@ class ComposedHandler {
63227
63676
  } catch (err) {
63228
63677
  log(`[${this.provider.displayName}] Auth/health check failed: ${err.message}`);
63229
63678
  logStderr(`Error [${this.provider.displayName}]: Auth/health check failed — ${err.message}. Check credentials and server.`);
63679
+ reportError({
63680
+ error: err,
63681
+ providerName: this.provider.name,
63682
+ providerDisplayName: this.provider.displayName,
63683
+ streamFormat: this.provider.streamFormat,
63684
+ modelId: this.targetModel,
63685
+ httpStatus: undefined,
63686
+ isStreaming: false,
63687
+ retryAttempted: false,
63688
+ isInteractive: this.isInteractive,
63689
+ authType: "oauth"
63690
+ });
63230
63691
  return c.json({ error: { type: "connection_error", message: err.message } }, 503);
63231
63692
  }
63232
63693
  if (this.provider.getContextWindow) {
@@ -63261,6 +63722,17 @@ class ComposedHandler {
63261
63722
  const msg = `Cannot connect to ${this.provider.displayName} at ${endpoint}. Make sure the server is running.`;
63262
63723
  log(`[${this.provider.displayName}] ${msg}`);
63263
63724
  logStderr(`Error: ${msg} Check the server is running.`);
63725
+ reportError({
63726
+ error: error46,
63727
+ providerName: this.provider.name,
63728
+ providerDisplayName: this.provider.displayName,
63729
+ streamFormat: this.provider.streamFormat,
63730
+ modelId: this.targetModel,
63731
+ httpStatus: undefined,
63732
+ isStreaming: false,
63733
+ retryAttempted: false,
63734
+ isInteractive: this.isInteractive
63735
+ });
63264
63736
  return c.json({ error: { type: "connection_error", message: msg } }, 503);
63265
63737
  }
63266
63738
  throw error46;
@@ -63286,11 +63758,35 @@ class ComposedHandler {
63286
63758
  const errorText = await retryResp.text();
63287
63759
  log(`[${this.provider.displayName}] Retry failed: ${errorText}`);
63288
63760
  logStderr(`Error [${this.provider.displayName}]: HTTP ${retryResp.status} after auth retry. Check API key.`);
63761
+ reportError({
63762
+ error: new Error(errorText),
63763
+ providerName: this.provider.name,
63764
+ providerDisplayName: this.provider.displayName,
63765
+ streamFormat: this.provider.streamFormat,
63766
+ modelId: this.targetModel,
63767
+ httpStatus: retryResp.status,
63768
+ isStreaming: false,
63769
+ retryAttempted: true,
63770
+ isInteractive: this.isInteractive,
63771
+ authType: "oauth"
63772
+ });
63289
63773
  return c.json({ error: errorText }, retryResp.status);
63290
63774
  }
63291
63775
  } catch (err) {
63292
63776
  log(`[${this.provider.displayName}] Auth refresh failed: ${err.message}`);
63293
63777
  logStderr(`Error [${this.provider.displayName}]: Authentication failed — ${err.message}. Check API key.`);
63778
+ reportError({
63779
+ error: err,
63780
+ providerName: this.provider.name,
63781
+ providerDisplayName: this.provider.displayName,
63782
+ streamFormat: this.provider.streamFormat,
63783
+ modelId: this.targetModel,
63784
+ httpStatus: 401,
63785
+ isStreaming: false,
63786
+ retryAttempted: true,
63787
+ isInteractive: this.isInteractive,
63788
+ authType: "oauth"
63789
+ });
63294
63790
  return c.json({ error: { type: "authentication_error", message: err.message } }, 401);
63295
63791
  }
63296
63792
  } else {
@@ -63298,6 +63794,26 @@ class ComposedHandler {
63298
63794
  log(`[${this.provider.displayName}] Error: ${errorText}`);
63299
63795
  const hint = getRecoveryHint(response.status, errorText, this.provider.displayName);
63300
63796
  logStderr(`Error [${this.provider.displayName}]: HTTP ${response.status}. ${hint}`);
63797
+ let providerErrorType;
63798
+ try {
63799
+ const parsed = JSON.parse(errorText);
63800
+ providerErrorType = parsed?.error?.type || parsed?.type || parsed?.code || undefined;
63801
+ if (typeof providerErrorType === "string" && providerErrorType.length > 50) {
63802
+ providerErrorType = undefined;
63803
+ }
63804
+ } catch {}
63805
+ reportError({
63806
+ error: new Error(errorText),
63807
+ providerName: this.provider.name,
63808
+ providerDisplayName: this.provider.displayName,
63809
+ streamFormat: this.provider.streamFormat,
63810
+ modelId: this.targetModel,
63811
+ httpStatus: response.status,
63812
+ isStreaming: false,
63813
+ retryAttempted: false,
63814
+ isInteractive: this.isInteractive,
63815
+ providerErrorType
63816
+ });
63301
63817
  return c.json({ error: errorText }, response.status);
63302
63818
  }
63303
63819
  }
@@ -63413,6 +63929,7 @@ var init_composed_handler = __esm(() => {
63413
63929
  init_gemini_sse();
63414
63930
  init_logger();
63415
63931
  init_vision_proxy();
63932
+ init_telemetry();
63416
63933
  });
63417
63934
 
63418
63935
  // src/providers/transport/litellm.ts
@@ -64068,7 +64585,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64068
64585
  if (!openRouterHandlers.has(modelId)) {
64069
64586
  const orProvider = new OpenRouterProvider(openrouterApiKey || "");
64070
64587
  const orAdapter = new OpenRouterAdapter(modelId);
64071
- openRouterHandlers.set(modelId, new ComposedHandler(orProvider, modelId, modelId, port, { adapter: orAdapter }));
64588
+ openRouterHandlers.set(modelId, new ComposedHandler(orProvider, modelId, modelId, port, { adapter: orAdapter, isInteractive: options.isInteractive }));
64072
64589
  }
64073
64590
  return openRouterHandlers.get(modelId);
64074
64591
  };
@@ -64081,7 +64598,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64081
64598
  const modelId = targetModel.replace(/^poe:/, "");
64082
64599
  if (!poeHandlers.has(modelId)) {
64083
64600
  const poeTransport = new PoeProvider(poeApiKey);
64084
- poeHandlers.set(modelId, new ComposedHandler(poeTransport, modelId, modelId, port));
64601
+ poeHandlers.set(modelId, new ComposedHandler(poeTransport, modelId, modelId, port, { isInteractive: options.isInteractive }));
64085
64602
  }
64086
64603
  return poeHandlers.get(modelId);
64087
64604
  };
@@ -64101,7 +64618,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64101
64618
  const handler = new ComposedHandler(provider, resolved.modelName, resolved.modelName, port, {
64102
64619
  adapter,
64103
64620
  tokenStrategy: "local",
64104
- summarizeTools: options.summarizeTools
64621
+ summarizeTools: options.summarizeTools,
64622
+ isInteractive: options.isInteractive
64105
64623
  });
64106
64624
  localProviderHandlers.set(targetModel, handler);
64107
64625
  log(`[Proxy] Created local provider handler: ${resolved.provider.name}/${resolved.modelName}${resolved.concurrency !== undefined ? ` (concurrency: ${resolved.concurrency})` : ""}`);
@@ -64115,7 +64633,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64115
64633
  const handler = new ComposedHandler(provider, urlParsed.modelName, urlParsed.modelName, port, {
64116
64634
  adapter,
64117
64635
  tokenStrategy: "local",
64118
- summarizeTools: options.summarizeTools
64636
+ summarizeTools: options.summarizeTools,
64637
+ isInteractive: options.isInteractive
64119
64638
  });
64120
64639
  localProviderHandlers.set(targetModel, handler);
64121
64640
  log(`[Proxy] Created URL-based local provider handler: ${urlParsed.baseUrl}/${urlParsed.modelName}`);
@@ -64154,7 +64673,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64154
64673
  const gemProvider = new GeminiApiKeyProvider(resolved.provider, resolved.modelName, apiKey);
64155
64674
  const gemAdapter = new GeminiAdapter(resolved.modelName);
64156
64675
  handler = new ComposedHandler(gemProvider, targetModel, resolved.modelName, port, {
64157
- adapter: gemAdapter
64676
+ adapter: gemAdapter,
64677
+ isInteractive: options.isInteractive
64158
64678
  });
64159
64679
  log(`[Proxy] Created Gemini handler (composed): ${resolved.modelName}`);
64160
64680
  } else if (resolved.provider.name === "gemini-codeassist") {
@@ -64162,7 +64682,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64162
64682
  const gcaAdapter = new GeminiAdapter(resolved.modelName);
64163
64683
  handler = new ComposedHandler(gcaProvider, targetModel, resolved.modelName, port, {
64164
64684
  adapter: gcaAdapter,
64165
- unwrapGeminiResponse: true
64685
+ unwrapGeminiResponse: true,
64686
+ isInteractive: options.isInteractive
64166
64687
  });
64167
64688
  log(`[Proxy] Created Gemini Code Assist handler (composed): ${resolved.modelName}`);
64168
64689
  } else if (resolved.provider.name === "openai") {
@@ -64170,14 +64691,16 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64170
64691
  const oaiAdapter = new OpenAIAdapter(resolved.modelName, resolved.provider.capabilities);
64171
64692
  handler = new ComposedHandler(oaiProvider, targetModel, resolved.modelName, port, {
64172
64693
  adapter: oaiAdapter,
64173
- tokenStrategy: "delta-aware"
64694
+ tokenStrategy: "delta-aware",
64695
+ isInteractive: options.isInteractive
64174
64696
  });
64175
64697
  log(`[Proxy] Created OpenAI handler (composed): ${resolved.modelName}`);
64176
64698
  } else if (resolved.provider.name === "minimax" || resolved.provider.name === "minimax-coding" || resolved.provider.name === "kimi" || resolved.provider.name === "kimi-coding" || resolved.provider.name === "zai") {
64177
64699
  const acProvider = new AnthropicCompatProvider(resolved.provider, apiKey);
64178
64700
  const acAdapter = new AnthropicPassthroughAdapter(resolved.modelName, resolved.provider.name);
64179
64701
  handler = new ComposedHandler(acProvider, targetModel, resolved.modelName, port, {
64180
- adapter: acAdapter
64702
+ adapter: acAdapter,
64703
+ isInteractive: options.isInteractive
64181
64704
  });
64182
64705
  log(`[Proxy] Created ${resolved.provider.name} handler (composed): ${resolved.modelName}`);
64183
64706
  } else if (resolved.provider.name === "glm" || resolved.provider.name === "glm-coding") {
@@ -64185,7 +64708,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64185
64708
  const glmAdapter = new OpenAIAdapter(resolved.modelName, resolved.provider.capabilities);
64186
64709
  handler = new ComposedHandler(glmProvider, targetModel, resolved.modelName, port, {
64187
64710
  adapter: glmAdapter,
64188
- tokenStrategy: "delta-aware"
64711
+ tokenStrategy: "delta-aware",
64712
+ isInteractive: options.isInteractive
64189
64713
  });
64190
64714
  log(`[Proxy] Created ${resolved.provider.name} handler (composed): ${resolved.modelName}`);
64191
64715
  } else if (resolved.provider.name === "opencode-zen") {
@@ -64193,7 +64717,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64193
64717
  const zenAcProvider = new AnthropicCompatProvider(resolved.provider, apiKey);
64194
64718
  const zenAcAdapter = new AnthropicPassthroughAdapter(resolved.modelName, resolved.provider.name);
64195
64719
  handler = new ComposedHandler(zenAcProvider, targetModel, resolved.modelName, port, {
64196
- adapter: zenAcAdapter
64720
+ adapter: zenAcAdapter,
64721
+ isInteractive: options.isInteractive
64197
64722
  });
64198
64723
  log(`[Proxy] Created OpenCode Zen (Anthropic composed): ${resolved.modelName}`);
64199
64724
  } else {
@@ -64201,7 +64726,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64201
64726
  const zenAdapter = new OpenAIAdapter(resolved.modelName, resolved.provider.capabilities);
64202
64727
  handler = new ComposedHandler(zenProvider, targetModel, resolved.modelName, port, {
64203
64728
  adapter: zenAdapter,
64204
- tokenStrategy: "delta-aware"
64729
+ tokenStrategy: "delta-aware",
64730
+ isInteractive: options.isInteractive
64205
64731
  });
64206
64732
  log(`[Proxy] Created OpenCode Zen (composed): ${resolved.modelName}`);
64207
64733
  }
@@ -64210,7 +64736,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64210
64736
  const ocAdapter = new OllamaCloudAdapter(resolved.modelName);
64211
64737
  handler = new ComposedHandler(ocProvider, targetModel, resolved.modelName, port, {
64212
64738
  adapter: ocAdapter,
64213
- tokenStrategy: "accumulate-both"
64739
+ tokenStrategy: "accumulate-both",
64740
+ isInteractive: options.isInteractive
64214
64741
  });
64215
64742
  log(`[Proxy] Created OllamaCloud handler (composed): ${resolved.modelName}`);
64216
64743
  } else if (resolved.provider.name === "litellm") {
@@ -64222,7 +64749,10 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64222
64749
  }
64223
64750
  const provider = new LiteLLMProvider(resolved.provider.baseUrl, apiKey, resolved.modelName);
64224
64751
  const adapter = new LiteLLMAdapter(resolved.modelName, resolved.provider.baseUrl);
64225
- handler = new ComposedHandler(provider, targetModel, resolved.modelName, port, { adapter });
64752
+ handler = new ComposedHandler(provider, targetModel, resolved.modelName, port, {
64753
+ adapter,
64754
+ isInteractive: options.isInteractive
64755
+ });
64226
64756
  log(`[Proxy] Created LiteLLM handler (composed): ${resolved.modelName} (${resolved.provider.baseUrl})`);
64227
64757
  } else if (resolved.provider.name === "vertex") {
64228
64758
  const hasApiKey = !!process.env.VERTEX_API_KEY;
@@ -64233,7 +64763,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64233
64763
  const vxGemProvider = new GeminiApiKeyProvider(expressProvider, resolved.modelName, process.env.VERTEX_API_KEY);
64234
64764
  const vxGemAdapter = new GeminiAdapter(resolved.modelName);
64235
64765
  handler = new ComposedHandler(vxGemProvider, targetModel, resolved.modelName, port, {
64236
- adapter: vxGemAdapter
64766
+ adapter: vxGemAdapter,
64767
+ isInteractive: options.isInteractive
64237
64768
  });
64238
64769
  log(`[Proxy] Created Vertex AI Express handler (composed): ${resolved.modelName}`);
64239
64770
  } else if (vertexConfig) {
@@ -64256,7 +64787,8 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
64256
64787
  }
64257
64788
  handler = new ComposedHandler(vxProvider, targetModel, resolved.modelName, port, {
64258
64789
  adapter: vxAdapter,
64259
- ...handlerOpts
64790
+ ...handlerOpts,
64791
+ isInteractive: options.isInteractive
64260
64792
  });
64261
64793
  log(`[Proxy] Created Vertex AI OAuth handler (composed): ${resolved.modelName} [${parsed.publisher}] (project: ${vertexConfig.projectId})`);
64262
64794
  } else {
@@ -64613,6 +65145,7 @@ var isKimiLogout = args.includes("--kimi-logout");
64613
65145
  var isUpdateCommand = args.includes("update");
64614
65146
  var isInitCommand = args[0] === "init" || args.includes("init");
64615
65147
  var isProfileCommand = args[0] === "profile" || args.some((a, i) => a === "profile" && (i === 0 || !args[i - 1]?.startsWith("-")));
65148
+ var isTelemetryCommand = args[0] === "telemetry";
64616
65149
  if (isMcpMode) {
64617
65150
  Promise.resolve().then(() => (init_mcp_server(), exports_mcp_server)).then((mcp) => mcp.startMcpServer());
64618
65151
  } else if (isGeminiLogin) {
@@ -64677,10 +65210,16 @@ if (isMcpMode) {
64677
65210
  } else if (isProfileCommand) {
64678
65211
  const profileArgIndex = args.findIndex((a) => a === "profile");
64679
65212
  Promise.resolve().then(() => (init_profile_commands(), exports_profile_commands)).then((pc) => pc.profileCommand(args.slice(profileArgIndex + 1)).catch(handlePromptExit));
65213
+ } else if (isTelemetryCommand) {
65214
+ const subcommand = args[1] ?? "status";
65215
+ Promise.resolve().then(() => (init_telemetry(), exports_telemetry)).then((tel) => {
65216
+ tel.initTelemetry({ interactive: true });
65217
+ return tel.handleTelemetryCommand(subcommand);
65218
+ });
64680
65219
  } else {
64681
65220
  runCli();
64682
65221
  }
64683
- function detectInstallMethod() {
65222
+ function detectInstallMethod2() {
64684
65223
  const scriptPath = process.argv[1] || "";
64685
65224
  if (scriptPath.includes("/.bun/")) {
64686
65225
  return "bun";
@@ -64705,13 +65244,13 @@ function getUpdateCommand2(method) {
64705
65244
  }
64706
65245
  }
64707
65246
  async function runSelfUpdate() {
64708
- const { getVersion: getVersion2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
65247
+ const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
64709
65248
  const { execSync: execSync2 } = await import("node:child_process");
64710
65249
  const { createInterface: createInterface3 } = await import("node:readline");
64711
- const currentVersion = getVersion2();
64712
- const installMethod = detectInstallMethod();
65250
+ const currentVersion = getVersion3();
65251
+ const installMethod2 = detectInstallMethod2();
64713
65252
  console.log(`claudish v${currentVersion}`);
64714
- console.log(`Installation: ${installMethod}`);
65253
+ console.log(`Installation: ${installMethod2}`);
64715
65254
  console.log(`
64716
65255
  Checking for updates...
64717
65256
  `);
@@ -64729,7 +65268,7 @@ Checking for updates...
64729
65268
  console.log(`✓ claudish is up to date (v${currentVersion})`);
64730
65269
  process.exit(0);
64731
65270
  }
64732
- const updateCmd = getUpdateCommand2(installMethod);
65271
+ const updateCmd = getUpdateCommand2(installMethod2);
64733
65272
  console.log(`New version available: v${currentVersion} → v${latestVersion}
64734
65273
  `);
64735
65274
  const shouldUpdate = await new Promise((resolve) => {
@@ -64770,7 +65309,7 @@ Update failed. Try manually:
64770
65309
  }
64771
65310
  async function runCli() {
64772
65311
  const { checkClaudeInstalled: checkClaudeInstalled2, runClaudeWithProxy: runClaudeWithProxy2 } = await Promise.resolve().then(() => (init_claude_runner(), exports_claude_runner));
64773
- const { parseArgs: parseArgs2, getVersion: getVersion2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
65312
+ const { parseArgs: parseArgs2, getVersion: getVersion3 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
64774
65313
  const { DEFAULT_PORT_RANGE: DEFAULT_PORT_RANGE2 } = await Promise.resolve().then(() => (init_config(), exports_config));
64775
65314
  const { selectModel: selectModel2, promptForApiKey: promptForApiKey2 } = await Promise.resolve().then(() => (init_model_selector(), exports_model_selector));
64776
65315
  const {
@@ -64793,6 +65332,8 @@ async function runCli() {
64793
65332
  try {
64794
65333
  const cliConfig = await parseArgs2(process.argv.slice(2));
64795
65334
  initLogger2(cliConfig.debug, cliConfig.logLevel);
65335
+ const { initTelemetry: initTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), exports_telemetry));
65336
+ initTelemetry2(cliConfig);
64796
65337
  if (cliConfig.debug && !cliConfig.quiet) {
64797
65338
  const logFile = getLogFilePath2();
64798
65339
  if (logFile) {
@@ -64800,7 +65341,7 @@ async function runCli() {
64800
65341
  }
64801
65342
  }
64802
65343
  if (cliConfig.interactive && !cliConfig.jsonOutput) {
64803
- const shouldExit = await checkForUpdates2(getVersion2(), {
65344
+ const shouldExit = await checkForUpdates2(getVersion3(), {
64804
65345
  quiet: cliConfig.quiet,
64805
65346
  skipPrompt: false
64806
65347
  });
@@ -64889,7 +65430,8 @@ async function runCli() {
64889
65430
  };
64890
65431
  const proxy = await createProxyServer2(port, cliConfig.monitor ? undefined : cliConfig.openrouterApiKey, cliConfig.monitor ? undefined : explicitModel, cliConfig.monitor, cliConfig.anthropicApiKey, modelMap, {
64891
65432
  summarizeTools: cliConfig.summarizeTools,
64892
- quiet: cliConfig.quiet
65433
+ quiet: cliConfig.quiet,
65434
+ isInteractive: cliConfig.interactive
64893
65435
  });
64894
65436
  let exitCode = 0;
64895
65437
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "5.3.1",
3
+ "version": "5.4.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",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.2.0",
3
- "lastUpdated": "2026-03-02",
3
+ "lastUpdated": "2026-03-03",
4
4
  "source": "https://openrouter.ai/models?categories=programming&fmt=cards&order=top-weekly",
5
5
  "models": [
6
6
  {