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.
- package/dist/index.js +160 -19
- 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.
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)) {
|
|
71349
|
-
|
|
71350
|
-
|
|
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.
|
|
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.
|
|
64
|
-
"@claudish/magmux-darwin-x64": "7.
|
|
65
|
-
"@claudish/magmux-linux-arm64": "7.
|
|
66
|
-
"@claudish/magmux-linux-x64": "7.
|
|
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",
|