claudish 7.18.0 → 7.18.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 +123 -15
- 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.
|
|
654
|
+
var VERSION = "7.18.1";
|
|
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:")) {
|
|
@@ -37112,9 +37112,15 @@ function statusToErrorType(status) {
|
|
|
37112
37112
|
return "api_error";
|
|
37113
37113
|
}
|
|
37114
37114
|
}
|
|
37115
|
+
function sanitizeErrorMessage(message, maxLength = MAX_ERROR_MESSAGE_LENGTH) {
|
|
37116
|
+
const flattened = String(message ?? "").replace(ANSI_ESCAPE, "").replace(CONTROL_CHARS, " ").replace(/\s+/g, " ").trim();
|
|
37117
|
+
if (flattened.length <= maxLength)
|
|
37118
|
+
return flattened;
|
|
37119
|
+
return `${flattened.slice(0, maxLength - 1).trimEnd()}\u2026`;
|
|
37120
|
+
}
|
|
37115
37121
|
function wrapAnthropicError(status, message, errorType, upstreamStatus) {
|
|
37116
37122
|
const type = errorType || statusToErrorType(status);
|
|
37117
|
-
const error46 = { type, message };
|
|
37123
|
+
const error46 = { type, message: sanitizeErrorMessage(message) };
|
|
37118
37124
|
if (upstreamStatus !== undefined)
|
|
37119
37125
|
error46.upstream_status = upstreamStatus;
|
|
37120
37126
|
return { type: "error", error: error46 };
|
|
@@ -37178,15 +37184,23 @@ function buildSurfacedErrorMessage(opts) {
|
|
|
37178
37184
|
}
|
|
37179
37185
|
function ensureAnthropicErrorFormat(status, body) {
|
|
37180
37186
|
if (body?.type === "error" && typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
|
|
37181
|
-
return body;
|
|
37187
|
+
return { ...body, error: { ...body.error, message: sanitizeErrorMessage(body.error.message) } };
|
|
37182
37188
|
}
|
|
37183
37189
|
if (typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
|
|
37184
|
-
return {
|
|
37190
|
+
return {
|
|
37191
|
+
type: "error",
|
|
37192
|
+
error: { ...body.error, message: sanitizeErrorMessage(body.error.message) }
|
|
37193
|
+
};
|
|
37185
37194
|
}
|
|
37186
37195
|
const message = body?.error?.message || body?.message || body?.error || (typeof body === "string" ? body : JSON.stringify(body));
|
|
37187
37196
|
const errorType = body?.error?.type || body?.type || body?.code;
|
|
37188
37197
|
return wrapAnthropicError(status, String(message), errorType);
|
|
37189
37198
|
}
|
|
37199
|
+
var MAX_ERROR_MESSAGE_LENGTH = 600, ANSI_ESCAPE, CONTROL_CHARS;
|
|
37200
|
+
var init_anthropic_error = __esm(() => {
|
|
37201
|
+
ANSI_ESCAPE = /\x1B\[[0-?]*[ -/]*[@-~]|\x1B[@-Z\\-_]/g;
|
|
37202
|
+
CONTROL_CHARS = /[\x00-\x1F\x7F]/g;
|
|
37203
|
+
});
|
|
37190
37204
|
|
|
37191
37205
|
// src/handlers/shared/connection-error.ts
|
|
37192
37206
|
function findConnectionCode(error46) {
|
|
@@ -37201,8 +37215,18 @@ function findConnectionCode(error46) {
|
|
|
37201
37215
|
const msg = String(error46?.message ?? error46 ?? "");
|
|
37202
37216
|
if (/getaddrinfo|ENOTFOUND|EAI_AGAIN|nodename nor servname/i.test(msg))
|
|
37203
37217
|
return "ENOTFOUND";
|
|
37218
|
+
if (BUN_CONNECT_MESSAGE.test(msg))
|
|
37219
|
+
return "ConnectionRefused";
|
|
37204
37220
|
return null;
|
|
37205
37221
|
}
|
|
37222
|
+
function isLoopback(endpoint) {
|
|
37223
|
+
try {
|
|
37224
|
+
const { hostname: hostname4 } = new URL(endpoint);
|
|
37225
|
+
return /^(localhost|127\.\d+\.\d+\.\d+|0\.0\.0\.0|\[?::1\]?)$/i.test(hostname4);
|
|
37226
|
+
} catch {
|
|
37227
|
+
return false;
|
|
37228
|
+
}
|
|
37229
|
+
}
|
|
37206
37230
|
function classifyConnectionError(error46) {
|
|
37207
37231
|
const code = findConnectionCode(error46);
|
|
37208
37232
|
if (!code)
|
|
@@ -37222,12 +37246,15 @@ function buildConnectionErrorMessage(kind, displayName, endpoint) {
|
|
|
37222
37246
|
case "dns":
|
|
37223
37247
|
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
37248
|
case "refused":
|
|
37225
|
-
|
|
37249
|
+
if (isLoopback(endpoint)) {
|
|
37250
|
+
return `Cannot connect to ${displayName} at ${endpoint}. Make sure the server is running.`;
|
|
37251
|
+
}
|
|
37252
|
+
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
37253
|
case "unreachable":
|
|
37227
37254
|
return `Cannot reach ${displayName} at ${endpoint}. Check your network connection.`;
|
|
37228
37255
|
}
|
|
37229
37256
|
}
|
|
37230
|
-
var CODE_KIND;
|
|
37257
|
+
var CODE_KIND, BUN_CONNECT_MESSAGE;
|
|
37231
37258
|
var init_connection_error = __esm(() => {
|
|
37232
37259
|
CODE_KIND = {
|
|
37233
37260
|
ENOTFOUND: "dns",
|
|
@@ -37239,8 +37266,13 @@ var init_connection_error = __esm(() => {
|
|
|
37239
37266
|
EHOSTUNREACH: "unreachable",
|
|
37240
37267
|
EPIPE: "unreachable",
|
|
37241
37268
|
UND_ERR_CONNECT_TIMEOUT: "unreachable",
|
|
37242
|
-
UND_ERR_SOCKET: "unreachable"
|
|
37269
|
+
UND_ERR_SOCKET: "unreachable",
|
|
37270
|
+
ConnectionRefused: "refused",
|
|
37271
|
+
ConnectionClosed: "unreachable",
|
|
37272
|
+
FailedToOpenSocket: "unreachable",
|
|
37273
|
+
ERR_SOCKET_CLOSED: "unreachable"
|
|
37243
37274
|
};
|
|
37275
|
+
BUN_CONNECT_MESSAGE = /unable to connect\. is the computer able to access the url\?/i;
|
|
37244
37276
|
});
|
|
37245
37277
|
|
|
37246
37278
|
// src/handlers/shared/stream-parsers/anthropic-sse.ts
|
|
@@ -38206,6 +38238,7 @@ data: ${JSON.stringify(data)}
|
|
|
38206
38238
|
var init_openai_responses_sse = __esm(() => {
|
|
38207
38239
|
init_reasoning_cache();
|
|
38208
38240
|
init_logger();
|
|
38241
|
+
init_anthropic_error();
|
|
38209
38242
|
});
|
|
38210
38243
|
|
|
38211
38244
|
// src/handlers/shared/token-tracker.ts
|
|
@@ -38548,7 +38581,7 @@ class ComposedHandler {
|
|
|
38548
38581
|
isInteractive: this.isInteractive,
|
|
38549
38582
|
authType: "oauth"
|
|
38550
38583
|
});
|
|
38551
|
-
return c.json(
|
|
38584
|
+
return c.json(wrapAnthropicError(401, err.message, "authentication_error"), 401);
|
|
38552
38585
|
}
|
|
38553
38586
|
}
|
|
38554
38587
|
if (this.provider.getContextWindow) {
|
|
@@ -38614,7 +38647,7 @@ class ComposedHandler {
|
|
|
38614
38647
|
invocation_mode: this.options.invocationMode ?? "auto-route"
|
|
38615
38648
|
});
|
|
38616
38649
|
} catch {}
|
|
38617
|
-
return c.json(wrapAnthropicError(
|
|
38650
|
+
return c.json(wrapAnthropicError(400, msg, "connection_error"), 400);
|
|
38618
38651
|
}
|
|
38619
38652
|
throw error46;
|
|
38620
38653
|
}
|
|
@@ -38951,6 +38984,7 @@ var init_composed_handler = __esm(() => {
|
|
|
38951
38984
|
init_stats();
|
|
38952
38985
|
init_telemetry();
|
|
38953
38986
|
init_transform();
|
|
38987
|
+
init_anthropic_error();
|
|
38954
38988
|
init_connection_error();
|
|
38955
38989
|
init_openai_compat();
|
|
38956
38990
|
init_anthropic_sse();
|
|
@@ -39907,6 +39941,7 @@ var init_native_handler = __esm(() => {
|
|
|
39907
39941
|
init_logger();
|
|
39908
39942
|
init_profile_config();
|
|
39909
39943
|
init_native_handler_advisor();
|
|
39944
|
+
init_anthropic_error();
|
|
39910
39945
|
});
|
|
39911
39946
|
|
|
39912
39947
|
// src/providers/api-key-map.ts
|
|
@@ -43482,7 +43517,7 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
|
|
|
43482
43517
|
log(`[Proxy] Registered ${customEpResult.registered} custom endpoint(s) from config`);
|
|
43483
43518
|
}
|
|
43484
43519
|
for (const err of customEpResult.errors) {
|
|
43485
|
-
|
|
43520
|
+
logStderr(`customEndpoints['${err.name}'] failed validation: ${err.message}`);
|
|
43486
43521
|
}
|
|
43487
43522
|
} catch (err) {
|
|
43488
43523
|
log(`[Proxy] customEndpoints load skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -43570,9 +43605,10 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
|
|
|
43570
43605
|
const resolution = resolveModelProvider(targetModel);
|
|
43571
43606
|
if (resolution.wasAutoRouted && resolution.autoRouteMessage) {
|
|
43572
43607
|
if (!options.quiet) {
|
|
43573
|
-
|
|
43608
|
+
logStderr(`[Auto-route] ${resolution.autoRouteMessage}`);
|
|
43609
|
+
} else {
|
|
43610
|
+
log(`[Auto-route] ${resolution.autoRouteMessage}`);
|
|
43574
43611
|
}
|
|
43575
|
-
log(`[Auto-route] ${resolution.autoRouteMessage}`);
|
|
43576
43612
|
}
|
|
43577
43613
|
if (resolution.category === "openrouter") {
|
|
43578
43614
|
if (resolution.wasAutoRouted && resolution.fullModelId) {
|
|
@@ -43591,7 +43627,7 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
|
|
|
43591
43627
|
let apiKey = "";
|
|
43592
43628
|
if (resolved.provider.apiKeyEnvVar) {
|
|
43593
43629
|
if (!credentials.get(resolved.provider.name)) {
|
|
43594
|
-
|
|
43630
|
+
logStderr(`[Proxy] No credential provider registered for "${resolved.provider.name}" \u2014 treating as missing credential (authority registration gap)`);
|
|
43595
43631
|
log(`[Proxy] Credential authority has no provider registered under "${resolved.provider.name}"`);
|
|
43596
43632
|
return null;
|
|
43597
43633
|
}
|
|
@@ -43749,6 +43785,11 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
|
|
|
43749
43785
|
};
|
|
43750
43786
|
const app = new Hono2;
|
|
43751
43787
|
app.use("*", cors());
|
|
43788
|
+
app.onError((err, c) => {
|
|
43789
|
+
logStderr(`[Proxy] Unhandled error on ${c.req.method} ${c.req.path}: ${err?.message ?? err}`);
|
|
43790
|
+
log(`[Proxy] Unhandled error stack: ${err?.stack ?? "(no stack)"}`);
|
|
43791
|
+
return c.json(wrapAnthropicError(500, `Proxy error: ${err?.message ?? String(err)}`), 500);
|
|
43792
|
+
});
|
|
43752
43793
|
app.get("/", (c) => c.json({
|
|
43753
43794
|
status: "ok",
|
|
43754
43795
|
message: "Claudish Proxy",
|
|
@@ -43828,7 +43869,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
|
|
|
43828
43869
|
const body = await c.req.json();
|
|
43829
43870
|
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
43871
|
const handler = await getHandlerForRequest(body.model);
|
|
43831
|
-
return handler.handle(c, body);
|
|
43872
|
+
return await handler.handle(c, body);
|
|
43832
43873
|
} catch (e) {
|
|
43833
43874
|
log(`[Proxy] Error: ${e}`);
|
|
43834
43875
|
if (e instanceof RoutingError) {
|
|
@@ -43882,6 +43923,7 @@ var init_proxy_server = __esm(() => {
|
|
|
43882
43923
|
init_composed_handler();
|
|
43883
43924
|
init_fallback_handler();
|
|
43884
43925
|
init_native_handler();
|
|
43926
|
+
init_anthropic_error();
|
|
43885
43927
|
init_logger();
|
|
43886
43928
|
init_model_loader();
|
|
43887
43929
|
init_profile_config();
|
|
@@ -71036,6 +71078,56 @@ var init_tui = __esm(() => {
|
|
|
71036
71078
|
}
|
|
71037
71079
|
});
|
|
71038
71080
|
|
|
71081
|
+
// src/terminal-isolation.ts
|
|
71082
|
+
import { format } from "util";
|
|
71083
|
+
function beginTerminalIsolation(onSuppressed) {
|
|
71084
|
+
if (active)
|
|
71085
|
+
return () => {};
|
|
71086
|
+
active = true;
|
|
71087
|
+
const emit2 = (source, text) => {
|
|
71088
|
+
if (routing)
|
|
71089
|
+
return;
|
|
71090
|
+
routing = true;
|
|
71091
|
+
try {
|
|
71092
|
+
onSuppressed({ source, text });
|
|
71093
|
+
} catch {} finally {
|
|
71094
|
+
routing = false;
|
|
71095
|
+
}
|
|
71096
|
+
};
|
|
71097
|
+
const originalConsole = {};
|
|
71098
|
+
for (const method of CONSOLE_METHODS) {
|
|
71099
|
+
originalConsole[method] = console[method];
|
|
71100
|
+
console[method] = (...args) => {
|
|
71101
|
+
emit2(`console.${method}`, format(...args));
|
|
71102
|
+
};
|
|
71103
|
+
}
|
|
71104
|
+
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
71105
|
+
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
71106
|
+
const makeWrite = (source) => (chunk, encoding, callback) => {
|
|
71107
|
+
const done = typeof encoding === "function" ? encoding : callback;
|
|
71108
|
+
emit2(source, typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8"));
|
|
71109
|
+
if (typeof done === "function")
|
|
71110
|
+
done(null);
|
|
71111
|
+
return true;
|
|
71112
|
+
};
|
|
71113
|
+
process.stdout.write = makeWrite("stdout");
|
|
71114
|
+
process.stderr.write = makeWrite("stderr");
|
|
71115
|
+
return function restore() {
|
|
71116
|
+
if (!active)
|
|
71117
|
+
return;
|
|
71118
|
+
for (const method of CONSOLE_METHODS) {
|
|
71119
|
+
console[method] = originalConsole[method];
|
|
71120
|
+
}
|
|
71121
|
+
process.stdout.write = originalStdoutWrite;
|
|
71122
|
+
process.stderr.write = originalStderrWrite;
|
|
71123
|
+
active = false;
|
|
71124
|
+
};
|
|
71125
|
+
}
|
|
71126
|
+
var CONSOLE_METHODS, active = false, routing = false;
|
|
71127
|
+
var init_terminal_isolation = __esm(() => {
|
|
71128
|
+
CONSOLE_METHODS = ["log", "error", "warn", "info", "debug", "trace", "dir"];
|
|
71129
|
+
});
|
|
71130
|
+
|
|
71039
71131
|
// src/claude-runner.ts
|
|
71040
71132
|
var exports_claude_runner = {};
|
|
71041
71133
|
__export(exports_claude_runner, {
|
|
@@ -71059,6 +71151,12 @@ import {
|
|
|
71059
71151
|
import { homedir as homedir24, tmpdir as tmpdir2 } from "os";
|
|
71060
71152
|
import { join as join25 } from "path";
|
|
71061
71153
|
import { isatty } from "tty";
|
|
71154
|
+
function releaseTerminalIsolation() {
|
|
71155
|
+
if (!restoreTerminal)
|
|
71156
|
+
return;
|
|
71157
|
+
restoreTerminal();
|
|
71158
|
+
restoreTerminal = null;
|
|
71159
|
+
}
|
|
71062
71160
|
function hasNativeAnthropicMapping(config3) {
|
|
71063
71161
|
const models = [
|
|
71064
71162
|
config3.model,
|
|
@@ -71417,6 +71515,11 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
71417
71515
|
stdio,
|
|
71418
71516
|
shell: needsShell
|
|
71419
71517
|
});
|
|
71518
|
+
if (config3.interactive) {
|
|
71519
|
+
restoreTerminal = beginTerminalIsolation((entry) => {
|
|
71520
|
+
logStderr(`[Suppressed] ${entry.source}: ${entry.text.trimEnd()}`);
|
|
71521
|
+
});
|
|
71522
|
+
}
|
|
71420
71523
|
if (ttyFd !== undefined) {
|
|
71421
71524
|
const fdToClose = ttyFd;
|
|
71422
71525
|
proc.on("spawn", () => {
|
|
@@ -71432,6 +71535,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
71432
71535
|
resolve3(code ?? 1);
|
|
71433
71536
|
});
|
|
71434
71537
|
});
|
|
71538
|
+
releaseTerminalIsolation();
|
|
71435
71539
|
try {
|
|
71436
71540
|
unlinkSync9(tempSettingsPath);
|
|
71437
71541
|
} catch {}
|
|
@@ -71441,6 +71545,7 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
71441
71545
|
const signals2 = isWindows2() ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
71442
71546
|
for (const signal of signals2) {
|
|
71443
71547
|
process.on(signal, () => {
|
|
71548
|
+
releaseTerminalIsolation();
|
|
71444
71549
|
if (!quiet) {
|
|
71445
71550
|
console.error(`
|
|
71446
71551
|
[claudish] Received ${signal}, shutting down...`);
|
|
@@ -71529,12 +71634,15 @@ async function checkClaudeInstalled() {
|
|
|
71529
71634
|
const binary = await findClaudeBinary();
|
|
71530
71635
|
return binary !== null;
|
|
71531
71636
|
}
|
|
71637
|
+
var restoreTerminal = null;
|
|
71532
71638
|
var init_claude_runner = __esm(() => {
|
|
71533
71639
|
init_model_catalog();
|
|
71534
71640
|
init_config();
|
|
71641
|
+
init_logger();
|
|
71535
71642
|
init_model_parser();
|
|
71536
71643
|
init_routing_rules();
|
|
71537
71644
|
init_telemetry();
|
|
71645
|
+
init_terminal_isolation();
|
|
71538
71646
|
});
|
|
71539
71647
|
|
|
71540
71648
|
// src/diag-output.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.18.
|
|
3
|
+
"version": "7.18.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",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"ai"
|
|
61
61
|
],
|
|
62
62
|
"optionalDependencies": {
|
|
63
|
-
"@claudish/magmux-darwin-arm64": "7.18.
|
|
64
|
-
"@claudish/magmux-darwin-x64": "7.18.
|
|
65
|
-
"@claudish/magmux-linux-arm64": "7.18.
|
|
66
|
-
"@claudish/magmux-linux-x64": "7.18.
|
|
63
|
+
"@claudish/magmux-darwin-arm64": "7.18.1",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.18.1",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.18.1",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.18.1"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|