claudish 9.0.7 → 9.0.8

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 +143 -32
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -715,7 +715,7 @@ var init_onepassword_config = __esm(() => {
715
715
  });
716
716
 
717
717
  // src/version.ts
718
- var VERSION = "9.0.7";
718
+ var VERSION = "9.0.8";
719
719
 
720
720
  // src/logger.ts
721
721
  import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
@@ -19334,6 +19334,60 @@ var init_transform = __esm(() => {
19334
19334
  });
19335
19335
 
19336
19336
  // src/handlers/shared/format/openai-tools.ts
19337
+ function isPortablePattern(pattern) {
19338
+ for (let i = 0;i < pattern.length; i++) {
19339
+ const char = pattern[i];
19340
+ if (char === "\\") {
19341
+ const escaped = pattern[i + 1];
19342
+ i++;
19343
+ if (escaped && /[A-Za-z]/.test(escaped) && !PORTABLE_ESCAPE_LETTERS.has(escaped)) {
19344
+ return false;
19345
+ }
19346
+ continue;
19347
+ }
19348
+ if (char === "(" && pattern[i + 1] === "?" && pattern[i + 2] === "<") {
19349
+ const after = pattern[i + 3];
19350
+ if (after !== "=" && after !== "!")
19351
+ return false;
19352
+ }
19353
+ }
19354
+ return true;
19355
+ }
19356
+ function isNamedSchemaMap(key, value) {
19357
+ return NAMED_SCHEMA_MAPS.has(key) && !!value && typeof value === "object" && !Array.isArray(value);
19358
+ }
19359
+ function stripInNamedSchemaMap(map, path) {
19360
+ const result = {};
19361
+ for (const name in map) {
19362
+ result[name] = stripUnportablePatterns(map[name], `${path}.${name}`);
19363
+ }
19364
+ return result;
19365
+ }
19366
+ function stripUnportablePatterns(schema, path = "parameters") {
19367
+ if (Array.isArray(schema)) {
19368
+ return schema.map((item, index) => stripUnportablePatterns(item, `${path}[${index}]`));
19369
+ }
19370
+ if (!schema || typeof schema !== "object")
19371
+ return schema;
19372
+ const result = {};
19373
+ for (const key in schema) {
19374
+ const value = schema[key];
19375
+ if (key === "pattern" && typeof value === "string") {
19376
+ if (isPortablePattern(value)) {
19377
+ result[key] = value;
19378
+ } else {
19379
+ log(`[OpenAITools] Dropped unportable pattern at ${path}: ${value}`);
19380
+ }
19381
+ continue;
19382
+ }
19383
+ if (isNamedSchemaMap(key, value)) {
19384
+ result[key] = stripInNamedSchemaMap(value, path);
19385
+ continue;
19386
+ }
19387
+ result[key] = stripUnportablePatterns(value, `${path}.${key}`);
19388
+ }
19389
+ return result;
19390
+ }
19337
19391
  function emptyParamsSchema() {
19338
19392
  return { type: "object", properties: {} };
19339
19393
  }
@@ -19358,7 +19412,7 @@ function sanitizeSchemaForOpenAI(schema) {
19358
19412
  root.type = "object";
19359
19413
  if (!root.properties)
19360
19414
  root.properties = {};
19361
- return removeUriFormat(root);
19415
+ return stripUnportablePatterns(removeUriFormat(root));
19362
19416
  }
19363
19417
  function convertToolsToOpenAI(req, summarize = false) {
19364
19418
  return req.tools?.map((tool) => ({
@@ -19398,8 +19452,33 @@ function summarizeToolParameters(schema) {
19398
19452
  }
19399
19453
  return summarized;
19400
19454
  }
19455
+ var PORTABLE_ESCAPE_LETTERS, NAMED_SCHEMA_MAPS;
19401
19456
  var init_openai_tools = __esm(() => {
19457
+ init_logger();
19402
19458
  init_transform();
19459
+ PORTABLE_ESCAPE_LETTERS = new Set([
19460
+ "A",
19461
+ "b",
19462
+ "B",
19463
+ "d",
19464
+ "D",
19465
+ "s",
19466
+ "S",
19467
+ "w",
19468
+ "W",
19469
+ "Z",
19470
+ "a",
19471
+ "f",
19472
+ "n",
19473
+ "r",
19474
+ "t",
19475
+ "v",
19476
+ "x",
19477
+ "u",
19478
+ "U",
19479
+ "N"
19480
+ ]);
19481
+ NAMED_SCHEMA_MAPS = new Set(["properties", "$defs", "definitions"]);
19403
19482
  });
19404
19483
 
19405
19484
  // src/adapters/base-api-format.ts
@@ -35872,7 +35951,7 @@ var init_provider_profiles = __esm(() => {
35872
35951
  };
35873
35952
  openaiProfile = {
35874
35953
  createHandler(ctx) {
35875
- if (requiresResponsesApi(ctx.modelName)) {
35954
+ if (requiresResponsesApi(ctx.modelName, ctx.catalogCachePath)) {
35876
35955
  const responsesProvider = { ...ctx.provider, apiPath: "/v1/responses" };
35877
35956
  const transport = new OpenAIProviderTransport(responsesProvider, ctx.modelName, ctx.apiKey);
35878
35957
  const adapter = new CodexAPIFormat(ctx.modelName);
@@ -39733,6 +39812,7 @@ function sessionsIn(dirName) {
39733
39812
  id: basename(n, ".jsonl"),
39734
39813
  file,
39735
39814
  mtimeMs: st.mtimeMs,
39815
+ birthtimeMs: st.birthtimeMs,
39736
39816
  sizeBytes: st.size
39737
39817
  };
39738
39818
  const head = readChunk(file, 0, Math.min(ENTRYPOINT_BYTES, st.size));
@@ -40076,10 +40156,12 @@ function sessionLabel(row) {
40076
40156
  return row.title || row.firstPrompt || row.id;
40077
40157
  }
40078
40158
  function findLatestSessionId(cwd = process.cwd(), sinceMs = 0) {
40079
- const rows = sessionsIn(slugForPath(cwd)).filter((r) => r.mtimeMs >= sinceMs);
40080
- if (rows.length === 0)
40159
+ const touched = sessionsIn(slugForPath(cwd)).filter((r) => r.mtimeMs >= sinceMs);
40160
+ if (touched.length === 0)
40081
40161
  return null;
40082
- return rows.reduce((a, b) => b.mtimeMs > a.mtimeMs ? b : a).id;
40162
+ const born = touched.filter((r) => r.birthtimeMs !== undefined && r.birthtimeMs >= sinceMs);
40163
+ const pool = born.length > 0 ? born : touched;
40164
+ return pool.reduce((a, b) => b.mtimeMs > a.mtimeMs ? b : a).id;
40083
40165
  }
40084
40166
  var ENTRYPOINT_BYTES = 8192, PROJECTS_DIR, ACTIVE_WINDOW_MS = 120000, HEAD_BYTES, TAIL_BYTES, HARNESS_ENVELOPES, DEEP_TAIL_BYTES, RECENT_AI_TURNS = 5, RECENT_USER_TURNS = 1;
40085
40167
  var init_session_discovery = __esm(() => {
@@ -44619,7 +44701,7 @@ If you cannot use structured tool_calls, format as JSON:
44619
44701
  // src/adapters/openrouter-api-format.ts
44620
44702
  var OpenRouterAPIFormat;
44621
44703
  var init_openrouter_api_format = __esm(() => {
44622
- init_transform();
44704
+ init_openai_tools();
44623
44705
  init_base_api_format();
44624
44706
  init_dialect_manager();
44625
44707
  OpenRouterAPIFormat = class OpenRouterAPIFormat extends BaseAPIFormat {
@@ -44673,14 +44755,7 @@ ${text}`;
44673
44755
  }
44674
44756
  }
44675
44757
  convertTools(claudeRequest, _summarize = false) {
44676
- return claudeRequest.tools?.map((tool) => ({
44677
- type: "function",
44678
- function: {
44679
- name: tool.name,
44680
- description: tool.description,
44681
- parameters: removeUriFormat(tool.input_schema)
44682
- }
44683
- })) || [];
44758
+ return convertToolsToOpenAI(claudeRequest, false);
44684
44759
  }
44685
44760
  buildPayload(claudeRequest, messages, tools) {
44686
44761
  const payload = {
@@ -53590,8 +53665,12 @@ function retintSurfaces(palette, pageHex) {
53590
53665
  ]);
53591
53666
  }
53592
53667
  }
53668
+ function isLightTheme() {
53669
+ return appliedMode === "light";
53670
+ }
53593
53671
  function applyTuiTheme(mode) {
53594
53672
  const palette = mode === "light" ? LIGHT2 : DARK;
53673
+ appliedMode = mode;
53595
53674
  activeLatencyBuckets = mode === "light" ? LATENCY_BUCKETS_LIGHT : LATENCY_BUCKETS_DARK;
53596
53675
  Object.assign(C, palette);
53597
53676
  const terminalBg = getTerminalBackground();
@@ -53675,7 +53754,7 @@ function tokBarCells(tokensPerSec, maxTokPerSec, tokWidth) {
53675
53754
  const raw = Math.round(tokWidth * Math.max(0, tokensPerSec) / denom);
53676
53755
  return Math.min(tokWidth, Math.max(0, raw));
53677
53756
  }
53678
- var DARK, LIGHT2, C, bold3, A, LATENCY_BUCKETS_DARK, LATENCY_BUCKETS_LIGHT, activeLatencyBuckets, latencyFg = "#ffffff", LATENCY_FG_ANSI = "\x1B[38;2;255;255;255m", ANSI_RESET = "\x1B[0m", STAGE_BG_DARK, STAGE_BG_LIGHT, STAGE_BG, STAGE_FG, STAGE_BG_ANSI, paletteRefreshers, SURFACE_TOKENS;
53757
+ var DARK, LIGHT2, C, bold3, A, LATENCY_BUCKETS_DARK, LATENCY_BUCKETS_LIGHT, activeLatencyBuckets, latencyFg = "#ffffff", LATENCY_FG_ANSI = "\x1B[38;2;255;255;255m", ANSI_RESET = "\x1B[0m", STAGE_BG_DARK, STAGE_BG_LIGHT, STAGE_BG, STAGE_FG, STAGE_BG_ANSI, paletteRefreshers, SURFACE_TOKENS, appliedMode = null;
53679
53758
  var init_theme2 = __esm(() => {
53680
53759
  init_theme_mode();
53681
53760
  DARK = {
@@ -66594,6 +66673,11 @@ function blendStops(steps, ...stops) {
66594
66673
  return mix(pts[s], pts[s + 1], p - s);
66595
66674
  });
66596
66675
  }
66676
+ function lighten(c, amount) {
66677
+ const k = clamp01(amount);
66678
+ const v = rgba(c);
66679
+ return hex(RGBA.fromValues(v.r + (1 - v.r) * k, v.g + (1 - v.g) * k, v.b + (1 - v.b) * k, v.a));
66680
+ }
66597
66681
  function luminance(c) {
66598
66682
  const f = (v) => v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
66599
66683
  return 0.2126 * f(clamp01(c.r)) + 0.7152 * f(clamp01(c.g)) + 0.0722 * f(clamp01(c.b));
@@ -68698,12 +68782,22 @@ function toolColors() {
68698
68782
  function toolOther() {
68699
68783
  return C.dim;
68700
68784
  }
68785
+ function area(hex) {
68786
+ return isLightTheme() ? lighten(hex, 0.55) : hex;
68787
+ }
68788
+ function areaRamp(ramp) {
68789
+ const [first, ...rest] = ramp;
68790
+ return [area(first), ...rest.map(area)];
68791
+ }
68701
68792
  function cardWidth() {
68702
68793
  const cols = process.stdout.columns || 80;
68703
68794
  return Math.max(MIN_W, Math.min(MAX_W, cols - 2));
68704
68795
  }
68796
+ function shellArg(path) {
68797
+ return /^[A-Za-z0-9_@%+=:,./-]+$/.test(path) ? path : `'${path.replace(/'/g, `'\\''`)}'`;
68798
+ }
68705
68799
  function renderSessionSummary(input) {
68706
- const { stats, modelSpec, resumeModelSpec, resumeId, exitCode } = input;
68800
+ const { stats, modelSpec, resumeModelSpec, resumeId, resumeCwd, exitCode } = input;
68707
68801
  const W = cardWidth();
68708
68802
  const inner = W - CHROME;
68709
68803
  const out = [];
@@ -68732,22 +68826,24 @@ function renderSessionSummary(input) {
68732
68826
  row(dim(truncate3(stats.providerName, inner)));
68733
68827
  blank();
68734
68828
  const VALUE_W = 24;
68735
- const barW = Math.max(12, inner - LABEL_W - VALUE_W);
68829
+ const BAR_MAX = 30;
68830
+ const barW = Math.max(12, Math.min(BAR_MAX, inner - LABEL_W - VALUE_W));
68831
+ const barGap = Math.max(0, inner - LABEL_W - barW - VALUE_W);
68736
68832
  const dataRow = (label, bar, values) => {
68737
- row(dim(padTo(label, LABEL_W)) + bar + padVisible2(values, VALUE_W, "right"));
68833
+ row(dim(padTo(label, LABEL_W)) + bar + " ".repeat(barGap) + padVisible2(values, VALUE_W, "right"));
68738
68834
  };
68739
68835
  if (stats.contextUsed !== null && stats.contextWindow) {
68740
68836
  const pct = stats.contextUsed * 100;
68741
- dataRow("context", meter(pct, barW, ramps.load), body(padStartTo(`${Math.round(pct)}%`, 4)) + dim(` ${compact(stats.inputTokens)}/${compact(stats.contextWindow)}`));
68837
+ dataRow("context", meter(pct, barW, areaRamp(ramps.load)), body(padStartTo(`${Math.round(pct)}%`, 4)) + dim(` ${compact(stats.inputTokens)}/${compact(stats.contextWindow)}`));
68742
68838
  }
68743
68839
  dataRow("tokens", stackedBar([
68744
- { value: stats.inputTokens, color: C.blue },
68745
- { value: stats.outputTokens, color: C.cyan }
68840
+ { value: stats.inputTokens, color: area(C.blue) },
68841
+ { value: stats.outputTokens, color: area(C.cyan) }
68746
68842
  ], barW), dim("in ") + body(compact(stats.inputTokens)) + dim(" out ") + body(compact(stats.outputTokens)));
68747
68843
  if (!stats.isFree && stats.inputCostUsd + stats.outputCostUsd > 0) {
68748
68844
  dataRow("spend", stackedBar([
68749
- { value: stats.inputCostUsd, color: C.blue },
68750
- { value: stats.outputCostUsd, color: C.cyan }
68845
+ { value: stats.inputCostUsd, color: area(C.blue) },
68846
+ { value: stats.outputCostUsd, color: area(C.cyan) }
68751
68847
  ], barW), dim("in ") + body(usd(stats.inputCostUsd)) + dim(" out ") + body(usd(stats.outputCostUsd)));
68752
68848
  }
68753
68849
  if (stats.toolCallTotal > 0) {
@@ -68755,9 +68851,12 @@ function renderSessionSummary(input) {
68755
68851
  const other = toolOther();
68756
68852
  const shown = stats.toolCalls.slice(0, toolCols.length);
68757
68853
  const rest = stats.toolCalls.slice(toolCols.length).reduce((a, t) => a + t.count, 0);
68758
- const segs = shown.map((t, i) => ({ value: t.count, color: toolCols[i] }));
68854
+ const segs = shown.map((t, i) => ({
68855
+ value: t.count,
68856
+ color: area(toolCols[i])
68857
+ }));
68759
68858
  if (rest > 0)
68760
- segs.push({ value: rest, color: other });
68859
+ segs.push({ value: rest, color: area(other) });
68761
68860
  dataRow("tools", stackedBar(segs, barW), body(padStartTo(String(stats.toolCallTotal), 4)) + dim(" calls"));
68762
68861
  const legend = shown.map((t, i) => paint(`${t.name} ${t.count}`, toolCols[i])).concat(rest > 0 ? [paint(`other ${rest}`, other)] : []);
68763
68862
  for (const line of wrapStyled(legend, dim(" \xB7 "), inner - LABEL_W)) {
@@ -68765,14 +68864,16 @@ function renderSessionSummary(input) {
68765
68864
  }
68766
68865
  }
68767
68866
  blank();
68768
- row(dim(padTo("cost", LABEL_W)) + paint(stats.isFree ? "free" : usd(stats.costUsd), stats.isFree ? tokens.success : tokens.text, true) + (stats.isEstimated && !stats.isFree ? dim(" estimated") : ""));
68867
+ row(dim(padTo("cost", LABEL_W)) + paint(stats.isFree ? "free" : usd(stats.costUsd), tokens.text, true) + (stats.isEstimated && !stats.isFree ? dim(" estimated") : ""));
68868
+ const dearest = Math.max(0, ...stats.savings.map((s) => s.baselineUsd));
68769
68869
  for (const s of stats.savings) {
68770
68870
  const label = padTo(`vs ${s.label}`, LABEL_W);
68771
68871
  if (s.savedUsd >= 0) {
68772
68872
  const pct = s.baselineUsd > 0 ? s.savedUsd / s.baselineUsd * 100 : 0;
68773
- dataRow(label, meter(pct, barW, ramps.savings), paint(padStartTo(`${Math.round(pct)}%`, 4), tokens.success) + dim(" saved ") + paint(usd(s.savedUsd), tokens.success));
68873
+ const share = dearest > 0 ? s.savedUsd / dearest * 100 : 0;
68874
+ dataRow(label, meter(share, barW, areaRamp(ramps.volume)), dim(`${padStartTo(`${Math.round(pct)}%`, 4)} saved `) + body(usd(s.savedUsd)));
68774
68875
  } else {
68775
- dataRow(label, meter(0, barW, ramps.savings), dim("over by ") + paint(usd(-s.savedUsd), tokens.error));
68876
+ dataRow(label, meter(0, barW, areaRamp(ramps.volume)), dim("over by ") + paint(usd(-s.savedUsd), tokens.error));
68776
68877
  }
68777
68878
  }
68778
68879
  out.push(paint(`\u2570${"\u2500".repeat(W - 2)}\u256F`, tokens.border));
@@ -68780,7 +68881,8 @@ function renderSessionSummary(input) {
68780
68881
  out.push("");
68781
68882
  out.push(dim("Resume this session with:"));
68782
68883
  const modelFlag = resumeModelSpec ? `--model ${resumeModelSpec} ` : "";
68783
- out.push(`claudish ${modelFlag}--resume ${resumeId}`);
68884
+ const prefix = resumeCwd ? `cd ${shellArg(resumeCwd)} && ` : "";
68885
+ out.push(`${prefix}claudish ${modelFlag}--resume ${resumeId}`);
68784
68886
  }
68785
68887
  return out;
68786
68888
  }
@@ -68812,6 +68914,7 @@ function printSessionSummary(input, write) {
68812
68914
  var MIN_W = 62, MAX_W = 96, CHROME = 4, LABEL_W = 10;
68813
68915
  var init_session_summary = __esm(() => {
68814
68916
  init_theme2();
68917
+ init_color();
68815
68918
  init_text();
68816
68919
  init_tokens();
68817
68920
  init_ansi_viz();
@@ -69345,18 +69448,26 @@ Team Status`);
69345
69448
  write(`[claudish] Done
69346
69449
  `);
69347
69450
  try {
69348
- const [{ readSessionStats }, { printSessionSummary }, { findLatestSessionId }] = await Promise.all([
69451
+ const [
69452
+ { readSessionStats },
69453
+ { printSessionSummary },
69454
+ { findLatestSessionId, getRepoContext }
69455
+ ] = await Promise.all([
69349
69456
  Promise.resolve().then(() => (init_session_stats(), exports_session_stats)),
69350
69457
  Promise.resolve().then(() => (init_session_summary(), exports_session_summary)),
69351
69458
  Promise.resolve().then(() => (init_session_discovery(), exports_session_discovery))
69352
69459
  ]);
69353
69460
  const stats = readSessionStats(port);
69461
+ const repo = getRepoContext(process.cwd());
69462
+ const worktreeCwd = repo && repo.current !== repo.root ? process.cwd() : null;
69463
+ const runStartMs = Date.now() - Math.round(process.uptime() * 1000);
69354
69464
  if (stats) {
69355
69465
  printSessionSummary({
69356
69466
  stats,
69357
69467
  modelSpec: explicitModel || stats.modelName || "",
69358
69468
  resumeModelSpec: explicitModel ?? null,
69359
- resumeId: resumedSessionId ?? findLatestSessionId(process.cwd(), Date.now() - stats.durationMs),
69469
+ resumeId: resumedSessionId ?? findLatestSessionId(process.cwd(), runStartMs),
69470
+ resumeCwd: worktreeCwd,
69360
69471
  exitCode
69361
69472
  }, write);
69362
69473
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "9.0.7",
3
+ "version": "9.0.8",
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": "9.0.7",
64
- "@claudish/magmux-darwin-x64": "9.0.7",
65
- "@claudish/magmux-linux-arm64": "9.0.7",
66
- "@claudish/magmux-linux-x64": "9.0.7"
63
+ "@claudish/magmux-darwin-arm64": "9.0.8",
64
+ "@claudish/magmux-darwin-x64": "9.0.8",
65
+ "@claudish/magmux-linux-arm64": "9.0.8",
66
+ "@claudish/magmux-linux-x64": "9.0.8"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",