claudish 7.18.0 → 7.19.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/dist/index.js +160 -19
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
651
651
  });
652
652
 
653
653
  // src/version.ts
654
- var VERSION = "7.18.0";
654
+ var VERSION = "7.19.0";
655
655
 
656
656
  // src/logger.ts
657
657
  var exports_logger = {};
@@ -755,7 +755,7 @@ function redactDeep(val, key) {
755
755
  return val;
756
756
  }
757
757
  function isStructuralLogWorthy(msg) {
758
- return msg.startsWith("[SSE:") || msg.startsWith("[Proxy]") || msg.startsWith("[Fallback]") || msg.startsWith("[Streaming] ===") || msg.startsWith("[Streaming] Chunk:") || msg.startsWith("[Streaming] Received") || msg.startsWith("[Streaming] Text-based tool calls") || msg.startsWith("[Streaming] Final usage") || msg.startsWith("[Streaming] Sending") || msg.startsWith("[AnthropicSSE] Stream complete") || msg.startsWith("[AnthropicSSE] Tool use:") || msg.includes("Response status:") || msg.includes("Error") || msg.includes("error") || msg.includes("[Auto-route]");
758
+ return msg.startsWith("[SSE:") || msg.startsWith("[Suppressed]") || msg.startsWith("[Proxy]") || msg.startsWith("[Fallback]") || msg.startsWith("[Streaming] ===") || msg.startsWith("[Streaming] Chunk:") || msg.startsWith("[Streaming] Received") || msg.startsWith("[Streaming] Text-based tool calls") || msg.startsWith("[Streaming] Final usage") || msg.startsWith("[Streaming] Sending") || msg.startsWith("[AnthropicSSE] Stream complete") || msg.startsWith("[AnthropicSSE] Tool use:") || msg.includes("Response status:") || msg.includes("Error") || msg.includes("error") || msg.includes("[Auto-route]");
759
759
  }
760
760
  function redactLogLine(message, timestamp) {
761
761
  if (message.startsWith("[SSE:")) {
@@ -27650,6 +27650,9 @@ function loadConfig() {
27650
27650
  if (config2.onepasswordEnvironments !== undefined) {
27651
27651
  merged.onepasswordEnvironments = config2.onepasswordEnvironments;
27652
27652
  }
27653
+ if (config2.anthropicApiBilling !== undefined) {
27654
+ merged.anthropicApiBilling = config2.anthropicApiBilling;
27655
+ }
27653
27656
  if (config2.localProviders !== undefined) {
27654
27657
  merged.localProviders = Array.from(new Set(config2.localProviders)).sort();
27655
27658
  }
@@ -37112,9 +37115,15 @@ function statusToErrorType(status) {
37112
37115
  return "api_error";
37113
37116
  }
37114
37117
  }
37118
+ function sanitizeErrorMessage(message, maxLength = MAX_ERROR_MESSAGE_LENGTH) {
37119
+ const flattened = String(message ?? "").replace(ANSI_ESCAPE, "").replace(CONTROL_CHARS, " ").replace(/\s+/g, " ").trim();
37120
+ if (flattened.length <= maxLength)
37121
+ return flattened;
37122
+ return `${flattened.slice(0, maxLength - 1).trimEnd()}\u2026`;
37123
+ }
37115
37124
  function wrapAnthropicError(status, message, errorType, upstreamStatus) {
37116
37125
  const type = errorType || statusToErrorType(status);
37117
- const error46 = { type, message };
37126
+ const error46 = { type, message: sanitizeErrorMessage(message) };
37118
37127
  if (upstreamStatus !== undefined)
37119
37128
  error46.upstream_status = upstreamStatus;
37120
37129
  return { type: "error", error: error46 };
@@ -37178,15 +37187,23 @@ function buildSurfacedErrorMessage(opts) {
37178
37187
  }
37179
37188
  function ensureAnthropicErrorFormat(status, body) {
37180
37189
  if (body?.type === "error" && typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
37181
- return body;
37190
+ return { ...body, error: { ...body.error, message: sanitizeErrorMessage(body.error.message) } };
37182
37191
  }
37183
37192
  if (typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
37184
- return { type: "error", error: body.error };
37193
+ return {
37194
+ type: "error",
37195
+ error: { ...body.error, message: sanitizeErrorMessage(body.error.message) }
37196
+ };
37185
37197
  }
37186
37198
  const message = body?.error?.message || body?.message || body?.error || (typeof body === "string" ? body : JSON.stringify(body));
37187
37199
  const errorType = body?.error?.type || body?.type || body?.code;
37188
37200
  return wrapAnthropicError(status, String(message), errorType);
37189
37201
  }
37202
+ var MAX_ERROR_MESSAGE_LENGTH = 600, ANSI_ESCAPE, CONTROL_CHARS;
37203
+ var init_anthropic_error = __esm(() => {
37204
+ ANSI_ESCAPE = /\x1B\[[0-?]*[ -/]*[@-~]|\x1B[@-Z\\-_]/g;
37205
+ CONTROL_CHARS = /[\x00-\x1F\x7F]/g;
37206
+ });
37190
37207
 
37191
37208
  // src/handlers/shared/connection-error.ts
37192
37209
  function findConnectionCode(error46) {
@@ -37201,8 +37218,18 @@ function findConnectionCode(error46) {
37201
37218
  const msg = String(error46?.message ?? error46 ?? "");
37202
37219
  if (/getaddrinfo|ENOTFOUND|EAI_AGAIN|nodename nor servname/i.test(msg))
37203
37220
  return "ENOTFOUND";
37221
+ if (BUN_CONNECT_MESSAGE.test(msg))
37222
+ return "ConnectionRefused";
37204
37223
  return null;
37205
37224
  }
37225
+ function isLoopback(endpoint) {
37226
+ try {
37227
+ const { hostname: hostname4 } = new URL(endpoint);
37228
+ return /^(localhost|127\.\d+\.\d+\.\d+|0\.0\.0\.0|\[?::1\]?)$/i.test(hostname4);
37229
+ } catch {
37230
+ return false;
37231
+ }
37232
+ }
37206
37233
  function classifyConnectionError(error46) {
37207
37234
  const code = findConnectionCode(error46);
37208
37235
  if (!code)
@@ -37222,12 +37249,15 @@ function buildConnectionErrorMessage(kind, displayName, endpoint) {
37222
37249
  case "dns":
37223
37250
  return `Cannot resolve ${host} for ${displayName}. This is a DNS/network problem on your machine \u2014 check your internet connection, VPN, or DNS resolver (e.g. Tailscale MagicDNS) \u2014 not ${displayName}.`;
37224
37251
  case "refused":
37225
- return `Cannot connect to ${displayName} at ${endpoint}. Make sure the server is running.`;
37252
+ if (isLoopback(endpoint)) {
37253
+ return `Cannot connect to ${displayName} at ${endpoint}. Make sure the server is running.`;
37254
+ }
37255
+ return `Cannot reach ${host} for ${displayName}. This is a network problem on your machine \u2014 check your internet connection, VPN, or DNS resolver (e.g. Tailscale MagicDNS) \u2014 not ${displayName}.`;
37226
37256
  case "unreachable":
37227
37257
  return `Cannot reach ${displayName} at ${endpoint}. Check your network connection.`;
37228
37258
  }
37229
37259
  }
37230
- var CODE_KIND;
37260
+ var CODE_KIND, BUN_CONNECT_MESSAGE;
37231
37261
  var init_connection_error = __esm(() => {
37232
37262
  CODE_KIND = {
37233
37263
  ENOTFOUND: "dns",
@@ -37239,8 +37269,13 @@ var init_connection_error = __esm(() => {
37239
37269
  EHOSTUNREACH: "unreachable",
37240
37270
  EPIPE: "unreachable",
37241
37271
  UND_ERR_CONNECT_TIMEOUT: "unreachable",
37242
- UND_ERR_SOCKET: "unreachable"
37272
+ UND_ERR_SOCKET: "unreachable",
37273
+ ConnectionRefused: "refused",
37274
+ ConnectionClosed: "unreachable",
37275
+ FailedToOpenSocket: "unreachable",
37276
+ ERR_SOCKET_CLOSED: "unreachable"
37243
37277
  };
37278
+ BUN_CONNECT_MESSAGE = /unable to connect\. is the computer able to access the url\?/i;
37244
37279
  });
37245
37280
 
37246
37281
  // src/handlers/shared/stream-parsers/anthropic-sse.ts
@@ -38206,6 +38241,7 @@ data: ${JSON.stringify(data)}
38206
38241
  var init_openai_responses_sse = __esm(() => {
38207
38242
  init_reasoning_cache();
38208
38243
  init_logger();
38244
+ init_anthropic_error();
38209
38245
  });
38210
38246
 
38211
38247
  // src/handlers/shared/token-tracker.ts
@@ -38548,7 +38584,7 @@ class ComposedHandler {
38548
38584
  isInteractive: this.isInteractive,
38549
38585
  authType: "oauth"
38550
38586
  });
38551
- return c.json({ error: { type: "authentication_error", message: err.message } }, 401);
38587
+ return c.json(wrapAnthropicError(401, err.message, "authentication_error"), 401);
38552
38588
  }
38553
38589
  }
38554
38590
  if (this.provider.getContextWindow) {
@@ -38614,7 +38650,7 @@ class ComposedHandler {
38614
38650
  invocation_mode: this.options.invocationMode ?? "auto-route"
38615
38651
  });
38616
38652
  } catch {}
38617
- return c.json(wrapAnthropicError(503, msg, "connection_error"), 503);
38653
+ return c.json(wrapAnthropicError(400, msg, "connection_error"), 400);
38618
38654
  }
38619
38655
  throw error46;
38620
38656
  }
@@ -38951,6 +38987,7 @@ var init_composed_handler = __esm(() => {
38951
38987
  init_stats();
38952
38988
  init_telemetry();
38953
38989
  init_transform();
38990
+ init_anthropic_error();
38954
38991
  init_connection_error();
38955
38992
  init_openai_compat();
38956
38993
  init_anthropic_sse();
@@ -39907,6 +39944,7 @@ var init_native_handler = __esm(() => {
39907
39944
  init_logger();
39908
39945
  init_profile_config();
39909
39946
  init_native_handler_advisor();
39947
+ init_anthropic_error();
39910
39948
  });
39911
39949
 
39912
39950
  // src/providers/api-key-map.ts
@@ -43482,7 +43520,7 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
43482
43520
  log(`[Proxy] Registered ${customEpResult.registered} custom endpoint(s) from config`);
43483
43521
  }
43484
43522
  for (const err of customEpResult.errors) {
43485
- console.error(`[claudish] customEndpoints['${err.name}'] failed validation: ${err.message}`);
43523
+ logStderr(`customEndpoints['${err.name}'] failed validation: ${err.message}`);
43486
43524
  }
43487
43525
  } catch (err) {
43488
43526
  log(`[Proxy] customEndpoints load skipped: ${err instanceof Error ? err.message : String(err)}`);
@@ -43570,9 +43608,10 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
43570
43608
  const resolution = resolveModelProvider(targetModel);
43571
43609
  if (resolution.wasAutoRouted && resolution.autoRouteMessage) {
43572
43610
  if (!options.quiet) {
43573
- console.error(`[Auto-route] ${resolution.autoRouteMessage}`);
43611
+ logStderr(`[Auto-route] ${resolution.autoRouteMessage}`);
43612
+ } else {
43613
+ log(`[Auto-route] ${resolution.autoRouteMessage}`);
43574
43614
  }
43575
- log(`[Auto-route] ${resolution.autoRouteMessage}`);
43576
43615
  }
43577
43616
  if (resolution.category === "openrouter") {
43578
43617
  if (resolution.wasAutoRouted && resolution.fullModelId) {
@@ -43591,7 +43630,7 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
43591
43630
  let apiKey = "";
43592
43631
  if (resolved.provider.apiKeyEnvVar) {
43593
43632
  if (!credentials.get(resolved.provider.name)) {
43594
- console.error(`[Proxy] No credential provider registered for "${resolved.provider.name}" \u2014 treating as missing credential (authority registration gap)`);
43633
+ logStderr(`[Proxy] No credential provider registered for "${resolved.provider.name}" \u2014 treating as missing credential (authority registration gap)`);
43595
43634
  log(`[Proxy] Credential authority has no provider registered under "${resolved.provider.name}"`);
43596
43635
  return null;
43597
43636
  }
@@ -43749,6 +43788,11 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
43749
43788
  };
43750
43789
  const app = new Hono2;
43751
43790
  app.use("*", cors());
43791
+ app.onError((err, c) => {
43792
+ logStderr(`[Proxy] Unhandled error on ${c.req.method} ${c.req.path}: ${err?.message ?? err}`);
43793
+ log(`[Proxy] Unhandled error stack: ${err?.stack ?? "(no stack)"}`);
43794
+ return c.json(wrapAnthropicError(500, `Proxy error: ${err?.message ?? String(err)}`), 500);
43795
+ });
43752
43796
  app.get("/", (c) => c.json({
43753
43797
  status: "ok",
43754
43798
  message: "Claudish Proxy",
@@ -43828,7 +43872,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
43828
43872
  const body = await c.req.json();
43829
43873
  log(`[RequestMeta] model=${body.model} output_config=${JSON.stringify(body.output_config) ?? "(none)"} metadata=${JSON.stringify(body.metadata) ?? "(none)"} anthropic-beta=${c.req.header("anthropic-beta") ?? "(none)"}`);
43830
43874
  const handler = await getHandlerForRequest(body.model);
43831
- return handler.handle(c, body);
43875
+ return await handler.handle(c, body);
43832
43876
  } catch (e) {
43833
43877
  log(`[Proxy] Error: ${e}`);
43834
43878
  if (e instanceof RoutingError) {
@@ -43882,6 +43926,7 @@ var init_proxy_server = __esm(() => {
43882
43926
  init_composed_handler();
43883
43927
  init_fallback_handler();
43884
43928
  init_native_handler();
43929
+ init_anthropic_error();
43885
43930
  init_logger();
43886
43931
  init_model_loader();
43887
43932
  init_profile_config();
@@ -58344,7 +58389,8 @@ var init_config = __esm(() => {
58344
58389
  OPENAI_BASE_URL: "OPENAI_BASE_URL",
58345
58390
  CLAUDISH_SUMMARIZE_TOOLS: "CLAUDISH_SUMMARIZE_TOOLS",
58346
58391
  CLAUDISH_DIAG_MODE: "CLAUDISH_DIAG_MODE",
58347
- CLAUDISH_DEBUG: "CLAUDISH_DEBUG"
58392
+ CLAUDISH_DEBUG: "CLAUDISH_DEBUG",
58393
+ CLAUDISH_ANTHROPIC_API_BILLING: "CLAUDISH_ANTHROPIC_API_BILLING"
58348
58394
  };
58349
58395
  OPENROUTER_HEADERS = {
58350
58396
  "HTTP-Referer": "https://claudish.com",
@@ -62301,6 +62347,8 @@ async function parseArgs(args) {
62301
62347
  process.exit(1);
62302
62348
  }
62303
62349
  config3.defaultProvider = dpArg;
62350
+ } else if (arg === "--anthropic-api-billing") {
62351
+ config3.anthropicApiBilling = true;
62304
62352
  } else if (arg === "--op-env" || arg.startsWith("--op-env=")) {
62305
62353
  const v = arg.startsWith("--op-env=") ? arg.slice("--op-env=".length) : args[++i];
62306
62354
  if (!v) {
@@ -63350,6 +63398,10 @@ ${h("OPTIONS")}
63350
63398
  ${green("--profile")} ${yellow("<name>")} Use named profile for model mapping (default profile if omitted)
63351
63399
  ${green("--default-provider")} ${yellow("<name>")} Fallback provider for bare model names (builtin or customEndpoints key)
63352
63400
  ${dim("Precedence: this flag > CLAUDISH_DEFAULT_PROVIDER env > config.json")}
63401
+ ${green("--anthropic-api-billing")} Use your real ANTHROPIC_API_KEY for native Claude models
63402
+ ${dim("(metered API billing). Default: the key is hidden so Claude Code")}
63403
+ ${dim("uses your claude.ai subscription. Env: CLAUDISH_ANTHROPIC_API_BILLING")}
63404
+ ${dim("Config: anthropicApiBilling: true")}
63353
63405
  ${green("--config")} ${yellow("<file>")} Use THIS config file for the run, fully replacing the machine
63354
63406
  ${dim("global (~/.claudish/config.json) AND project (.claudish.json).")}
63355
63407
  ${dim("A file naming no op:// source never touches 1Password (no prompt).")}
@@ -63525,6 +63577,7 @@ ${h("ENVIRONMENT VARIABLES")}
63525
63577
  ${blue("CLAUDISH_CONTEXT_WINDOW")} Override context window size
63526
63578
  ${blue("CLAUDISH_DIAG_MODE")} Diagnostic output: auto / logfile / off
63527
63579
  ${blue("CLAUDISH_DEBUG")} Always enable debug logging: 1 / true ${dim("(same as -d)")}
63580
+ ${blue("CLAUDISH_ANTHROPIC_API_BILLING")} Bill native Claude to your API key ${dim("(see --anthropic-api-billing)")}
63528
63581
  ${blue("CLAUDISH_MCP_TOOLS")} MCP tool gating: all / low-level / agentic / channel
63529
63582
  ${blue("CLAUDISH_MODEL_OPUS")} Override model for Opus role
63530
63583
  ${blue("CLAUDISH_MODEL_SONNET")} Override model for Sonnet role
@@ -71036,6 +71089,56 @@ var init_tui = __esm(() => {
71036
71089
  }
71037
71090
  });
71038
71091
 
71092
+ // src/terminal-isolation.ts
71093
+ import { format } from "util";
71094
+ function beginTerminalIsolation(onSuppressed) {
71095
+ if (active)
71096
+ return () => {};
71097
+ active = true;
71098
+ const emit2 = (source, text) => {
71099
+ if (routing)
71100
+ return;
71101
+ routing = true;
71102
+ try {
71103
+ onSuppressed({ source, text });
71104
+ } catch {} finally {
71105
+ routing = false;
71106
+ }
71107
+ };
71108
+ const originalConsole = {};
71109
+ for (const method of CONSOLE_METHODS) {
71110
+ originalConsole[method] = console[method];
71111
+ console[method] = (...args) => {
71112
+ emit2(`console.${method}`, format(...args));
71113
+ };
71114
+ }
71115
+ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
71116
+ const originalStderrWrite = process.stderr.write.bind(process.stderr);
71117
+ const makeWrite = (source) => (chunk, encoding, callback) => {
71118
+ const done = typeof encoding === "function" ? encoding : callback;
71119
+ emit2(source, typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8"));
71120
+ if (typeof done === "function")
71121
+ done(null);
71122
+ return true;
71123
+ };
71124
+ process.stdout.write = makeWrite("stdout");
71125
+ process.stderr.write = makeWrite("stderr");
71126
+ return function restore() {
71127
+ if (!active)
71128
+ return;
71129
+ for (const method of CONSOLE_METHODS) {
71130
+ console[method] = originalConsole[method];
71131
+ }
71132
+ process.stdout.write = originalStdoutWrite;
71133
+ process.stderr.write = originalStderrWrite;
71134
+ active = false;
71135
+ };
71136
+ }
71137
+ var CONSOLE_METHODS, active = false, routing = false;
71138
+ var init_terminal_isolation = __esm(() => {
71139
+ CONSOLE_METHODS = ["log", "error", "warn", "info", "debug", "trace", "dir"];
71140
+ });
71141
+
71039
71142
  // src/claude-runner.ts
71040
71143
  var exports_claude_runner = {};
71041
71144
  __export(exports_claude_runner, {
@@ -71059,6 +71162,12 @@ import {
71059
71162
  import { homedir as homedir24, tmpdir as tmpdir2 } from "os";
71060
71163
  import { join as join25 } from "path";
71061
71164
  import { isatty } from "tty";
71165
+ function releaseTerminalIsolation() {
71166
+ if (!restoreTerminal)
71167
+ return;
71168
+ restoreTerminal();
71169
+ restoreTerminal = null;
71170
+ }
71062
71171
  function hasNativeAnthropicMapping(config3) {
71063
71172
  const models = [
71064
71173
  config3.model,
@@ -71069,6 +71178,18 @@ function hasNativeAnthropicMapping(config3) {
71069
71178
  ];
71070
71179
  return models.some((m) => m && parseModelSpec(m).provider === "native-anthropic");
71071
71180
  }
71181
+ function wantsAnthropicApiBilling(config3) {
71182
+ if (config3.anthropicApiBilling)
71183
+ return true;
71184
+ const raw2 = process.env[ENV.CLAUDISH_ANTHROPIC_API_BILLING];
71185
+ if (raw2 !== undefined && raw2 !== "" && raw2 !== "0" && raw2.toLowerCase() !== "false")
71186
+ return true;
71187
+ try {
71188
+ return loadConfig().anthropicApiBilling === true;
71189
+ } catch {
71190
+ return false;
71191
+ }
71192
+ }
71072
71193
  function isProxyAuthMode(config3) {
71073
71194
  return !config3.monitor && !hasNativeAnthropicMapping(config3);
71074
71195
  }
@@ -71332,6 +71453,7 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71332
71453
  [ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelDisplayName,
71333
71454
  CLAUDISH_IS_LOCAL: isLocalModel2 ? "true" : "false"
71334
71455
  };
71456
+ let hidAnthropicApiKey = false;
71335
71457
  delete env.CLAUDECODE;
71336
71458
  if (config3.monitor) {
71337
71459
  delete env.ANTHROPIC_API_KEY;
@@ -71345,9 +71467,14 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71345
71467
  env[ENV.ANTHROPIC_MODEL] = modelId;
71346
71468
  env[ENV.ANTHROPIC_SMALL_FAST_MODEL] = modelId;
71347
71469
  }
71348
- if (hasNativeAnthropicMapping(config3)) {} else {
71349
- env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
71350
- env.ANTHROPIC_AUTH_TOKEN = process.env.ANTHROPIC_AUTH_TOKEN || "placeholder-token-not-used-proxy-handles-auth";
71470
+ if (hasNativeAnthropicMapping(config3)) {
71471
+ if (process.env.ANTHROPIC_API_KEY && !wantsAnthropicApiBilling(config3)) {
71472
+ delete env.ANTHROPIC_API_KEY;
71473
+ hidAnthropicApiKey = true;
71474
+ }
71475
+ } else {
71476
+ env.ANTHROPIC_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
71477
+ env.ANTHROPIC_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth";
71351
71478
  if (!process.env[ENV.CLAUDE_CODE_AUTO_COMPACT_WINDOW]) {
71352
71479
  const autoCompactWindow = await computeMainThreadContextWindow(config3);
71353
71480
  if (autoCompactWindow > 0) {
@@ -71370,6 +71497,9 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71370
71497
  };
71371
71498
  if (!config3.monitor && hasNativeAnthropicMapping(config3)) {
71372
71499
  log2("[claudish] Native Claude model detected \u2014 using Claude Code subscription credentials");
71500
+ if (hidAnthropicApiKey) {
71501
+ log2("[claudish] ANTHROPIC_API_KEY found but hidden so it can't override that subscription \xB7 " + "use --anthropic-api-billing (or anthropicApiBilling: true) to bill the API instead");
71502
+ }
71373
71503
  }
71374
71504
  if (config3.interactive) {
71375
71505
  log2(`
@@ -71417,6 +71547,11 @@ Or set CLAUDE_PATH to your custom installation:`);
71417
71547
  stdio,
71418
71548
  shell: needsShell
71419
71549
  });
71550
+ if (config3.interactive) {
71551
+ restoreTerminal = beginTerminalIsolation((entry) => {
71552
+ logStderr(`[Suppressed] ${entry.source}: ${entry.text.trimEnd()}`);
71553
+ });
71554
+ }
71420
71555
  if (ttyFd !== undefined) {
71421
71556
  const fdToClose = ttyFd;
71422
71557
  proc.on("spawn", () => {
@@ -71432,6 +71567,7 @@ Or set CLAUDE_PATH to your custom installation:`);
71432
71567
  resolve3(code ?? 1);
71433
71568
  });
71434
71569
  });
71570
+ releaseTerminalIsolation();
71435
71571
  try {
71436
71572
  unlinkSync9(tempSettingsPath);
71437
71573
  } catch {}
@@ -71441,6 +71577,7 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
71441
71577
  const signals2 = isWindows2() ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
71442
71578
  for (const signal of signals2) {
71443
71579
  process.on(signal, () => {
71580
+ releaseTerminalIsolation();
71444
71581
  if (!quiet) {
71445
71582
  console.error(`
71446
71583
  [claudish] Received ${signal}, shutting down...`);
@@ -71529,12 +71666,16 @@ async function checkClaudeInstalled() {
71529
71666
  const binary = await findClaudeBinary();
71530
71667
  return binary !== null;
71531
71668
  }
71669
+ var restoreTerminal = null;
71532
71670
  var init_claude_runner = __esm(() => {
71533
71671
  init_model_catalog();
71534
71672
  init_config();
71673
+ init_logger();
71674
+ init_profile_config();
71535
71675
  init_model_parser();
71536
71676
  init_routing_rules();
71537
71677
  init_telemetry();
71678
+ init_terminal_isolation();
71538
71679
  });
71539
71680
 
71540
71681
  // src/diag-output.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.18.0",
3
+ "version": "7.19.0",
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",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "7.18.0",
64
- "@claudish/magmux-darwin-x64": "7.18.0",
65
- "@claudish/magmux-linux-arm64": "7.18.0",
66
- "@claudish/magmux-linux-x64": "7.18.0"
63
+ "@claudish/magmux-darwin-arm64": "7.19.0",
64
+ "@claudish/magmux-darwin-x64": "7.19.0",
65
+ "@claudish/magmux-linux-arm64": "7.19.0",
66
+ "@claudish/magmux-linux-x64": "7.19.0"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",