claudish 7.12.4 → 7.12.6

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 +176 -61
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -581,7 +581,7 @@ var init_onepassword_config = __esm(() => {
581
581
  });
582
582
 
583
583
  // src/version.ts
584
- var VERSION = "7.12.4";
584
+ var VERSION = "7.12.6";
585
585
 
586
586
  // src/logger.ts
587
587
  var exports_logger = {};
@@ -30918,11 +30918,18 @@ ${msg}`;
30918
30918
  }
30919
30919
  return messages;
30920
30920
  }
30921
+ function imageBlockToUrlPart(block) {
30922
+ return {
30923
+ type: "image_url",
30924
+ image_url: { url: `data:${block.source.media_type};base64,${block.source.data}` }
30925
+ };
30926
+ }
30921
30927
  function processUserMessage(msg, messages, simpleFormat = false) {
30922
30928
  if (Array.isArray(msg.content)) {
30923
30929
  const textParts = [];
30924
30930
  const contentParts = [];
30925
30931
  const toolResults = [];
30932
+ const toolResultImages = [];
30926
30933
  const seen = new Set;
30927
30934
  for (const block of msg.content) {
30928
30935
  if (block.type === "text") {
@@ -30932,22 +30939,45 @@ function processUserMessage(msg, messages, simpleFormat = false) {
30932
30939
  }
30933
30940
  } else if (block.type === "image") {
30934
30941
  if (!simpleFormat) {
30935
- contentParts.push({
30936
- type: "image_url",
30937
- image_url: { url: `data:${block.source.media_type};base64,${block.source.data}` }
30938
- });
30942
+ contentParts.push(imageBlockToUrlPart(block));
30939
30943
  }
30940
30944
  } else if (block.type === "tool_result") {
30941
30945
  if (seen.has(block.tool_use_id))
30942
30946
  continue;
30943
30947
  seen.add(block.tool_use_id);
30944
- const resultContent = typeof block.content === "string" ? block.content : JSON.stringify(block.content);
30948
+ let resultText;
30949
+ if (typeof block.content === "string") {
30950
+ resultText = block.content;
30951
+ } else if (Array.isArray(block.content)) {
30952
+ const texts = [];
30953
+ const others = [];
30954
+ for (const inner of block.content) {
30955
+ if (inner.type === "text") {
30956
+ texts.push(inner.text);
30957
+ } else if (inner.type === "image" && inner.source) {
30958
+ if (!simpleFormat)
30959
+ toolResultImages.push(imageBlockToUrlPart(inner));
30960
+ } else {
30961
+ others.push(inner);
30962
+ }
30963
+ }
30964
+ resultText = texts.join(`
30965
+ `);
30966
+ if (others.length)
30967
+ resultText += (resultText ? `
30968
+ ` : "") + JSON.stringify(others);
30969
+ if (!resultText) {
30970
+ resultText = toolResultImages.length ? "[image returned; see following message]" : "";
30971
+ }
30972
+ } else {
30973
+ resultText = JSON.stringify(block.content);
30974
+ }
30945
30975
  if (simpleFormat) {
30946
- textParts.push(`[Tool Result]: ${resultContent}`);
30976
+ textParts.push(`[Tool Result]: ${resultText}`);
30947
30977
  } else {
30948
30978
  toolResults.push({
30949
30979
  role: "tool",
30950
- content: resultContent,
30980
+ content: resultText,
30951
30981
  tool_call_id: block.tool_use_id
30952
30982
  });
30953
30983
  }
@@ -30962,6 +30992,8 @@ function processUserMessage(msg, messages, simpleFormat = false) {
30962
30992
  } else {
30963
30993
  if (toolResults.length)
30964
30994
  messages.push(...toolResults);
30995
+ if (toolResultImages.length)
30996
+ messages.push({ role: "user", content: toolResultImages });
30965
30997
  if (contentParts.length)
30966
30998
  messages.push({ role: "user", content: contentParts });
30967
30999
  }
@@ -38113,15 +38145,18 @@ function createResponsesStreamHandler(c, response, opts) {
38113
38145
  const encoder = new TextEncoder;
38114
38146
  const decoder = new TextDecoder;
38115
38147
  let buffer = "";
38116
- let blockIndex = 0;
38148
+ let curIdx = 0;
38149
+ let textIdx = -1;
38150
+ let reasoningIdx = -1;
38151
+ let lastSummaryIndex = -1;
38117
38152
  let inputTokens = 0;
38118
38153
  let outputTokens = 0;
38119
- let hasTextContent = false;
38120
38154
  let hasToolUse = false;
38121
38155
  let lastActivity = Date.now();
38122
38156
  let pingInterval = null;
38123
38157
  let isClosed = false;
38124
38158
  const functionCalls = new Map;
38159
+ const openToolBlocks = new Set;
38125
38160
  const stream = new ReadableStream({
38126
38161
  start: async (controller) => {
38127
38162
  const send = (event, data) => {
@@ -38132,6 +38167,24 @@ data: ${JSON.stringify(data)}
38132
38167
  `));
38133
38168
  }
38134
38169
  };
38170
+ const closeReasoning = () => {
38171
+ if (reasoningIdx >= 0) {
38172
+ send("content_block_stop", { type: "content_block_stop", index: reasoningIdx });
38173
+ reasoningIdx = -1;
38174
+ }
38175
+ };
38176
+ const closeText = () => {
38177
+ if (textIdx >= 0) {
38178
+ send("content_block_stop", { type: "content_block_stop", index: textIdx });
38179
+ textIdx = -1;
38180
+ }
38181
+ };
38182
+ const closeTools = () => {
38183
+ for (const fnCall of openToolBlocks) {
38184
+ send("content_block_stop", { type: "content_block_stop", index: fnCall.index });
38185
+ }
38186
+ openToolBlocks.clear();
38187
+ };
38135
38188
  send("message_start", {
38136
38189
  type: "message_start",
38137
38190
  message: {
@@ -38169,23 +38222,27 @@ data: ${JSON.stringify(data)}
38169
38222
  const data = line.slice(6);
38170
38223
  if (data === "[DONE]")
38171
38224
  continue;
38225
+ if (getLogLevel() === "debug") {
38226
+ log(`[SSE:responses] ${data.substring(0, 300)}`);
38227
+ }
38172
38228
  try {
38173
38229
  const event = JSON.parse(data);
38174
38230
  if (getLogLevel() === "debug" && event.type) {
38175
38231
  log(`[ResponsesSSE] Event: ${event.type}`);
38176
38232
  }
38177
38233
  if (event.type === "response.output_text.delta") {
38178
- if (!hasTextContent) {
38234
+ closeReasoning();
38235
+ if (textIdx < 0) {
38236
+ textIdx = curIdx++;
38179
38237
  send("content_block_start", {
38180
38238
  type: "content_block_start",
38181
- index: blockIndex,
38239
+ index: textIdx,
38182
38240
  content_block: { type: "text", text: "" }
38183
38241
  });
38184
- hasTextContent = true;
38185
38242
  }
38186
38243
  send("content_block_delta", {
38187
38244
  type: "content_block_delta",
38188
- index: blockIndex,
38245
+ index: textIdx,
38189
38246
  delta: { type: "text_delta", text: event.delta || "" }
38190
38247
  });
38191
38248
  } else if (event.type === "response.output_item.added") {
@@ -38195,41 +38252,51 @@ data: ${JSON.stringify(data)}
38195
38252
  const callId = openaiCallId.startsWith("toolu_") ? openaiCallId : `toolu_${openaiCallId.replace(/^fc_/, "")}`;
38196
38253
  const rawFnName = event.item.name || "";
38197
38254
  const fnName = opts.toolNameMap?.get(rawFnName) || rawFnName;
38198
- const fnIndex = blockIndex + functionCalls.size + (hasTextContent ? 1 : 0);
38255
+ closeReasoning();
38256
+ closeText();
38199
38257
  const fnCallData = {
38200
38258
  name: fnName,
38201
38259
  arguments: "",
38202
- index: fnIndex,
38260
+ index: curIdx++,
38203
38261
  claudeId: callId
38204
38262
  };
38205
38263
  functionCalls.set(openaiCallId, fnCallData);
38206
38264
  if (itemId && itemId !== openaiCallId) {
38207
38265
  functionCalls.set(itemId, fnCallData);
38208
38266
  }
38209
- if (hasTextContent && !hasToolUse) {
38210
- send("content_block_stop", { type: "content_block_stop", index: blockIndex });
38211
- blockIndex++;
38212
- }
38267
+ openToolBlocks.add(fnCallData);
38213
38268
  send("content_block_start", {
38214
38269
  type: "content_block_start",
38215
- index: fnIndex,
38270
+ index: fnCallData.index,
38216
38271
  content_block: { type: "tool_use", id: callId, name: fnName, input: {} }
38217
38272
  });
38218
38273
  hasToolUse = true;
38219
38274
  }
38220
38275
  } else if (event.type === "response.reasoning_summary_text.delta") {
38221
- if (!hasTextContent) {
38276
+ const summaryIndex = typeof event.summary_index === "number" ? event.summary_index : 0;
38277
+ if (reasoningIdx < 0) {
38278
+ closeText();
38279
+ reasoningIdx = curIdx++;
38280
+ lastSummaryIndex = summaryIndex;
38222
38281
  send("content_block_start", {
38223
38282
  type: "content_block_start",
38224
- index: blockIndex,
38225
- content_block: { type: "text", text: "" }
38283
+ index: reasoningIdx,
38284
+ content_block: { type: "thinking", thinking: "" }
38285
+ });
38286
+ } else if (summaryIndex !== lastSummaryIndex) {
38287
+ lastSummaryIndex = summaryIndex;
38288
+ send("content_block_delta", {
38289
+ type: "content_block_delta",
38290
+ index: reasoningIdx,
38291
+ delta: { type: "thinking_delta", thinking: `
38292
+
38293
+ ` }
38226
38294
  });
38227
- hasTextContent = true;
38228
38295
  }
38229
38296
  send("content_block_delta", {
38230
38297
  type: "content_block_delta",
38231
- index: blockIndex,
38232
- delta: { type: "text_delta", text: event.delta || "" }
38298
+ index: reasoningIdx,
38299
+ delta: { type: "thinking_delta", thinking: event.delta || "" }
38233
38300
  });
38234
38301
  } else if (event.type === "response.function_call_arguments.delta") {
38235
38302
  const callId = event.call_id || event.item_id;
@@ -38246,8 +38313,9 @@ data: ${JSON.stringify(data)}
38246
38313
  if (event.item?.type === "function_call") {
38247
38314
  const callId = event.item.call_id || event.item.id;
38248
38315
  const fnCall = functionCalls.get(callId) || functionCalls.get(event.item.id);
38249
- if (fnCall) {
38316
+ if (fnCall && openToolBlocks.has(fnCall)) {
38250
38317
  send("content_block_stop", { type: "content_block_stop", index: fnCall.index });
38318
+ openToolBlocks.delete(fnCall);
38251
38319
  }
38252
38320
  }
38253
38321
  } else if (event.type === "response.incomplete") {
@@ -38269,14 +38337,10 @@ data: ${JSON.stringify(data)}
38269
38337
  const errMsg = err.message || event.message || "Unknown API error";
38270
38338
  const errCode = err.code || event.code || "";
38271
38339
  log(`[ResponsesSSE] API error: ${errCode} - ${errMsg}`);
38272
- if (hasTextContent) {
38273
- send("content_block_stop", { type: "content_block_stop", index: blockIndex });
38274
- hasTextContent = false;
38275
- }
38276
- for (const [, fnCall] of functionCalls) {
38277
- send("content_block_stop", { type: "content_block_stop", index: fnCall.index });
38278
- }
38279
- const errorIdx = blockIndex + functionCalls.size + (hasToolUse ? 1 : 0);
38340
+ closeReasoning();
38341
+ closeText();
38342
+ closeTools();
38343
+ const errorIdx = curIdx++;
38280
38344
  send("content_block_start", {
38281
38345
  type: "content_block_start",
38282
38346
  index: errorIdx,
@@ -38315,9 +38379,9 @@ data: ${JSON.stringify(data)}
38315
38379
  clearInterval(pingInterval);
38316
38380
  pingInterval = null;
38317
38381
  }
38318
- if (hasTextContent) {
38319
- send("content_block_stop", { type: "content_block_stop", index: blockIndex });
38320
- }
38382
+ closeReasoning();
38383
+ closeText();
38384
+ closeTools();
38321
38385
  const stopReason = hasToolUse ? "tool_use" : "end_turn";
38322
38386
  send("message_delta", {
38323
38387
  type: "message_delta",
@@ -38337,13 +38401,10 @@ data: ${JSON.stringify(data)}
38337
38401
  log(`[ResponsesSSE] Stream error: ${error46}`);
38338
38402
  if (!isClosed) {
38339
38403
  try {
38340
- if (hasTextContent) {
38341
- send("content_block_stop", { type: "content_block_stop", index: blockIndex });
38342
- }
38343
- for (const [, fnCall] of functionCalls) {
38344
- send("content_block_stop", { type: "content_block_stop", index: fnCall.index });
38345
- }
38346
- const errorIdx = blockIndex + functionCalls.size + (hasToolUse ? 1 : 0);
38404
+ closeReasoning();
38405
+ closeText();
38406
+ closeTools();
38407
+ const errorIdx = curIdx++;
38347
38408
  send("content_block_start", {
38348
38409
  type: "content_block_start",
38349
38410
  index: errorIdx,
@@ -63799,6 +63860,7 @@ var init_cli = __esm(() => {
63799
63860
  // src/update-checker.ts
63800
63861
  var exports_update_checker = {};
63801
63862
  __export(exports_update_checker, {
63863
+ fetchLatestVersionOrThrow: () => fetchLatestVersionOrThrow,
63802
63864
  fetchLatestVersion: () => fetchLatestVersion,
63803
63865
  compareVersions: () => compareVersions,
63804
63866
  clearCache: () => clearCache,
@@ -63871,20 +63933,39 @@ function compareVersions(v1, v2) {
63871
63933
  }
63872
63934
  return 0;
63873
63935
  }
63874
- async function fetchLatestVersion() {
63875
- try {
63936
+ async function fetchLatestVersionOrThrow(options = {}) {
63937
+ const { timeoutMs = 5000, retries = 0 } = options;
63938
+ let lastError = new Error("unknown error");
63939
+ for (let attempt = 0;attempt <= retries; attempt++) {
63876
63940
  const controller = new AbortController;
63877
- const timeout = setTimeout(() => controller.abort(), 5000);
63878
- const response = await fetch(NPM_REGISTRY_URL, {
63879
- signal: controller.signal,
63880
- headers: { Accept: "application/json" }
63881
- });
63882
- clearTimeout(timeout);
63883
- if (!response.ok) {
63884
- return null;
63941
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
63942
+ try {
63943
+ const response = await fetch(NPM_REGISTRY_URL, {
63944
+ signal: controller.signal,
63945
+ headers: { Accept: "application/json" }
63946
+ });
63947
+ if (!response.ok) {
63948
+ throw new Error(`npm registry returned HTTP ${response.status}`);
63949
+ }
63950
+ const data = await response.json();
63951
+ if (!data.version) {
63952
+ throw new Error("npm registry response contained no version field");
63953
+ }
63954
+ return data.version;
63955
+ } catch (error46) {
63956
+ lastError = error46 instanceof Error && error46.name === "AbortError" ? new Error(`request timed out after ${timeoutMs}ms`) : error46 instanceof Error ? error46 : new Error(String(error46));
63957
+ if (attempt < retries) {
63958
+ await new Promise((resolve3) => setTimeout(resolve3, 300 * (attempt + 1)));
63959
+ }
63960
+ } finally {
63961
+ clearTimeout(timeout);
63885
63962
  }
63886
- const data = await response.json();
63887
- return data.version || null;
63963
+ }
63964
+ throw lastError;
63965
+ }
63966
+ async function fetchLatestVersion(options = {}) {
63967
+ try {
63968
+ return await fetchLatestVersionOrThrow(options);
63888
63969
  } catch {
63889
63970
  return null;
63890
63971
  }
@@ -64085,16 +64166,50 @@ ${BOLD2}Unable to detect installation method.${RESET2}`);
64085
64166
  console.log(` ${CYAN2}brew:${RESET2} brew upgrade claudish
64086
64167
  `);
64087
64168
  }
64169
+ function fetchLatestVersionViaNpm() {
64170
+ try {
64171
+ const output = execSync("npm view claudish version", {
64172
+ encoding: "utf-8",
64173
+ timeout: 20000,
64174
+ stdio: ["ignore", "pipe", "ignore"]
64175
+ });
64176
+ const version2 = output.trim();
64177
+ return /^\d+\.\d+\.\d+/.test(version2) ? version2 : null;
64178
+ } catch {
64179
+ return null;
64180
+ }
64181
+ }
64182
+ async function resolveLatestVersion() {
64183
+ let fetchError;
64184
+ try {
64185
+ return { version: await fetchLatestVersionOrThrow({ timeoutMs: 15000, retries: 2 }) };
64186
+ } catch (error46) {
64187
+ fetchError = error46 instanceof Error ? error46.message : String(error46);
64188
+ }
64189
+ const viaNpm = fetchLatestVersionViaNpm();
64190
+ if (viaNpm)
64191
+ return { version: viaNpm };
64192
+ return { error: fetchError };
64193
+ }
64088
64194
  async function updateCommand() {
64089
64195
  const currentVersion = getVersion3();
64090
64196
  const installInfo = detectInstallationMethod();
64091
- const latestVersion = await fetchLatestVersion();
64092
- if (!latestVersion) {
64197
+ const result = await resolveLatestVersion();
64198
+ if ("error" in result) {
64093
64199
  console.error(`${RED2}\u2717${RESET2} Unable to fetch latest version from npm registry.`);
64094
- console.error(`${YELLOW}Please check your internet connection and try again.${RESET2}
64200
+ console.error(`${DIM2}Reason: ${result.error}${RESET2}`);
64201
+ console.error(`${YELLOW}The npm registry may be slow or unreachable from this network.${RESET2}`);
64202
+ const manualCommand = getUpdateCommand(installInfo.method);
64203
+ if (manualCommand) {
64204
+ console.error(`${YELLOW}You can update manually:${RESET2}`);
64205
+ console.error(` ${CYAN2}${manualCommand}${RESET2}
64095
64206
  `);
64207
+ } else {
64208
+ printManualInstructions();
64209
+ }
64096
64210
  process.exit(1);
64097
64211
  }
64212
+ const latestVersion = result.version;
64098
64213
  const comparison = compareVersions(latestVersion, currentVersion);
64099
64214
  if (comparison <= 0) {
64100
64215
  console.log(`${GREEN2}\u2713${RESET2} ${BOLD2}Already up-to-date!${RESET2}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.12.4",
3
+ "version": "7.12.6",
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.12.4",
64
- "@claudish/magmux-darwin-x64": "7.12.4",
65
- "@claudish/magmux-linux-arm64": "7.12.4",
66
- "@claudish/magmux-linux-x64": "7.12.4"
63
+ "@claudish/magmux-darwin-arm64": "7.12.6",
64
+ "@claudish/magmux-darwin-x64": "7.12.6",
65
+ "@claudish/magmux-linux-arm64": "7.12.6",
66
+ "@claudish/magmux-linux-x64": "7.12.6"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",