claudish 14.18.2 → 14.18.3

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 +172 -106
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -5494,7 +5494,7 @@ var init_onepassword_config = __esm(() => {
5494
5494
  });
5495
5495
 
5496
5496
  // src/version.ts
5497
- var VERSION = "14.18.2";
5497
+ var VERSION = "14.18.3";
5498
5498
 
5499
5499
  // src/redact.ts
5500
5500
  function isPlaceholder(value) {
@@ -93087,8 +93087,29 @@ function bodyToForward(c, payload) {
93087
93087
  const inbound = c.get(INBOUND_BODY_KEY);
93088
93088
  return inbound !== undefined && inbound.canonical === serialized ? inbound.raw : serialized;
93089
93089
  }
93090
- var ALLOWED_NAMES, HOP_BY_HOP, INTERNAL_PREFIX = "x-claudish-", ALLOWED_QUERY_NAMES, INBOUND_BODY_KEY = "inboundBody";
93090
+ async function buildForwardRequest(c, payload, endpoint, fallbackKey) {
93091
+ const headers = {
93092
+ ...requestHeadersToForward(c.req.raw.headers),
93093
+ ...inboundAuthHeaders(c.req.raw.headers)
93094
+ };
93095
+ if (headers.authorization && CLAUDE_LOGIN_BEARER.test(headers.authorization)) {
93096
+ delete headers["x-api-key"];
93097
+ }
93098
+ headers["content-type"] = "application/json";
93099
+ if (!headers["anthropic-version"])
93100
+ headers["anthropic-version"] = "2023-06-01";
93101
+ if (!headers.authorization && !headers["x-api-key"]) {
93102
+ const key = await fallbackKey();
93103
+ if (key)
93104
+ headers["x-api-key"] = key;
93105
+ }
93106
+ const url = `${endpoint}${forwardedSearch(c)}`;
93107
+ addSigningSecrets(c, credentialValuesFromRequest(headers, url));
93108
+ return { headers, url, body: bodyToForward(c, payload) };
93109
+ }
93110
+ var ALLOWED_NAMES, HOP_BY_HOP, INTERNAL_PREFIX = "x-claudish-", ALLOWED_QUERY_NAMES, INBOUND_BODY_KEY = "inboundBody", CLAUDE_LOGIN_BEARER;
93091
93111
  var init_anthropic_forward = __esm(() => {
93112
+ init_call_context();
93092
93113
  ALLOWED_NAMES = new Set([
93093
93114
  "authorization",
93094
93115
  "x-api-key",
@@ -93124,6 +93145,7 @@ var init_anthropic_forward = __esm(() => {
93124
93145
  "content-length"
93125
93146
  ]);
93126
93147
  ALLOWED_QUERY_NAMES = new Set(["beta"]);
93148
+ CLAUDE_LOGIN_BEARER = /^Bearer\s+sk-ant-oat\d+-/i;
93127
93149
  });
93128
93150
 
93129
93151
  // src/handlers/shared/thinking-signature.ts
@@ -93216,36 +93238,26 @@ class NativeHandler {
93216
93238
  }
93217
93239
  async handle(c, incoming) {
93218
93240
  const payload = await this.applyRequestHooks(c, incoming);
93219
- const headers = {
93220
- ...requestHeadersToForward(c.req.raw.headers),
93221
- ...inboundAuthHeaders(c.req.raw.headers)
93222
- };
93223
93241
  const target = payload.model;
93224
93242
  const strippedThinking = stripUnsignedThinkingBlocks(payload.messages);
93225
93243
  if (strippedThinking > 0) {
93226
93244
  log(`[Native] stripped ${strippedThinking} unsigned thinking block(s) from history for ${target} (foreign-provider origin)`);
93227
93245
  }
93228
93246
  const advisorSwapped = c.get(ADVISOR_SWAPPED_CONTEXT_KEY) === true;
93247
+ const inboundAuth = inboundAuthHeaders(c.req.raw.headers);
93229
93248
  log(`
93230
93249
  === [NATIVE] Claude Code \u2192 Anthropic API Request ===`);
93231
- log(`[Native] x-api-key: ${headers["x-api-key"] ? maskCredential(headers["x-api-key"]) : "(not set)"}`);
93232
- log(`[Native] authorization: ${headers.authorization ? maskCredential(headers.authorization) : "(not set)"}`);
93250
+ log(`[Native] x-api-key: ${inboundAuth["x-api-key"] ? maskCredential(inboundAuth["x-api-key"]) : "(not set)"}`);
93251
+ log(`[Native] authorization: ${inboundAuth.authorization ? maskCredential(inboundAuth.authorization) : "(not set)"}`);
93233
93252
  log(`Request body (Model: ${target}):`);
93234
93253
  log(`=== End Request ===
93235
93254
  `);
93236
- headers["content-type"] = "application/json";
93237
- if (!headers["anthropic-version"])
93238
- headers["anthropic-version"] = "2023-06-01";
93239
- if (!headers.authorization && !headers["x-api-key"]) {
93240
- let fallbackKey = this.apiKey;
93241
- if (!fallbackKey) {
93242
- const auth = await credentials.getRequestAuth("native-anthropic", { model: target });
93243
- fallbackKey = auth.headers["x-api-key"];
93244
- }
93245
- if (fallbackKey) {
93246
- headers["x-api-key"] = fallbackKey;
93247
- }
93248
- }
93255
+ const { headers, url, body } = await buildForwardRequest(c, payload, `${this.baseUrl}/v1/messages`, async () => {
93256
+ if (this.apiKey)
93257
+ return this.apiKey;
93258
+ const auth = await credentials.getRequestAuth("native-anthropic", { model: target });
93259
+ return auth.headers["x-api-key"];
93260
+ });
93249
93261
  const incomingBeta = headers["anthropic-beta"];
93250
93262
  if (incomingBeta && advisorSwapped) {
93251
93263
  const { stripped, changed } = stripAdvisorBeta(incomingBeta);
@@ -93262,9 +93274,6 @@ class NativeHandler {
93262
93274
  else
93263
93275
  delete headers["anthropic-beta"];
93264
93276
  }
93265
- const url = `${this.baseUrl}/v1/messages${forwardedSearch(c)}`;
93266
- addSigningSecrets(c, credentialValuesFromRequest(headers, url));
93267
- const body = bodyToForward(c, payload);
93268
93277
  try {
93269
93278
  const anthropicResponse = await fetch(url, {
93270
93279
  method: "POST",
@@ -93419,7 +93428,6 @@ var init_native_handler = __esm(() => {
93419
93428
  init_native_handler_advisor();
93420
93429
  init_anthropic_error();
93421
93430
  init_anthropic_forward();
93422
- init_call_context();
93423
93431
  });
93424
93432
 
93425
93433
  // src/hooks/seam-hooks.ts
@@ -94471,43 +94479,31 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
94471
94479
  });
94472
94480
  app.post("/v1/messages/count_tokens", async (c) => {
94473
94481
  try {
94474
- const body = await c.req.json();
94482
+ const rawBody = await c.req.text();
94483
+ const body = JSON.parse(rawBody);
94484
+ recordInboundBody(c, rawBody, body);
94475
94485
  if (typeof body?.model !== "string" || body.model.length === 0) {
94476
94486
  return c.json(wrapAnthropicError(400, "missing required field: model"), 400);
94477
94487
  }
94478
94488
  const handler = await getHandlerForRequest(body.model);
94479
94489
  if (handler instanceof NativeHandler) {
94480
- const inbound = c.req.header();
94481
- const headers = {
94482
- "Content-Type": "application/json",
94483
- "anthropic-version": inbound["anthropic-version"] || "2023-06-01"
94484
- };
94485
- if (inbound.authorization)
94486
- headers.authorization = inbound.authorization;
94487
- if (inbound["x-api-key"])
94488
- headers["x-api-key"] = inbound["x-api-key"];
94489
- if (inbound["anthropic-beta"])
94490
- headers["anthropic-beta"] = inbound["anthropic-beta"];
94491
- if (!inbound.authorization && !inbound["x-api-key"]) {
94492
- let fallbackKey = anthropicApiKey;
94493
- if (!fallbackKey) {
94494
- try {
94495
- const auth = await credentials.getRequestAuth("native-anthropic", {
94496
- model: body.model
94497
- });
94498
- fallbackKey = auth.headers["x-api-key"];
94499
- } catch (err) {
94500
- log(`[CountTokens] no resolvable Anthropic credential: ${err}`);
94501
- }
94490
+ const forward = await buildForwardRequest(c, body, resolveUpstreamUrl("https://api.anthropic.com/v1/messages/count_tokens"), async () => {
94491
+ if (anthropicApiKey)
94492
+ return anthropicApiKey;
94493
+ try {
94494
+ const auth = await credentials.getRequestAuth("native-anthropic", {
94495
+ model: body.model
94496
+ });
94497
+ return auth.headers["x-api-key"];
94498
+ } catch (err) {
94499
+ log(`[CountTokens] no resolvable Anthropic credential: ${err}`);
94500
+ return;
94502
94501
  }
94503
- if (fallbackKey)
94504
- headers["x-api-key"] = fallbackKey;
94505
- }
94506
- addSigningSecrets(c, credentialValuesFromRequest(headers));
94507
- const res = await fetch(resolveUpstreamUrl("https://api.anthropic.com/v1/messages/count_tokens"), {
94502
+ });
94503
+ const res = await fetch(forward.url, {
94508
94504
  method: "POST",
94509
- headers,
94510
- body: JSON.stringify(body)
94505
+ headers: forward.headers,
94506
+ body: forward.body
94511
94507
  });
94512
94508
  if (res.status === 401 || res.status === 403) {
94513
94509
  log(`[CountTokens] upstream ${res.status} \u2014 falling back to the local estimate`);
@@ -96521,11 +96517,12 @@ function readProcessTable() {
96521
96517
  }
96522
96518
  return tableOf(stdout, spawnedAt);
96523
96519
  }
96524
- function readProcessTableAsync() {
96520
+ function readProcessTableAsync(cancelAfterMs) {
96521
+ const options = cancelAfterMs === undefined ? PS_OPTIONS : { ...PS_OPTIONS, timeout: cancelAfterMs, killSignal: "SIGKILL" };
96525
96522
  return new Promise((resolve) => {
96526
96523
  const spawnedAt = Date.now();
96527
96524
  try {
96528
- psSpawn.execFile("ps", PS_ARGS, PS_OPTIONS, (err, stdout) => resolve(tableOf(err ? null : String(stdout), spawnedAt)));
96525
+ psSpawn.execFile("ps", PS_ARGS, options, (err, stdout) => resolve(tableOf(err ? null : String(stdout), spawnedAt)));
96529
96526
  } catch {
96530
96527
  resolve(tableOf(null, spawnedAt));
96531
96528
  }
@@ -96582,11 +96579,14 @@ function escapedDescendants(table, pgid, inGroup) {
96582
96579
  }
96583
96580
  return out;
96584
96581
  }
96582
+ function liveMembers(table, members) {
96583
+ const keys = new Set(members.map((m) => `${m.pid} ${collapse(m.lstart)}`));
96584
+ return table.filter((r) => keys.has(`${r.pid} ${r.lstart}`)).map((r) => r.pid);
96585
+ }
96585
96586
  function liveEscaped(table, snap) {
96586
96587
  if (!snap?.escaped?.length)
96587
96588
  return [];
96588
- const keys = new Set(snap.escaped.map((m) => `${m.pid} ${collapse(m.lstart)}`));
96589
- return table.filter((r) => keys.has(`${r.pid} ${r.lstart}`)).map((r) => r.pid);
96589
+ return liveMembers(table, snap.escaped);
96590
96590
  }
96591
96591
  function mergeSnapshots(a, b, table) {
96592
96592
  if (!a)
@@ -97467,8 +97467,62 @@ function waitForExit(proc, ms) {
97467
97467
  t.unref?.();
97468
97468
  });
97469
97469
  }
97470
+ function descendantsOf(table, rootPid) {
97471
+ const childrenOf = new Map;
97472
+ for (const { pid, ppid, lstart } of table) {
97473
+ const siblings = childrenOf.get(ppid);
97474
+ if (siblings)
97475
+ siblings.push({ pid, lstart });
97476
+ else
97477
+ childrenOf.set(ppid, [{ pid, lstart }]);
97478
+ }
97479
+ const seen = new Set([rootPid, process.pid]);
97480
+ const out = [];
97481
+ const queue = [rootPid];
97482
+ for (let parent = queue.shift();parent !== undefined; parent = queue.shift()) {
97483
+ for (const child of childrenOf.get(parent) ?? []) {
97484
+ if (child.pid <= 1 || seen.has(child.pid))
97485
+ continue;
97486
+ seen.add(child.pid);
97487
+ out.push(child);
97488
+ queue.push(child.pid);
97489
+ }
97490
+ }
97491
+ return out;
97492
+ }
97493
+ async function readTableWithin(budgetMs) {
97494
+ let timer;
97495
+ const table = await Promise.race([
97496
+ readProcessTableAsync(budgetMs),
97497
+ new Promise((resolve) => {
97498
+ timer = setTimeout(() => resolve(null), budgetMs);
97499
+ timer.unref?.();
97500
+ })
97501
+ ]);
97502
+ clearTimeout(timer);
97503
+ return table;
97504
+ }
97505
+ async function snapshotDescendants(rootPid, budgetMs) {
97506
+ const table = await readTableWithin(budgetMs);
97507
+ return table ? descendantsOf(table, rootPid) : [];
97508
+ }
97509
+ async function killStillLiveMembers(members, budgetMs) {
97510
+ if (members.length === 0)
97511
+ return 0;
97512
+ const table = await readTableWithin(budgetMs);
97513
+ if (!table)
97514
+ return 0;
97515
+ const pids = liveMembers(table, members);
97516
+ for (const pid of pids) {
97517
+ try {
97518
+ process.kill(pid, "SIGKILL");
97519
+ } catch {}
97520
+ }
97521
+ return pids.length;
97522
+ }
97470
97523
  var KILL_PROCESS_GROUP;
97471
97524
  var init_process_tree = __esm(() => {
97525
+ init_process_identity();
97472
97526
  KILL_PROCESS_GROUP = process.platform !== "win32";
97473
97527
  });
97474
97528
 
@@ -98962,58 +99016,61 @@ Or set CLAUDE_PATH to your custom installation:`);
98962
99016
  }
98963
99017
  log(exitSignal ? `[Claude Code] Exited from ${exitSignal} (exit code ${exitCode})` : `[Claude Code] Exited with code ${exitCode}`);
98964
99018
  releaseTerminalIsolation();
98965
- try {
98966
- unlinkSync11(tempSettingsPath);
98967
- } catch {}
98968
- signalShutdown.launcherCleanupDone();
98969
- if (signalShutdown.started())
98970
- return new Promise(() => {});
98971
- return exitCode;
99019
+ signalShutdown.removeSettingsFile();
99020
+ await signalShutdown.claudeCodeStopped();
99021
+ return signalShutdownExitCode() ?? exitCode;
98972
99022
  }
98973
99023
  function sessionOutcomeOf(exitCode) {
98974
99024
  return exitCode === 0 ? { state: "COMPLETED", reason: null, exitCode } : { state: "FAILED", reason: "child_exited", exitCode };
98975
99025
  }
98976
- function delay(ms) {
98977
- return new Promise((resolve) => {
98978
- const t = setTimeout(resolve, Math.max(0, ms));
98979
- t.unref?.();
98980
- });
99026
+ function signalShutdownExitCode() {
99027
+ return signalShutdownCode;
98981
99028
  }
98982
99029
  function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
98983
99030
  const signals = isWindows2() ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
98984
99031
  let shuttingDown = null;
98985
- let markLauncherCleanupDone = () => {};
98986
- const launcherCleanup = new Promise((resolve) => {
98987
- markLauncherCleanupDone = resolve;
98988
- });
98989
- const shutdown = async (signal) => {
98990
- const startedAt = Date.now();
99032
+ let claudeCodeStopped = Promise.resolve();
99033
+ let settingsFileRemoved = false;
99034
+ const removeSettingsFile = () => {
99035
+ if (settingsFileRemoved)
99036
+ return;
99037
+ settingsFileRemoved = true;
99038
+ try {
99039
+ unlinkSync11(tempSettingsPath);
99040
+ } catch {}
99041
+ };
99042
+ const stopClaudeCode = async () => {
98991
99043
  try {
98992
99044
  proc.kill("SIGTERM");
98993
- if (!await waitForExit(proc, SIGNAL_CHILD_EXIT_GRACE_MS)) {
98994
- log(`[claudish] Claude Code did not exit within ${SIGNAL_CHILD_EXIT_GRACE_MS} ms of SIGTERM; sending SIGKILL`);
98995
- try {
98996
- proc.kill("SIGKILL");
98997
- } catch {}
98998
- await waitForExit(proc, SIGNAL_CHILD_KILL_WAIT_MS);
99045
+ if (await waitForExit(proc, SIGNAL_CHILD_EXIT_GRACE_MS))
99046
+ return;
99047
+ log(`[claudish] Claude Code did not exit within ${SIGNAL_CHILD_EXIT_GRACE_MS} ms of SIGTERM; sending SIGKILL`);
99048
+ const killStepStartedAt = Date.now();
99049
+ const descendants = proc.pid ? await snapshotDescendants(proc.pid, SIGNAL_DESCENDANT_READ_MS) : [];
99050
+ if (proc.exitCode !== null || proc.signalCode !== null)
99051
+ return;
99052
+ let killed = 0;
99053
+ try {
99054
+ proc.kill("SIGKILL");
99055
+ } finally {
99056
+ killed = await killStillLiveMembers(descendants, SIGNAL_DESCENDANT_READ_MS);
98999
99057
  }
99000
- await Promise.race([
99001
- launcherCleanup,
99002
- delay(SIGNAL_SHUTDOWN_BUDGET_MS - (Date.now() - startedAt))
99003
- ]);
99058
+ log(`[claudish] Sent SIGKILL to Claude Code and ${killed} of ${descendants.length} descendants`);
99059
+ await waitForExit(proc, SIGNAL_CHILD_KILL_WAIT_MS - (Date.now() - killStepStartedAt));
99004
99060
  } catch (err) {
99005
99061
  log(`[claudish] Signal shutdown error: ${err}`);
99006
- } finally {
99007
- if (onCleanup) {
99008
- try {
99009
- onCleanup();
99010
- } catch {}
99011
- }
99062
+ }
99063
+ };
99064
+ const armDeadline = (code) => {
99065
+ const deadline = setTimeout(() => {
99066
+ log(`[claudish] Signal shutdown passed ${SIGNAL_SHUTDOWN_BUDGET_MS} ms; exiting`);
99012
99067
  try {
99013
- unlinkSync11(tempSettingsPath);
99068
+ onCleanup?.();
99014
99069
  } catch {}
99015
- process.exit(signalExitCode(signal));
99016
- }
99070
+ removeSettingsFile();
99071
+ process.exit(code);
99072
+ }, SIGNAL_SHUTDOWN_BUDGET_MS);
99073
+ deadline.unref?.();
99017
99074
  };
99018
99075
  claimSignalExit();
99019
99076
  for (const signal of signals) {
@@ -99023,18 +99080,19 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
99023
99080
  return;
99024
99081
  }
99025
99082
  shuttingDown = signal;
99083
+ const code = signalExitCode(signal);
99084
+ signalShutdownCode = code;
99085
+ process.exitCode = code;
99086
+ armDeadline(code);
99026
99087
  releaseTerminalIsolation();
99027
99088
  if (!quiet) {
99028
99089
  console.error(`
99029
99090
  [claudish] Received ${signal}, shutting down...`);
99030
99091
  }
99031
- shutdown(signal);
99092
+ claudeCodeStopped = stopClaudeCode();
99032
99093
  });
99033
99094
  }
99034
- return {
99035
- started: () => shuttingDown !== null,
99036
- launcherCleanupDone: () => markLauncherCleanupDone()
99037
- };
99095
+ return { removeSettingsFile, claudeCodeStopped: () => claudeCodeStopped };
99038
99096
  }
99039
99097
  async function findClaudeBinary(env = process.env) {
99040
99098
  const isWindows = process.platform === "win32";
@@ -99135,7 +99193,7 @@ var restoreTerminal = null, macosKeychainAnthropicMemo, defaultKeychainAnthropic
99135
99193
  }
99136
99194
  macosKeychainAnthropicMemo.set(memoKey, found);
99137
99195
  return found;
99138
- }, CLAUDISH_PLACEHOLDER_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx", CLAUDISH_PLACEHOLDER_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth", STALE_TOKEN_FILE_MS, MAX_TOKEN_FILES_SCANNED = 4000, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, USER_STATUS_LINE_TIMEOUT_SECONDS = 3, MIN_AUTO_COMPACT_WINDOW = 200000, MAX_AUTO_COMPACT_WINDOW = 1e6, ADVISOR_TOOL_ENV_VAR = "CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL", CLAUDISH_CHILD_ADVISOR_MODEL = "sonnet", CHILD_STDERR_NOISE, SIGNAL_CHILD_EXIT_GRACE_MS = 3000, SIGNAL_CHILD_KILL_WAIT_MS = 500, SIGNAL_SHUTDOWN_BUDGET_MS = 4000;
99196
+ }, CLAUDISH_PLACEHOLDER_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx", CLAUDISH_PLACEHOLDER_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth", STALE_TOKEN_FILE_MS, MAX_TOKEN_FILES_SCANNED = 4000, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, USER_STATUS_LINE_TIMEOUT_SECONDS = 3, MIN_AUTO_COMPACT_WINDOW = 200000, MAX_AUTO_COMPACT_WINDOW = 1e6, ADVISOR_TOOL_ENV_VAR = "CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL", CLAUDISH_CHILD_ADVISOR_MODEL = "sonnet", CHILD_STDERR_NOISE, SIGNAL_CHILD_EXIT_GRACE_MS = 2000, SIGNAL_CHILD_KILL_WAIT_MS = 500, SIGNAL_DESCENDANT_READ_MS = 200, SIGNAL_SHUTDOWN_BUDGET_MS = 4500, signalShutdownCode = null;
99139
99197
  var init_claude_runner = __esm(() => {
99140
99198
  init_model_catalog();
99141
99199
  init_claude_code_facts();
@@ -125287,11 +125345,18 @@ Team Status`);
125287
125345
  }
125288
125346
  finalizeStartupTrace("run", { quiet: cliConfig.quiet });
125289
125347
  let exitCode = 0;
125348
+ let diagCleaned = false;
125349
+ const cleanupDiag = () => {
125350
+ if (diagCleaned)
125351
+ return;
125352
+ diagCleaned = true;
125353
+ diag.cleanup();
125354
+ };
125290
125355
  try {
125291
- exitCode = await runClaudeWithProxy(cliConfig, proxy.url, () => diag.cleanup());
125356
+ exitCode = await runClaudeWithProxy(cliConfig, proxy.url, cleanupDiag);
125292
125357
  } finally {
125293
125358
  setDiagOutput(null);
125294
- diag.cleanup();
125359
+ cleanupDiag();
125295
125360
  if (!cliConfig.quiet) {
125296
125361
  const write = cliConfig.interactive ? console.log : console.error;
125297
125362
  write(`
@@ -125331,8 +125396,9 @@ Team Status`);
125331
125396
  console.error(`[claudish] session summary unavailable: ${e}`);
125332
125397
  }
125333
125398
  }
125399
+ exitCode = signalShutdownExitCode() ?? exitCode;
125334
125400
  const sessionLogPath = getAlwaysOnLogPath();
125335
- const quitBySignal = exitCode === 130 || exitCode === 143;
125401
+ const quitBySignal = exitCode === 130 || exitCode === 143 || signalShutdownExitCode() !== null;
125336
125402
  if (exitCode !== 0 && !quitBySignal && sessionLogPath && !cliConfig.quiet) {
125337
125403
  console.error(`
125338
125404
  [claudish] Session ended with errors (exit code ${exitCode}).`);
@@ -125347,6 +125413,6 @@ Team Status`);
125347
125413
  } catch (error) {
125348
125414
  console.error("[claudish] Fatal error:", error);
125349
125415
  console.error("[claudish] Stack:", error instanceof Error ? error.stack : "no stack");
125350
- process.exit(1);
125416
+ process.exit(signalShutdownExitCode() ?? 1);
125351
125417
  }
125352
125418
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "14.18.2",
3
+ "version": "14.18.3",
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",
@@ -71,10 +71,10 @@
71
71
  "ai"
72
72
  ],
73
73
  "optionalDependencies": {
74
- "@claudish/magmux-darwin-arm64": "14.18.2",
75
- "@claudish/magmux-darwin-x64": "14.18.2",
76
- "@claudish/magmux-linux-arm64": "14.18.2",
77
- "@claudish/magmux-linux-x64": "14.18.2"
74
+ "@claudish/magmux-darwin-arm64": "14.18.3",
75
+ "@claudish/magmux-darwin-x64": "14.18.3",
76
+ "@claudish/magmux-linux-arm64": "14.18.3",
77
+ "@claudish/magmux-linux-x64": "14.18.3"
78
78
  },
79
79
  "author": "Jack Rudenko <i@madappgang.com>",
80
80
  "license": "MIT",