claudish 7.26.0 → 7.28.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 +156 -26
  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.26.0";
654
+ var VERSION = "7.28.0";
655
655
 
656
656
  // src/logger.ts
657
657
  var exports_logger = {};
@@ -35364,7 +35364,21 @@ function createStreamingState() {
35364
35364
  accumulatedText: ""
35365
35365
  };
35366
35366
  }
35367
- function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap, priorInputTokens) {
35367
+ function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap, priorInputTokens, behavior) {
35368
+ const repairArgs = (toolName, argsJson) => {
35369
+ if (!behavior?.onToolCall)
35370
+ return argsJson;
35371
+ try {
35372
+ const repaired = behavior.onToolCall(toolName, argsJson);
35373
+ if (typeof repaired === "string" && repaired !== argsJson) {
35374
+ log(`[Streaming] tool call repaired by behavior layer: ${toolName}`);
35375
+ return repaired;
35376
+ }
35377
+ } catch (err) {
35378
+ log(`[Streaming] behavior onToolCall threw for ${toolName}: ${err}`);
35379
+ }
35380
+ return argsJson;
35381
+ };
35368
35382
  log(`[Streaming] ===== HANDLER STARTED for ${target} =====`);
35369
35383
  let isClosed = false;
35370
35384
  let ping = null;
@@ -35429,7 +35443,10 @@ data: ${JSON.stringify(d)}
35429
35443
  send("content_block_delta", {
35430
35444
  type: "content_block_delta",
35431
35445
  index: toolIdx,
35432
- delta: { type: "input_json_delta", partial_json: JSON.stringify(tc.arguments) }
35446
+ delta: {
35447
+ type: "input_json_delta",
35448
+ partial_json: repairArgs(tc.name, JSON.stringify(tc.arguments))
35449
+ }
35433
35450
  });
35434
35451
  send("content_block_stop", { type: "content_block_stop", index: toolIdx });
35435
35452
  }
@@ -35445,7 +35462,7 @@ data: ${JSON.stringify(d)}
35445
35462
  if (toolSchemas && toolSchemas.length > 0) {
35446
35463
  const validation = validateToolArguments(t.name, t.arguments, toolSchemas, state.accumulatedText);
35447
35464
  if (validation.valid || validation.repaired && validation.repairedArgs) {
35448
- const argsJson = JSON.stringify(validation.repaired ? validation.repairedArgs : validation.parsedArgs);
35465
+ const argsJson = repairArgs(t.name, JSON.stringify(validation.repaired ? validation.repairedArgs : validation.parsedArgs));
35449
35466
  log(`[Streaming] Sending buffered tool call (finish_reason!=tool_calls): ${t.name} with args: ${argsJson}`);
35450
35467
  send("content_block_start", {
35451
35468
  type: "content_block_start",
@@ -35468,7 +35485,7 @@ data: ${JSON.stringify(d)}
35468
35485
  t.closed = true;
35469
35486
  }
35470
35487
  } else {
35471
- const argsJson = t.arguments || "{}";
35488
+ const argsJson = repairArgs(t.name, t.arguments || "{}");
35472
35489
  log(`[Streaming] Sending buffered tool call (no validation): ${t.name} with args: ${argsJson}`);
35473
35490
  send("content_block_start", {
35474
35491
  type: "content_block_start",
@@ -35665,7 +35682,7 @@ data: ${JSON.stringify(d)}
35665
35682
  started: false,
35666
35683
  closed: false,
35667
35684
  arguments: "",
35668
- buffered: !!toolSchemas && toolSchemas.length > 0
35685
+ buffered: !!toolSchemas && toolSchemas.length > 0 || behavior?.shouldBufferTool?.(restoredName) === true
35669
35686
  };
35670
35687
  state.tools.set(idx, t);
35671
35688
  if (isWebSearchToolCall(restoredName)) {
@@ -35704,7 +35721,7 @@ data: ${JSON.stringify(d)}
35704
35721
  const validation = validateToolArguments(t.name, t.arguments, toolSchemas, state.accumulatedText);
35705
35722
  if (validation.repaired && validation.repairedArgs) {
35706
35723
  log(`[Streaming] Tool call ${t.name} was repaired with inferred parameters`);
35707
- const repairedJson = JSON.stringify(validation.repairedArgs);
35724
+ const repairedJson = repairArgs(t.name, JSON.stringify(validation.repairedArgs));
35708
35725
  log(`[Streaming] Sending repaired tool call: ${t.name} with args: ${repairedJson}`);
35709
35726
  if (t.buffered && !t.started) {
35710
35727
  send("content_block_start", {
@@ -35780,7 +35797,7 @@ data: ${JSON.stringify(d)}
35780
35797
  continue;
35781
35798
  }
35782
35799
  if (t.buffered && !t.started) {
35783
- const argsJson = JSON.stringify(validation.parsedArgs);
35800
+ const argsJson = repairArgs(t.name, JSON.stringify(validation.parsedArgs));
35784
35801
  send("content_block_start", {
35785
35802
  type: "content_block_start",
35786
35803
  index: t.blockIndex,
@@ -39448,6 +39465,70 @@ var init_stream_head_sniffer = __esm(() => {
39448
39465
  });
39449
39466
 
39450
39467
  // src/handlers/shared/stream-parsers/anthropic-sse.ts
39468
+ function createToolRepairInterceptor(opts) {
39469
+ const heldTools = new Map;
39470
+ const flush = (index, stopFrame) => {
39471
+ const held = heldTools.get(index);
39472
+ if (!held)
39473
+ return stopFrame;
39474
+ heldTools.delete(index);
39475
+ let finalArgs = held.args;
39476
+ try {
39477
+ const repaired = opts.repairToolArgs?.(held.name, finalArgs);
39478
+ if (typeof repaired === "string" && repaired !== finalArgs) {
39479
+ log(`[AnthropicSSE] tool call repaired: ${held.name}`);
39480
+ finalArgs = repaired;
39481
+ }
39482
+ } catch (err) {
39483
+ log(`[AnthropicSSE] repairToolArgs threw for ${held.name}: ${err}`);
39484
+ }
39485
+ const deltaFrame = `event: content_block_delta
39486
+ data: ${JSON.stringify({
39487
+ type: "content_block_delta",
39488
+ index,
39489
+ delta: { type: "input_json_delta", partial_json: finalArgs }
39490
+ })}
39491
+
39492
+ `;
39493
+ return `${deltaFrame}${stopFrame}`;
39494
+ };
39495
+ const noteToolStart = (data) => {
39496
+ if (data.content_block?.type !== "tool_use")
39497
+ return;
39498
+ const name = data.content_block.name;
39499
+ if (typeof name !== "string")
39500
+ return;
39501
+ if (!opts.shouldBufferTool?.(name))
39502
+ return;
39503
+ heldTools.set(data.index, { name, args: "" });
39504
+ };
39505
+ const absorbFragment = (data) => {
39506
+ if (data.delta?.type !== "input_json_delta")
39507
+ return false;
39508
+ const held = heldTools.get(data.index);
39509
+ if (!held)
39510
+ return false;
39511
+ held.args += data.delta.partial_json ?? "";
39512
+ return true;
39513
+ };
39514
+ return (data, line) => {
39515
+ const asIs = `${line}
39516
+ `;
39517
+ if (!opts.repairToolArgs || !opts.shouldBufferTool)
39518
+ return asIs;
39519
+ switch (data?.type) {
39520
+ case "content_block_start":
39521
+ noteToolStart(data);
39522
+ return asIs;
39523
+ case "content_block_delta":
39524
+ return absorbFragment(data) ? null : asIs;
39525
+ case "content_block_stop":
39526
+ return heldTools.has(data.index) ? flush(data.index, asIs) : asIs;
39527
+ default:
39528
+ return asIs;
39529
+ }
39530
+ };
39531
+ }
39451
39532
  function createAnthropicPassthroughStream(c, response, opts) {
39452
39533
  const encoder = new TextEncoder;
39453
39534
  const decoder = new TextDecoder;
@@ -39455,6 +39536,14 @@ function createAnthropicPassthroughStream(c, response, opts) {
39455
39536
  let lastActivity = Date.now();
39456
39537
  let pingInterval = null;
39457
39538
  const filterThinking = opts.adapter?.shouldFilterThinking() ?? false;
39539
+ const interceptToolFrame = createToolRepairInterceptor(opts);
39540
+ const enqueueData = (controller, data, line) => {
39541
+ if (isClosed)
39542
+ return;
39543
+ const out = interceptToolFrame(data, line);
39544
+ if (out !== null)
39545
+ controller.enqueue(encoder.encode(out));
39546
+ };
39458
39547
  return c.body(new ReadableStream({
39459
39548
  async start(controller) {
39460
39549
  const sendPing = () => {
@@ -39537,10 +39626,7 @@ data: ${JSON.stringify({
39537
39626
  `));
39538
39627
  }
39539
39628
  } else {
39540
- if (!isClosed) {
39541
- controller.enqueue(encoder.encode(`${line}
39542
- `));
39543
- }
39629
+ enqueueData(controller, data, line);
39544
39630
  }
39545
39631
  } catch {
39546
39632
  if (!isClosed) {
@@ -39572,10 +39658,7 @@ data: ${JSON.stringify({
39572
39658
  }
39573
39659
  return;
39574
39660
  }
39575
- if (!isClosed) {
39576
- controller.enqueue(encoder.encode(`${line}
39577
- `));
39578
- }
39661
+ enqueueData(controller, data, line);
39579
39662
  if (data.message?.usage) {
39580
39663
  inputTokens = data.message.usage.input_tokens || inputTokens;
39581
39664
  outputTokens = data.message.usage.output_tokens || outputTokens;
@@ -39870,7 +39953,18 @@ data: ${JSON.stringify(data)}
39870
39953
  const toolIdx = toolCalls.size;
39871
39954
  const toolId = `toolu_${Date.now()}_${toolIdx}`;
39872
39955
  const blockIndex = curIdx++;
39873
- const args = JSON.stringify(part.functionCall.args || {});
39956
+ let args = JSON.stringify(part.functionCall.args || {});
39957
+ if (opts.repairToolArgs) {
39958
+ try {
39959
+ const repaired = opts.repairToolArgs(part.functionCall.name, args);
39960
+ if (typeof repaired === "string" && repaired !== args) {
39961
+ log(`[GeminiSSE] tool call repaired: ${part.functionCall.name}`);
39962
+ args = repaired;
39963
+ }
39964
+ } catch (err) {
39965
+ log(`[GeminiSSE] repairToolArgs threw for ${part.functionCall.name}: ${err}`);
39966
+ }
39967
+ }
39874
39968
  const t = {
39875
39969
  id: toolId,
39876
39970
  name: part.functionCall.name,
@@ -40593,7 +40687,7 @@ class TokenTracker {
40593
40687
  try {
40594
40688
  const total = inputTokens + outputTokens;
40595
40689
  const cw = this.config.contextWindow;
40596
- const leftPct = cw > 0 ? Math.max(0, Math.min(100, Math.round((cw - total) / cw * 100))) : -1;
40690
+ const leftPct = cw > 0 ? Math.max(0, Math.min(100, Math.round((cw - inputTokens) / cw * 100))) : -1;
40597
40691
  const pricing = this.getPricing();
40598
40692
  const isFreeModel = pricing.isFree || pricing.inputCostPer1M === 0 && pricing.outputCostPer1M === 0;
40599
40693
  const data = {
@@ -41203,7 +41297,10 @@ class ComposedHandler {
41203
41297
  const priorInputTokens = this.tokenTracker.getLastInputTokens();
41204
41298
  switch (streamFormat) {
41205
41299
  case "openai-sse":
41206
- return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens);
41300
+ return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens, behaviorSession && {
41301
+ shouldBufferTool: (name) => behaviorSession.interceptsTool(name),
41302
+ onToolCall: (name, argsJson) => behaviorSession.repairToolCall(name, argsJson)
41303
+ });
41207
41304
  case "openai-responses-sse":
41208
41305
  return createResponsesStreamHandler(c, response, {
41209
41306
  modelName: this.bareModelName,
@@ -41220,7 +41317,9 @@ class ComposedHandler {
41220
41317
  return createAnthropicPassthroughStream(c, response, {
41221
41318
  modelName: this.bareModelName,
41222
41319
  onTokenUpdate,
41223
- adapter
41320
+ adapter,
41321
+ shouldBufferTool: (name) => behaviorSession?.interceptsTool(name) ?? false,
41322
+ repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null
41224
41323
  });
41225
41324
  case "gemini-sse": {
41226
41325
  const onToolCall = (toolId, name, thoughtSignature) => {
@@ -41234,6 +41333,7 @@ class ComposedHandler {
41234
41333
  middlewareManager: this.middlewareManager,
41235
41334
  onTokenUpdate,
41236
41335
  onToolCall,
41336
+ repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null,
41237
41337
  unwrapResponse: this.options.unwrapGeminiResponse,
41238
41338
  priorInputTokens
41239
41339
  });
@@ -72912,10 +73012,13 @@ __export(exports_claude_runner, {
72912
73012
  resolveContextWindowEnv: () => resolveContextWindowEnv,
72913
73013
  managedSettingsForcesClaudeAi: () => managedSettingsForcesClaudeAi,
72914
73014
  isProxyAuthMode: () => isProxyAuthMode,
73015
+ createTempSettingsFile: () => createTempSettingsFile,
73016
+ createStatusLineScript: () => createStatusLineScript,
72915
73017
  computeMainThreadContextWindow: () => computeMainThreadContextWindow,
72916
73018
  checkClaudeInstalled: () => checkClaudeInstalled,
72917
73019
  buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay,
72918
- MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW
73020
+ MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW,
73021
+ CLAUDE_CODE_DEFAULT_MAX_CONTEXT: () => CLAUDE_CODE_DEFAULT_MAX_CONTEXT
72919
73022
  });
72920
73023
  import { spawn as spawn4 } from "child_process";
72921
73024
  import {
@@ -73008,6 +73111,25 @@ function formatTokens(n) {
73008
73111
  return String(n);
73009
73112
  }
73010
73113
 
73114
+ // The window Claude Code will actually enforce, which is not always the model's spec
73115
+ // window: it compacts at min(CLAUDE_CODE_AUTO_COMPACT_WINDOW, maxContextTokens), and
73116
+ // maxContextTokens falls back to a fixed default for model names it does not know \u2014
73117
+ // every model claudish proxies. This script runs inside Claude Code's environment, so
73118
+ // it reads the governing values first-hand.
73119
+ function effectiveWindow(specWindow) {
73120
+ if (!(specWindow > 0)) return 0;
73121
+ const num = (v, dflt) => {
73122
+ const n = parseInt(v, 10);
73123
+ return Number.isFinite(n) && n > 0 ? n : dflt;
73124
+ };
73125
+ let w = specWindow;
73126
+ const maxCtx = num(process.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS, ${CLAUDE_CODE_DEFAULT_MAX_CONTEXT});
73127
+ if (maxCtx > 0 && maxCtx < w) w = maxCtx;
73128
+ const autoCompact = num(process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW, 0);
73129
+ if (autoCompact > 0 && autoCompact < w) w = autoCompact;
73130
+ return w;
73131
+ }
73132
+
73011
73133
  let input = '';
73012
73134
  process.stdin.setEncoding('utf8');
73013
73135
  process.stdin.on('data', chunk => input += chunk);
@@ -73051,17 +73173,24 @@ process.stdin.on('end', () => {
73051
73173
  }
73052
73174
  const modelDisplay = providerName ? providerName + ' ' + model : model;
73053
73175
  // Format context display as progress bar: [\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591] 116k/1M
73176
+ const effWindow = effectiveWindow(contextWindow);
73177
+ if (effWindow > 0 && inputTokens > 0) {
73178
+ ctx = Math.max(0, Math.min(100, Math.round(((effWindow - inputTokens) / effWindow) * 100)));
73179
+ }
73054
73180
  let ctxDisplay = '';
73055
- if (ctx < 0 || contextWindow <= 0) {
73181
+ if (ctx < 0 || effWindow <= 0) {
73056
73182
  // Unknown context window \u2014 show token count only
73057
73183
  ctxDisplay = inputTokens > 0 ? formatTokens(inputTokens) + ' tokens' : 'N/A';
73058
- } else if (inputTokens > 0 && contextWindow > 0) {
73184
+ } else if (inputTokens > 0) {
73059
73185
  const usedPct = 100 - ctx; // ctx is "left", so used = 100 - left
73060
73186
  const barWidth = 15;
73061
73187
  const filled = Math.round((usedPct / 100) * barWidth);
73062
73188
  const empty = barWidth - filled;
73063
73189
  const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(empty);
73064
- ctxDisplay = '[' + bar + '] ' + formatTokens(inputTokens) + '/' + formatTokens(contextWindow);
73190
+ // When Claude Code enforces less than the model advertises, show both \u2014 the
73191
+ // gap is the whole reason this line exists.
73192
+ const clamped = effWindow < contextWindow ? ' of ' + formatTokens(contextWindow) : '';
73193
+ ctxDisplay = '[' + bar + '] ' + formatTokens(inputTokens) + '/' + formatTokens(effWindow) + clamped;
73065
73194
  } else {
73066
73195
  ctxDisplay = ctx + '%';
73067
73196
  }
@@ -73103,7 +73232,8 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
73103
73232
  const RESET4 = "\\033[0m";
73104
73233
  const BOLD4 = "\\033[1m";
73105
73234
  const formatTokensBash = `fmt_tok() { local n=\${1:-0}; if [ "$n" -ge 1000000 ]; then echo "$((n/1000000))M"; elif [ "$n" -ge 1000 ]; then echo "$((n/1000))k"; else echo "$n"; fi; }`;
73106
- statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX=-1 && COST="0" && IS_FREE="false" && IS_EST="false" && PROVIDER="" && TOKEN_MODEL="" && IN_TOK=0 && CTX_WIN=0 && ${formatTokensBash} && if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d ' \\n') && REAL_CTX=$(echo "$TOKENS" | grep -o '"context_left_percent":-\\?[0-9]*' | grep -o '\\-\\?[0-9]*') && if [ ! -z "$REAL_CTX" ]; then CTX="$REAL_CTX"; fi && REAL_COST=$(echo "$TOKENS" | grep -o '"total_cost":[0-9.]*' | cut -d: -f2) && if [ ! -z "$REAL_COST" ]; then COST="$REAL_COST"; fi && IN_TOK=$(echo "$TOKENS" | grep -o '"input_tokens":[0-9]*' | grep -o '[0-9]*') && CTX_WIN=$(echo "$TOKENS" | grep -o '"context_window":[0-9]*' | grep -o '[0-9]*') && IS_FREE=$(echo "$TOKENS" | grep -o '"is_free":[a-z]*' | cut -d: -f2) && IS_EST=$(echo "$TOKENS" | grep -o '"is_estimated":[a-z]*' | cut -d: -f2) && PROVIDER=$(echo "$TOKENS" | grep -o '"provider_name":"[^"]*"' | cut -d'"' -f4) && TOKEN_MODEL=$(echo "$TOKENS" | grep -o '"model_name":"[^"]*"' | cut -d'"' -f4); fi && if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi && MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}" && if [ ! -z "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi && if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$CTX_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null && [ "$CTX_WIN" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX%"; fi && printf "${CYAN4}${BOLD4}%s${RESET4} ${DIM4}\u2022${RESET4} ${YELLOW3}%s${RESET4} ${DIM4}\u2022${RESET4} ${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"`;
73235
+ const effWinBash = `eff_win() { local w=\${1:-0}; local m=\${CLAUDE_CODE_MAX_CONTEXT_TOKENS:-}; local a=\${CLAUDE_CODE_AUTO_COMPACT_WINDOW:-}; case "$m" in ''|*[!0-9]*) m=${CLAUDE_CODE_DEFAULT_MAX_CONTEXT};; esac; case "$a" in ''|*[!0-9]*) a=0;; esac; case "$w" in ''|*[!0-9]*) w=0;; esac; if [ "$w" -gt 0 ]; then if [ "$m" -gt 0 ] && [ "$m" -lt "$w" ]; then w=$m; fi; if [ "$a" -gt 0 ] && [ "$a" -lt "$w" ]; then w=$a; fi; fi; echo "$w"; }`;
73236
+ statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX=-1 && COST="0" && IS_FREE="false" && IS_EST="false" && PROVIDER="" && TOKEN_MODEL="" && IN_TOK=0 && CTX_WIN=0 && ${formatTokensBash} && ${effWinBash} && if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d ' \\n') && REAL_CTX=$(echo "$TOKENS" | grep -o '"context_left_percent":-\\?[0-9]*' | grep -o '\\-\\?[0-9]*') && if [ ! -z "$REAL_CTX" ]; then CTX="$REAL_CTX"; fi && REAL_COST=$(echo "$TOKENS" | grep -o '"total_cost":[0-9.]*' | cut -d: -f2) && if [ ! -z "$REAL_COST" ]; then COST="$REAL_COST"; fi && IN_TOK=$(echo "$TOKENS" | grep -o '"input_tokens":[0-9]*' | grep -o '[0-9]*') && CTX_WIN=$(echo "$TOKENS" | grep -o '"context_window":[0-9]*' | grep -o '[0-9]*') && IS_FREE=$(echo "$TOKENS" | grep -o '"is_free":[a-z]*' | cut -d: -f2) && IS_EST=$(echo "$TOKENS" | grep -o '"is_estimated":[a-z]*' | cut -d: -f2) && PROVIDER=$(echo "$TOKENS" | grep -o '"provider_name":"[^"]*"' | cut -d'"' -f4) && TOKEN_MODEL=$(echo "$TOKENS" | grep -o '"model_name":"[^"]*"' | cut -d'"' -f4); fi && if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi && MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}" && if [ ! -z "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi && EFF_WIN=$(eff_win $CTX_WIN) && if [ "$EFF_WIN" -gt 0 ] 2>/dev/null && [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX=$(( ((EFF_WIN - IN_TOK) * 200 / EFF_WIN + 1) / 2 )); if [ "$CTX" -lt 0 ]; then CTX=0; fi; fi && if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$EFF_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null; then if [ "$EFF_WIN" -lt "$CTX_WIN" ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN) of $(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN))"; fi; else CTX_DISPLAY="$CTX%"; fi && printf "${CYAN4}${BOLD4}%s${RESET4} ${DIM4}\u2022${RESET4} ${YELLOW3}%s${RESET4} ${DIM4}\u2022${RESET4} ${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"`;
73107
73237
  }
73108
73238
  const statusLine = {
73109
73239
  type: "command",
@@ -73452,7 +73582,7 @@ async function checkClaudeInstalled() {
73452
73582
  const binary = await findClaudeBinary();
73453
73583
  return binary !== null;
73454
73584
  }
73455
- var restoreTerminal = null, MIN_AUTO_COMPACT_WINDOW = 200000;
73585
+ var restoreTerminal = null, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, MIN_AUTO_COMPACT_WINDOW = 200000;
73456
73586
  var init_claude_runner = __esm(() => {
73457
73587
  init_model_catalog();
73458
73588
  init_config2();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.26.0",
3
+ "version": "7.28.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.26.0",
64
- "@claudish/magmux-darwin-x64": "7.26.0",
65
- "@claudish/magmux-linux-arm64": "7.26.0",
66
- "@claudish/magmux-linux-x64": "7.26.0"
63
+ "@claudish/magmux-darwin-arm64": "7.28.0",
64
+ "@claudish/magmux-darwin-x64": "7.28.0",
65
+ "@claudish/magmux-linux-arm64": "7.28.0",
66
+ "@claudish/magmux-linux-x64": "7.28.0"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",