claudish 6.4.1 → 6.4.5

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 CHANGED
@@ -13996,10 +13996,10 @@ class ScrollbackBuffer {
13996
13996
  const cleaned = data.replace(ANSI_RE, "");
13997
13997
  const newLines = cleaned.split(`
13998
13998
  `);
13999
- for (const line of newLines) {
14000
- if (line === "" && newLines.indexOf(line) === newLines.length - 1)
13999
+ for (let i = 0;i < newLines.length; i++) {
14000
+ if (newLines[i] === "" && i === newLines.length - 1)
14001
14001
  continue;
14002
- this.lines[this.head] = line;
14002
+ this.lines[this.head] = newLines[i];
14003
14003
  this.head = (this.head + 1) % this.capacity;
14004
14004
  if (this.count < this.capacity)
14005
14005
  this.count++;
@@ -14039,6 +14039,7 @@ var init_scrollback_buffer = __esm(() => {
14039
14039
  class SignalWatcher {
14040
14040
  sessionId;
14041
14041
  callback;
14042
+ quietPeriodMs;
14042
14043
  _state = "starting";
14043
14044
  quietTimer = null;
14044
14045
  toolBatchTimer = null;
@@ -14046,9 +14047,10 @@ class SignalWatcher {
14046
14047
  toolBatchName = null;
14047
14048
  lastChunkHadQuestion = false;
14048
14049
  disposed = false;
14049
- constructor(sessionId, callback) {
14050
+ constructor(sessionId, callback, quietPeriodMs = QUIET_PERIOD_MS) {
14050
14051
  this.sessionId = sessionId;
14051
14052
  this.callback = callback;
14053
+ this.quietPeriodMs = quietPeriodMs;
14052
14054
  }
14053
14055
  get state() {
14054
14056
  return this._state;
@@ -14074,7 +14076,7 @@ class SignalWatcher {
14074
14076
  const lastLine = lines[lines.length - 1] || text.trim();
14075
14077
  this.transition("waiting_for_input", { content: lastLine });
14076
14078
  }
14077
- }, QUIET_PERIOD_MS);
14079
+ }, this.quietPeriodMs);
14078
14080
  }
14079
14081
  processExited(exitCode) {
14080
14082
  if (this.disposed)
@@ -17969,14 +17971,14 @@ var init_model_catalog = __esm(() => {
17969
17971
  supportsVision: false,
17970
17972
  temperatureRange: { min: 0.01, max: 1 }
17971
17973
  },
17972
- { pattern: "gpt-5.4", contextWindow: 1050000 },
17973
- { pattern: "gpt-5", contextWindow: 400000 },
17974
- { pattern: "o1", contextWindow: 200000 },
17975
- { pattern: "o3", contextWindow: 200000 },
17976
- { pattern: "o4", contextWindow: 200000 },
17977
- { pattern: "gpt-4o", contextWindow: 128000 },
17978
- { pattern: "gpt-4-turbo", contextWindow: 128000 },
17979
- { pattern: "gpt-3.5", contextWindow: 16385 },
17974
+ { pattern: "gpt-5.4", contextWindow: 1050000, maxToolCount: 128 },
17975
+ { pattern: "gpt-5", contextWindow: 400000, maxToolCount: 128 },
17976
+ { pattern: "o1", contextWindow: 200000, maxToolCount: 128 },
17977
+ { pattern: "o3", contextWindow: 200000, maxToolCount: 128 },
17978
+ { pattern: "o4", contextWindow: 200000, maxToolCount: 128 },
17979
+ { pattern: "gpt-4o", contextWindow: 128000, maxToolCount: 128 },
17980
+ { pattern: "gpt-4-turbo", contextWindow: 128000, maxToolCount: 128 },
17981
+ { pattern: "gpt-3.5", contextWindow: 16385, maxToolCount: 128 },
17980
17982
  { pattern: "kimi-k2.5", contextWindow: 262144 },
17981
17983
  { pattern: "kimi-k2-5", contextWindow: 262144 },
17982
17984
  { pattern: "kimi-k2", contextWindow: 131000 },
@@ -23934,7 +23936,12 @@ class ComposedHandler {
23934
23936
  if (typeof adapter.reset === "function")
23935
23937
  adapter.reset();
23936
23938
  const messages = adapter.convertMessages(claudeRequest, filterIdentity);
23937
- const tools = adapter.convertTools(claudeRequest, this.options.summarizeTools);
23939
+ let tools = adapter.convertTools(claudeRequest, this.options.summarizeTools);
23940
+ const maxToolCount = lookupModel(this.targetModel)?.maxToolCount;
23941
+ if (maxToolCount && tools.length > maxToolCount) {
23942
+ log(`[ComposedHandler] Truncating tools from ${tools.length} to ${maxToolCount} (model limit for ${this.targetModel})`);
23943
+ tools = tools.slice(0, maxToolCount);
23944
+ }
23938
23945
  if (!this.getModelSupportsVision()) {
23939
23946
  const imageBlocks = [];
23940
23947
  for (let msgIdx = 0;msgIdx < messages.length; msgIdx++) {
@@ -24406,6 +24413,7 @@ var init_composed_handler = __esm(() => {
24406
24413
  init_vision_proxy();
24407
24414
  init_telemetry();
24408
24415
  init_stats();
24416
+ init_model_catalog();
24409
24417
  });
24410
24418
 
24411
24419
  // src/providers/provider-registry.ts
@@ -28630,8 +28638,12 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
28630
28638
  }
28631
28639
  return { content: [{ type: "text", text: response }] };
28632
28640
  } catch (error2) {
28641
+ const errMsg = error2 instanceof Error ? error2.message : String(error2);
28633
28642
  return {
28634
- content: [{ type: "text", text: `Error: ${error2 instanceof Error ? error2.message : String(error2)}` }],
28643
+ content: [{ type: "text", text: `Error: ${errMsg}
28644
+
28645
+ ---
28646
+ **To report this error**, use the \`report_error\` tool with \`error_type: "provider_failure"\` and \`model: "${args.model}"\`.` }],
28635
28647
  isError: true
28636
28648
  };
28637
28649
  }
@@ -28779,6 +28791,10 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
28779
28791
 
28780
28792
  `;
28781
28793
  }
28794
+ const failed = results.filter((r) => r.error);
28795
+ if (failed.length > 0) {
28796
+ output += '---\n**To report failed model(s)**, use the `report_error` tool with `error_type: "provider_failure"` and the model ID(s) above.\n';
28797
+ }
28782
28798
  return { content: [{ type: "text", text: output }] };
28783
28799
  }
28784
28800
  });
@@ -28997,8 +29013,12 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
28997
29013
  content: [{ type: "text", text: JSON.stringify({ session_id: sessionId2, status: "starting" }) }]
28998
29014
  };
28999
29015
  } catch (error2) {
29016
+ const errMsg = error2 instanceof Error ? error2.message : String(error2);
29000
29017
  return {
29001
- content: [{ type: "text", text: `Error: ${error2 instanceof Error ? error2.message : String(error2)}` }],
29018
+ content: [{ type: "text", text: `Error creating session: ${errMsg}
29019
+
29020
+ ---
29021
+ **To report this error**, use the \`report_error\` tool with \`error_type: "provider_failure"\` and \`model: "${args.model}"\`.` }],
29002
29022
  isError: true
29003
29023
  };
29004
29024
  }
@@ -29111,10 +29131,13 @@ async function main() {
29111
29131
  });
29112
29132
  const sessionManager = new SessionManager({
29113
29133
  onStateChange: (sessionId2, event) => {
29134
+ const notificationContent = event.type === "failed" ? `${event.content}
29135
+
29136
+ To report this error, use the report_error tool with error_type: "provider_failure" and model: "${event.model}".` : event.content;
29114
29137
  server.notification({
29115
29138
  method: "notifications/claude/channel",
29116
29139
  params: {
29117
- content: event.content,
29140
+ content: notificationContent,
29118
29141
  meta: {
29119
29142
  session_id: sessionId2,
29120
29143
  event: event.type,
@@ -30954,7 +30977,7 @@ async function fetchGLMCodingModels() {
30954
30977
  return [];
30955
30978
  }
30956
30979
  }
30957
- var __filename4, __dirname4, VERSION = "6.4.1", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
30980
+ var __filename4, __dirname4, VERSION = "6.4.5", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
30958
30981
  var init_cli = __esm(() => {
30959
30982
  init_config();
30960
30983
  init_model_loader();
@@ -94178,13 +94201,234 @@ var init_tui = __esm(async () => {
94178
94201
  }
94179
94202
  });
94180
94203
 
94204
+ // src/team-grid.ts
94205
+ var exports_team_grid = {};
94206
+ __export(exports_team_grid, {
94207
+ runWithGrid: () => runWithGrid
94208
+ });
94209
+ import { spawn as spawn3 } from "child_process";
94210
+ import {
94211
+ appendFileSync,
94212
+ existsSync as existsSync24,
94213
+ mkdirSync as mkdirSync13,
94214
+ readFileSync as readFileSync19,
94215
+ writeFileSync as writeFileSync14
94216
+ } from "fs";
94217
+ import { dirname as dirname6, join as join25 } from "path";
94218
+ import { fileURLToPath as fileURLToPath6 } from "url";
94219
+ import { execSync as execSync3 } from "child_process";
94220
+ function formatElapsed(ms) {
94221
+ const s = Math.floor(ms / 1000);
94222
+ if (s < 60)
94223
+ return `${s}s`;
94224
+ const m2 = Math.floor(s / 60);
94225
+ const rem = s % 60;
94226
+ return `${m2}m ${rem}s`;
94227
+ }
94228
+ function findMtmBinary() {
94229
+ const thisFile = fileURLToPath6(import.meta.url);
94230
+ const thisDir = dirname6(thisFile);
94231
+ const platform3 = process.platform;
94232
+ const arch = process.arch;
94233
+ const pkgRoot = join25(thisDir, "..");
94234
+ const builtDev = join25(pkgRoot, "native", "mtm", "mtm");
94235
+ if (existsSync24(builtDev))
94236
+ return builtDev;
94237
+ const bundledPlatform = join25(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
94238
+ if (existsSync24(bundledPlatform))
94239
+ return bundledPlatform;
94240
+ try {
94241
+ const result = execSync3("which mtm", { encoding: "utf-8" }).trim();
94242
+ if (result && isMtmForkWithGrid(result))
94243
+ return result;
94244
+ } catch {}
94245
+ throw new Error("mtm binary not found. Build it with: cd packages/cli/native/mtm && make");
94246
+ }
94247
+ function isMtmForkWithGrid(binPath) {
94248
+ try {
94249
+ const output = execSync3(`"${binPath}" --help 2>&1 || true`, {
94250
+ encoding: "utf-8",
94251
+ timeout: 2000
94252
+ });
94253
+ return output.includes("-g ");
94254
+ } catch {
94255
+ return false;
94256
+ }
94257
+ }
94258
+ function renderGridStatusBar(counts) {
94259
+ const elapsed = formatElapsed(counts.elapsedMs);
94260
+ const { done, running, failed, total, allDone } = counts;
94261
+ if (allDone) {
94262
+ if (failed > 0) {
94263
+ return [
94264
+ "C: claudish team",
94265
+ `G: ${done} done`,
94266
+ `R: ${failed} failed`,
94267
+ `D: ${elapsed}`,
94268
+ "R: \u2717 issues"
94269
+ ].join("\t");
94270
+ }
94271
+ return [
94272
+ "C: claudish team",
94273
+ `G: ${total} done`,
94274
+ `D: ${elapsed}`,
94275
+ "G: \u2713 complete"
94276
+ ].join("\t");
94277
+ }
94278
+ return [
94279
+ "C: claudish team",
94280
+ `G: ${done} done`,
94281
+ `C: ${running} running`,
94282
+ `R: ${failed} failed`,
94283
+ `D: ${elapsed}`
94284
+ ].join("\t");
94285
+ }
94286
+ function pollStatus(state) {
94287
+ const { statusCache, statusPath, sessionPath, anonIds, startTime, timeoutMs, statusbarPath } = state;
94288
+ const elapsedMs = Date.now() - startTime;
94289
+ let changed = false;
94290
+ let done = 0;
94291
+ let running = 0;
94292
+ let failed = 0;
94293
+ for (const anonId of anonIds) {
94294
+ const current = statusCache.models[anonId];
94295
+ if (current.state === "COMPLETED" || current.state === "FAILED" || current.state === "TIMEOUT") {
94296
+ if (current.state === "COMPLETED")
94297
+ done++;
94298
+ else
94299
+ failed++;
94300
+ continue;
94301
+ }
94302
+ const exitCodePath = join25(sessionPath, "work", anonId, ".exit-code");
94303
+ const responsePath = join25(sessionPath, `response-${anonId}.md`);
94304
+ if (existsSync24(exitCodePath)) {
94305
+ const codeStr = readFileSync19(exitCodePath, "utf-8").trim();
94306
+ const code = parseInt(codeStr, 10);
94307
+ const isSuccess = code === 0;
94308
+ let outputSize = 0;
94309
+ try {
94310
+ outputSize = existsSync24(responsePath) ? readFileSync19(responsePath, "utf-8").length : 0;
94311
+ } catch {}
94312
+ const newState = {
94313
+ ...current,
94314
+ state: isSuccess ? "COMPLETED" : "FAILED",
94315
+ exitCode: code,
94316
+ startedAt: current.startedAt ?? new Date().toISOString(),
94317
+ completedAt: new Date().toISOString(),
94318
+ outputSize
94319
+ };
94320
+ statusCache.models[anonId] = newState;
94321
+ changed = true;
94322
+ if (isSuccess)
94323
+ done++;
94324
+ else
94325
+ failed++;
94326
+ } else {
94327
+ if (elapsedMs > timeoutMs) {
94328
+ const newState = {
94329
+ ...current,
94330
+ state: "TIMEOUT",
94331
+ startedAt: current.startedAt ?? new Date().toISOString(),
94332
+ completedAt: new Date().toISOString()
94333
+ };
94334
+ statusCache.models[anonId] = newState;
94335
+ changed = true;
94336
+ failed++;
94337
+ } else {
94338
+ if (current.state === "PENDING" && existsSync24(responsePath)) {
94339
+ statusCache.models[anonId] = {
94340
+ ...current,
94341
+ state: "RUNNING",
94342
+ startedAt: current.startedAt ?? new Date().toISOString()
94343
+ };
94344
+ changed = true;
94345
+ }
94346
+ running++;
94347
+ }
94348
+ }
94349
+ }
94350
+ if (changed) {
94351
+ writeFileSync14(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
94352
+ }
94353
+ const total = anonIds.length;
94354
+ const allDone = done + failed >= total;
94355
+ const counts = {
94356
+ done,
94357
+ running,
94358
+ failed,
94359
+ total,
94360
+ elapsedMs,
94361
+ allDone
94362
+ };
94363
+ appendFileSync(statusbarPath, renderGridStatusBar(counts) + `
94364
+ `);
94365
+ return allDone;
94366
+ }
94367
+ async function runWithGrid(sessionPath, models, input, opts) {
94368
+ const timeoutMs = (opts?.timeout ?? 300) * 1000;
94369
+ const manifest = setupSession(sessionPath, models, input);
94370
+ mkdirSync13(join25(sessionPath, "errors"), { recursive: true });
94371
+ const gridfilePath = join25(sessionPath, "gridfile.txt");
94372
+ const gridLines = Object.entries(manifest.models).map(([anonId]) => {
94373
+ const inputMd = join25(sessionPath, "input.md");
94374
+ const errorLog = join25(sessionPath, "errors", `${anonId}.log`);
94375
+ const responseMd = join25(sessionPath, `response-${anonId}.md`);
94376
+ const exitCodeFile = join25(sessionPath, "work", anonId, ".exit-code");
94377
+ return `claudish --model ${manifest.models[anonId].model} -y --stdin --quiet` + ` < ${inputMd} 2>${errorLog}` + ` | tee ${responseMd}` + `; echo $? > ${exitCodeFile}`;
94378
+ });
94379
+ writeFileSync14(gridfilePath, gridLines.join(`
94380
+ `) + `
94381
+ `, "utf-8");
94382
+ const mtmBin = findMtmBinary();
94383
+ const statusbarPath = join25(sessionPath, "statusbar.txt");
94384
+ const statusPath = join25(sessionPath, "status.json");
94385
+ const statusCache = JSON.parse(readFileSync19(statusPath, "utf-8"));
94386
+ const anonIds = Object.keys(manifest.models);
94387
+ const startTime = Date.now();
94388
+ appendFileSync(statusbarPath, renderGridStatusBar({
94389
+ done: 0,
94390
+ running: 0,
94391
+ failed: 0,
94392
+ total: anonIds.length,
94393
+ elapsedMs: 0,
94394
+ allDone: false
94395
+ }) + `
94396
+ `);
94397
+ const pollState = {
94398
+ statusCache,
94399
+ statusPath,
94400
+ sessionPath,
94401
+ anonIds,
94402
+ startTime,
94403
+ timeoutMs,
94404
+ statusbarPath
94405
+ };
94406
+ const pollInterval = setInterval(() => {
94407
+ pollStatus(pollState);
94408
+ }, 500);
94409
+ const proc = spawn3(mtmBin, ["-g", gridfilePath, "-S", statusbarPath, "-t", "xterm-256color"], {
94410
+ stdio: "inherit",
94411
+ env: { ...process.env }
94412
+ });
94413
+ await new Promise((resolve4) => {
94414
+ proc.on("exit", () => resolve4());
94415
+ proc.on("error", () => resolve4());
94416
+ });
94417
+ clearInterval(pollInterval);
94418
+ pollStatus(pollState);
94419
+ return JSON.parse(readFileSync19(statusPath, "utf-8"));
94420
+ }
94421
+ var init_team_grid = __esm(() => {
94422
+ init_team_orchestrator();
94423
+ });
94424
+
94181
94425
  // src/team-cli.ts
94182
94426
  var exports_team_cli = {};
94183
94427
  __export(exports_team_cli, {
94184
94428
  teamCommand: () => teamCommand
94185
94429
  });
94186
- import { readFileSync as readFileSync19 } from "fs";
94187
- import { join as join25 } from "path";
94430
+ import { readFileSync as readFileSync20 } from "fs";
94431
+ import { join as join26 } from "path";
94188
94432
  function getFlag(args, flag) {
94189
94433
  const idx = args.indexOf(flag);
94190
94434
  if (idx === -1 || idx + 1 >= args.length)
@@ -94222,6 +94466,7 @@ Options (run / run-and-judge):
94222
94466
  --models <a,b,...> Comma-separated model IDs to run
94223
94467
  --input <text> Task prompt (or create input.md in --path beforehand)
94224
94468
  --timeout <secs> Timeout per model in seconds (default: 300)
94469
+ --grid Show all models in an mtm grid with live output + status bar
94225
94470
 
94226
94471
  Options (judge / run-and-judge):
94227
94472
  --judges <a,b,...> Comma-separated judge model IDs (default: same as runners)
@@ -94231,6 +94476,7 @@ Options (status):
94231
94476
 
94232
94477
  Examples:
94233
94478
  claudish team run --path ./review --models minimax-m2.5,kimi-k2.5 --input "Review this code"
94479
+ claudish team run --grid --models kimi-k2.5,gpt-5.4,gemini-3.1-pro --input "Solve this"
94234
94480
  claudish team judge --path ./review
94235
94481
  claudish team run-and-judge --path ./review --models gpt-5.4,gemini-3.1-pro-preview --input "Evaluate this design"
94236
94482
  claudish team status --path ./review
@@ -94263,20 +94509,26 @@ async function teamCommand(args) {
94263
94509
  console.error("Error: --models is required for 'run'");
94264
94510
  process.exit(1);
94265
94511
  }
94266
- setupSession(sessionPath, models, input);
94267
- const runStatus = await runModels(sessionPath, {
94268
- timeout,
94269
- onStatusChange: (id, s) => {
94270
- process.stderr.write(`[team] ${id}: ${s.state}
94512
+ if (hasFlag(args, "--grid")) {
94513
+ const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
94514
+ const gridStatus = await runWithGrid2(sessionPath, models, input ?? "", { timeout });
94515
+ printStatus(gridStatus);
94516
+ } else {
94517
+ setupSession(sessionPath, models, input);
94518
+ const runStatus = await runModels(sessionPath, {
94519
+ timeout,
94520
+ onStatusChange: (id, s) => {
94521
+ process.stderr.write(`[team] ${id}: ${s.state}
94271
94522
  `);
94272
- }
94273
- });
94274
- printStatus(runStatus);
94523
+ }
94524
+ });
94525
+ printStatus(runStatus);
94526
+ }
94275
94527
  break;
94276
94528
  }
94277
94529
  case "judge": {
94278
94530
  const verdict = await judgeResponses(sessionPath, { judges });
94279
- console.log(readFileSync19(join25(sessionPath, "verdict.md"), "utf-8"));
94531
+ console.log(readFileSync20(join26(sessionPath, "verdict.md"), "utf-8"));
94280
94532
  break;
94281
94533
  }
94282
94534
  case "run-and-judge": {
@@ -94294,7 +94546,7 @@ async function teamCommand(args) {
94294
94546
  });
94295
94547
  printStatus(status);
94296
94548
  await judgeResponses(sessionPath, { judges });
94297
- console.log(readFileSync19(join25(sessionPath, "verdict.md"), "utf-8"));
94549
+ console.log(readFileSync20(join26(sessionPath, "verdict.md"), "utf-8"));
94298
94550
  break;
94299
94551
  }
94300
94552
  case "status": {
@@ -94319,10 +94571,10 @@ __export(exports_claude_runner, {
94319
94571
  runClaudeWithProxy: () => runClaudeWithProxy,
94320
94572
  checkClaudeInstalled: () => checkClaudeInstalled
94321
94573
  });
94322
- import { spawn as spawn3 } from "child_process";
94323
- import { writeFileSync as writeFileSync14, unlinkSync as unlinkSync7, mkdirSync as mkdirSync13, existsSync as existsSync24, readFileSync as readFileSync20 } from "fs";
94574
+ import { spawn as spawn4 } from "child_process";
94575
+ import { writeFileSync as writeFileSync15, unlinkSync as unlinkSync7, mkdirSync as mkdirSync14, existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
94324
94576
  import { tmpdir as tmpdir2, homedir as homedir23 } from "os";
94325
- import { join as join26 } from "path";
94577
+ import { join as join27 } from "path";
94326
94578
  function hasNativeAnthropicMapping(config3) {
94327
94579
  const models = [
94328
94580
  config3.model,
@@ -94338,9 +94590,9 @@ function isWindows2() {
94338
94590
  }
94339
94591
  function createStatusLineScript(tokenFilePath) {
94340
94592
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
94341
- const claudishDir = join26(homeDir, ".claudish");
94593
+ const claudishDir = join27(homeDir, ".claudish");
94342
94594
  const timestamp = Date.now();
94343
- const scriptPath = join26(claudishDir, `status-${timestamp}.js`);
94595
+ const scriptPath = join27(claudishDir, `status-${timestamp}.js`);
94344
94596
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
94345
94597
  const script = `
94346
94598
  const fs = require('fs');
@@ -94420,18 +94672,18 @@ process.stdin.on('end', () => {
94420
94672
  }
94421
94673
  });
94422
94674
  `;
94423
- writeFileSync14(scriptPath, script, "utf-8");
94675
+ writeFileSync15(scriptPath, script, "utf-8");
94424
94676
  return scriptPath;
94425
94677
  }
94426
94678
  function createTempSettingsFile(modelDisplay, port) {
94427
94679
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
94428
- const claudishDir = join26(homeDir, ".claudish");
94680
+ const claudishDir = join27(homeDir, ".claudish");
94429
94681
  try {
94430
- mkdirSync13(claudishDir, { recursive: true });
94682
+ mkdirSync14(claudishDir, { recursive: true });
94431
94683
  } catch {}
94432
94684
  const timestamp = Date.now();
94433
- const tempPath = join26(claudishDir, `settings-${timestamp}.json`);
94434
- const tokenFilePath = join26(claudishDir, `tokens-${port}.json`);
94685
+ const tempPath = join27(claudishDir, `settings-${timestamp}.json`);
94686
+ const tokenFilePath = join27(claudishDir, `tokens-${port}.json`);
94435
94687
  let statusCommand;
94436
94688
  if (isWindows2()) {
94437
94689
  const scriptPath = createStatusLineScript(tokenFilePath);
@@ -94453,7 +94705,7 @@ function createTempSettingsFile(modelDisplay, port) {
94453
94705
  padding: 0
94454
94706
  };
94455
94707
  const settings = { statusLine };
94456
- writeFileSync14(tempPath, JSON.stringify(settings, null, 2), "utf-8");
94708
+ writeFileSync15(tempPath, JSON.stringify(settings, null, 2), "utf-8");
94457
94709
  return { path: tempPath, statusLine };
94458
94710
  }
94459
94711
  function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
@@ -94467,11 +94719,11 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine) {
94467
94719
  if (userSettingsValue.trimStart().startsWith("{")) {
94468
94720
  userSettings = JSON.parse(userSettingsValue);
94469
94721
  } else {
94470
- const rawUserSettings = readFileSync20(userSettingsValue, "utf-8");
94722
+ const rawUserSettings = readFileSync21(userSettingsValue, "utf-8");
94471
94723
  userSettings = JSON.parse(rawUserSettings);
94472
94724
  }
94473
94725
  userSettings.statusLine = statusLine;
94474
- writeFileSync14(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
94726
+ writeFileSync15(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
94475
94727
  } catch {
94476
94728
  if (!config3.quiet) {
94477
94729
  console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
@@ -94560,7 +94812,7 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup, ptyDiagRunner) {
94560
94812
  console.error(`
94561
94813
  Or set CLAUDE_PATH to your custom installation:`);
94562
94814
  const home = homedir23();
94563
- const localPath = isWindows2() ? join26(home, ".claude", "local", "claude.exe") : join26(home, ".claude", "local", "claude");
94815
+ const localPath = isWindows2() ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
94564
94816
  console.error(` export CLAUDE_PATH=${localPath}`);
94565
94817
  process.exit(1);
94566
94818
  }
@@ -94573,7 +94825,7 @@ Or set CLAUDE_PATH to your custom installation:`);
94573
94825
  unlinkSync7(tempSettingsPath);
94574
94826
  } catch {}
94575
94827
  } else {
94576
- const proc = spawn3(spawnCommand, claudeArgs, {
94828
+ const proc = spawn4(spawnCommand, claudeArgs, {
94577
94829
  env: env2,
94578
94830
  stdio: "inherit",
94579
94831
  shell: needsShell
@@ -94614,23 +94866,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
94614
94866
  async function findClaudeBinary() {
94615
94867
  const isWindows3 = process.platform === "win32";
94616
94868
  if (process.env.CLAUDE_PATH) {
94617
- if (existsSync24(process.env.CLAUDE_PATH)) {
94869
+ if (existsSync26(process.env.CLAUDE_PATH)) {
94618
94870
  return process.env.CLAUDE_PATH;
94619
94871
  }
94620
94872
  }
94621
94873
  const home = homedir23();
94622
- const localPath = isWindows3 ? join26(home, ".claude", "local", "claude.exe") : join26(home, ".claude", "local", "claude");
94623
- if (existsSync24(localPath)) {
94874
+ const localPath = isWindows3 ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
94875
+ if (existsSync26(localPath)) {
94624
94876
  return localPath;
94625
94877
  }
94626
94878
  if (isWindows3) {
94627
94879
  const windowsPaths = [
94628
- join26(home, "AppData", "Roaming", "npm", "claude.cmd"),
94629
- join26(home, ".npm-global", "claude.cmd"),
94630
- join26(home, "node_modules", ".bin", "claude.cmd")
94880
+ join27(home, "AppData", "Roaming", "npm", "claude.cmd"),
94881
+ join27(home, ".npm-global", "claude.cmd"),
94882
+ join27(home, "node_modules", ".bin", "claude.cmd")
94631
94883
  ];
94632
94884
  for (const path2 of windowsPaths) {
94633
- if (existsSync24(path2)) {
94885
+ if (existsSync26(path2)) {
94634
94886
  return path2;
94635
94887
  }
94636
94888
  }
@@ -94638,21 +94890,21 @@ async function findClaudeBinary() {
94638
94890
  const commonPaths = [
94639
94891
  "/usr/local/bin/claude",
94640
94892
  "/opt/homebrew/bin/claude",
94641
- join26(home, ".npm-global/bin/claude"),
94642
- join26(home, ".local/bin/claude"),
94643
- join26(home, "node_modules/.bin/claude"),
94893
+ join27(home, ".npm-global/bin/claude"),
94894
+ join27(home, ".local/bin/claude"),
94895
+ join27(home, "node_modules/.bin/claude"),
94644
94896
  "/data/data/com.termux/files/usr/bin/claude",
94645
- join26(home, "../usr/bin/claude")
94897
+ join27(home, "../usr/bin/claude")
94646
94898
  ];
94647
94899
  for (const path2 of commonPaths) {
94648
- if (existsSync24(path2)) {
94900
+ if (existsSync26(path2)) {
94649
94901
  return path2;
94650
94902
  }
94651
94903
  }
94652
94904
  }
94653
94905
  try {
94654
94906
  const shellCommand = isWindows3 ? "where claude" : "command -v claude";
94655
- const proc = spawn3(shellCommand, [], {
94907
+ const proc = spawn4(shellCommand, [], {
94656
94908
  stdio: "pipe",
94657
94909
  shell: true
94658
94910
  });
@@ -94697,19 +94949,19 @@ __export(exports_diag_output, {
94697
94949
  MtmDiagOutput: () => MtmDiagOutput,
94698
94950
  LogFileDiagOutput: () => LogFileDiagOutput
94699
94951
  });
94700
- import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync14, writeFileSync as writeFileSync15, unlinkSync as unlinkSync8 } from "fs";
94952
+ import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync15, writeFileSync as writeFileSync16, unlinkSync as unlinkSync8 } from "fs";
94701
94953
  import { execFileSync } from "child_process";
94702
94954
  import { homedir as homedir24 } from "os";
94703
- import { join as join27 } from "path";
94955
+ import { join as join28 } from "path";
94704
94956
  function getClaudishDir() {
94705
- const dir = join27(homedir24(), ".claudish");
94957
+ const dir = join28(homedir24(), ".claudish");
94706
94958
  try {
94707
- mkdirSync14(dir, { recursive: true });
94959
+ mkdirSync15(dir, { recursive: true });
94708
94960
  } catch {}
94709
94961
  return dir;
94710
94962
  }
94711
94963
  function getDiagLogPath() {
94712
- return join27(getClaudishDir(), `diag-${process.pid}.log`);
94964
+ return join28(getClaudishDir(), `diag-${process.pid}.log`);
94713
94965
  }
94714
94966
 
94715
94967
  class LogFileDiagOutput {
@@ -94718,7 +94970,7 @@ class LogFileDiagOutput {
94718
94970
  constructor() {
94719
94971
  this.logPath = getDiagLogPath();
94720
94972
  try {
94721
- writeFileSync15(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
94973
+ writeFileSync16(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
94722
94974
  `);
94723
94975
  } catch {}
94724
94976
  this.stream = createWriteStream3(this.logPath, { flags: "a" });
@@ -94847,12 +95099,12 @@ __export(exports_pty_diag_runner, {
94847
95099
  PtyDiagRunner: () => MtmDiagRunner,
94848
95100
  MtmDiagRunner: () => MtmDiagRunner
94849
95101
  });
94850
- import { spawn as spawn4 } from "child_process";
94851
- import { appendFileSync, createWriteStream as createWriteStream4, existsSync as existsSync26, mkdirSync as mkdirSync15, unlinkSync as unlinkSync9 } from "fs";
95102
+ import { spawn as spawn5 } from "child_process";
95103
+ import { appendFileSync as appendFileSync2, createWriteStream as createWriteStream4, existsSync as existsSync27, mkdirSync as mkdirSync16, unlinkSync as unlinkSync9 } from "fs";
94852
95104
  import { homedir as homedir25 } from "os";
94853
- import { dirname as dirname6, join as join28 } from "path";
94854
- import { execSync as execSync3 } from "child_process";
94855
- import { fileURLToPath as fileURLToPath6 } from "url";
95105
+ import { dirname as dirname7, join as join29 } from "path";
95106
+ import { execSync as execSync4 } from "child_process";
95107
+ import { fileURLToPath as fileURLToPath7 } from "url";
94856
95108
 
94857
95109
  class MtmDiagRunner {
94858
95110
  mtmProc = null;
@@ -94860,12 +95112,12 @@ class MtmDiagRunner {
94860
95112
  statusPath;
94861
95113
  logStream = null;
94862
95114
  constructor() {
94863
- const dir = join28(homedir25(), ".claudish");
95115
+ const dir = join29(homedir25(), ".claudish");
94864
95116
  try {
94865
- mkdirSync15(dir, { recursive: true });
95117
+ mkdirSync16(dir, { recursive: true });
94866
95118
  } catch {}
94867
- this.logPath = join28(dir, `diag-${process.pid}.log`);
94868
- this.statusPath = join28(dir, `status-${process.pid}.txt`);
95119
+ this.logPath = join29(dir, `diag-${process.pid}.log`);
95120
+ this.statusPath = join29(dir, `status-${process.pid}.txt`);
94869
95121
  this.logStream = createWriteStream4(this.logPath, { flags: "w" });
94870
95122
  this.logStream.on("error", () => {});
94871
95123
  }
@@ -94874,7 +95126,7 @@ class MtmDiagRunner {
94874
95126
  const quotedArgs = claudeArgs.map((a) => shellQuote(a)).join(" ");
94875
95127
  const claudeCmd = `${shellQuote(claudeCommand)} ${quotedArgs}`;
94876
95128
  const mergedEnv = { ...process.env, ...env2 };
94877
- this.mtmProc = spawn4(mtmBin, ["-t", "xterm-256color", "-e", claudeCmd, "-S", this.statusPath, "-L", this.logPath], {
95129
+ this.mtmProc = spawn5(mtmBin, ["-t", "xterm-256color", "-e", claudeCmd, "-S", this.statusPath, "-L", this.logPath], {
94878
95130
  stdio: "inherit",
94879
95131
  env: mergedEnv
94880
95132
  });
@@ -94955,7 +95207,7 @@ class MtmDiagRunner {
94955
95207
  avgRoundtripMs: this.avgRoundtripMs
94956
95208
  });
94957
95209
  try {
94958
- appendFileSync(this.statusPath, bar + `
95210
+ appendFileSync2(this.statusPath, bar + `
94959
95211
  `);
94960
95212
  } catch {}
94961
95213
  }
@@ -94983,19 +95235,19 @@ class MtmDiagRunner {
94983
95235
  }
94984
95236
  }
94985
95237
  findMtmBinary() {
94986
- const thisFile = fileURLToPath6(import.meta.url);
94987
- const thisDir = dirname6(thisFile);
95238
+ const thisFile = fileURLToPath7(import.meta.url);
95239
+ const thisDir = dirname7(thisFile);
94988
95240
  const platform3 = process.platform;
94989
95241
  const arch = process.arch;
94990
- const pkgRoot = join28(thisDir, "..");
94991
- const bundledPlatform = join28(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
94992
- if (existsSync26(bundledPlatform))
95242
+ const pkgRoot = join29(thisDir, "..");
95243
+ const bundledPlatform = join29(pkgRoot, "native", "mtm", `mtm-${platform3}-${arch}`);
95244
+ if (existsSync27(bundledPlatform))
94993
95245
  return bundledPlatform;
94994
- const builtDev = join28(pkgRoot, "native", "mtm", "mtm");
94995
- if (existsSync26(builtDev))
95246
+ const builtDev = join29(pkgRoot, "native", "mtm", "mtm");
95247
+ if (existsSync27(builtDev))
94996
95248
  return builtDev;
94997
95249
  try {
94998
- const result = execSync3("which mtm", { encoding: "utf-8" }).trim();
95250
+ const result = execSync4("which mtm", { encoding: "utf-8" }).trim();
94999
95251
  if (result && this.isMtmFork(result))
95000
95252
  return result;
95001
95253
  } catch {}
@@ -95003,7 +95255,7 @@ class MtmDiagRunner {
95003
95255
  }
95004
95256
  isMtmFork(binPath) {
95005
95257
  try {
95006
- const output = execSync3(`"${binPath}" --help 2>&1 || true`, {
95258
+ const output = execSync4(`"${binPath}" --help 2>&1 || true`, {
95007
95259
  encoding: "utf-8",
95008
95260
  timeout: 2000
95009
95261
  });
@@ -95088,16 +95340,16 @@ var init_pty_diag_runner = __esm(() => {
95088
95340
 
95089
95341
  // src/index.ts
95090
95342
  var import_dotenv3 = __toESM(require_main(), 1);
95091
- import { existsSync as existsSync27, readFileSync as readFileSync21 } from "fs";
95343
+ import { existsSync as existsSync28, readFileSync as readFileSync22 } from "fs";
95092
95344
  import { homedir as homedir26 } from "os";
95093
- import { join as join29 } from "path";
95345
+ import { join as join30 } from "path";
95094
95346
  import_dotenv3.config({ quiet: true });
95095
95347
  function loadStoredApiKeys() {
95096
95348
  try {
95097
- const configPath = join29(homedir26(), ".claudish", "config.json");
95098
- if (!existsSync27(configPath))
95349
+ const configPath = join30(homedir26(), ".claudish", "config.json");
95350
+ if (!existsSync28(configPath))
95099
95351
  return;
95100
- const raw2 = readFileSync21(configPath, "utf-8");
95352
+ const raw2 = readFileSync22(configPath, "utf-8");
95101
95353
  const cfg = JSON.parse(raw2);
95102
95354
  if (cfg.apiKeys) {
95103
95355
  for (const [envVar, value] of Object.entries(cfg.apiKeys)) {
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "6.4.1",
3
+ "version": "6.4.5",
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",
@@ -12,9 +12,9 @@
12
12
  "category": "programming",
13
13
  "priority": 1,
14
14
  "pricing": {
15
- "input": "$0.20/1M",
16
- "output": "$1.17/1M",
17
- "average": "$0.69/1M"
15
+ "input": "$0.19/1M",
16
+ "output": "$1.15/1M",
17
+ "average": "$0.67/1M"
18
18
  },
19
19
  "context": "196K",
20
20
  "maxOutputTokens": 65536,
@@ -34,12 +34,12 @@
34
34
  "category": "vision",
35
35
  "priority": 2,
36
36
  "pricing": {
37
- "input": "$0.44/1M",
38
- "output": "$2.22/1M",
39
- "average": "$1.33/1M"
37
+ "input": "$0.42/1M",
38
+ "output": "$2.20/1M",
39
+ "average": "$1.31/1M"
40
40
  },
41
41
  "context": "262K",
42
- "maxOutputTokens": 262144,
42
+ "maxOutputTokens": 65535,
43
43
  "modality": "text+image->text",
44
44
  "supportsTools": true,
45
45
  "supportsReasoning": true,