claudish 6.10.0 → 6.11.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 +374 -240
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -13626,6 +13626,18 @@ var init_stdio2 = __esm(() => {
13626
13626
  });
13627
13627
 
13628
13628
  // src/team-orchestrator.ts
13629
+ var exports_team_orchestrator = {};
13630
+ __export(exports_team_orchestrator, {
13631
+ validateSessionPath: () => validateSessionPath,
13632
+ setupSession: () => setupSession,
13633
+ runModels: () => runModels,
13634
+ parseJudgeVotes: () => parseJudgeVotes,
13635
+ judgeResponses: () => judgeResponses,
13636
+ getStatus: () => getStatus,
13637
+ fisherYatesShuffle: () => fisherYatesShuffle,
13638
+ buildJudgePrompt: () => buildJudgePrompt,
13639
+ aggregateVerdict: () => aggregateVerdict
13640
+ });
13629
13641
  import { spawn } from "child_process";
13630
13642
  import {
13631
13643
  mkdirSync,
@@ -16916,6 +16928,45 @@ var init_logger = __esm(() => {
16916
16928
  ]);
16917
16929
  });
16918
16930
 
16931
+ // src/handlers/shared/anthropic-error.ts
16932
+ function statusToErrorType(status) {
16933
+ switch (status) {
16934
+ case 400:
16935
+ return "invalid_request_error";
16936
+ case 401:
16937
+ return "authentication_error";
16938
+ case 403:
16939
+ return "permission_error";
16940
+ case 404:
16941
+ return "not_found_error";
16942
+ case 429:
16943
+ return "rate_limit_error";
16944
+ case 503:
16945
+ case 529:
16946
+ return "overloaded_error";
16947
+ default:
16948
+ return "api_error";
16949
+ }
16950
+ }
16951
+ function wrapAnthropicError(status, message, errorType) {
16952
+ const type = errorType || statusToErrorType(status);
16953
+ return {
16954
+ type: "error",
16955
+ error: { type, message }
16956
+ };
16957
+ }
16958
+ function ensureAnthropicErrorFormat(status, body) {
16959
+ if (body?.type === "error" && typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
16960
+ return body;
16961
+ }
16962
+ if (typeof body?.error?.type === "string" && typeof body?.error?.message === "string") {
16963
+ return { type: "error", error: body.error };
16964
+ }
16965
+ const message = body?.error?.message || body?.message || body?.error || (typeof body === "string" ? body : JSON.stringify(body));
16966
+ const errorType = body?.error?.type || body?.type || body?.code;
16967
+ return wrapAnthropicError(status, String(message), errorType);
16968
+ }
16969
+
16919
16970
  // src/handlers/native-handler.ts
16920
16971
  class NativeHandler {
16921
16972
  apiKey;
@@ -17007,7 +17058,7 @@ class NativeHandler {
17007
17058
  return c.json(data, { status: anthropicResponse.status, headers: responseHeaders });
17008
17059
  } catch (error2) {
17009
17060
  log(`[Native] Fetch Error: ${error2}`);
17010
- return c.json({ error: { type: "api_error", message: String(error2) } }, 500);
17061
+ return c.json(wrapAnthropicError(500, String(error2)), 500);
17011
17062
  }
17012
17063
  }
17013
17064
  async shutdown() {}
@@ -18571,6 +18622,24 @@ var init_tool_call_recovery = __esm(() => {
18571
18622
  init_logger();
18572
18623
  });
18573
18624
 
18625
+ // src/handlers/shared/web-search-detector.ts
18626
+ function isWebSearchToolCall(toolName) {
18627
+ return WEB_SEARCH_NAMES.has(toolName);
18628
+ }
18629
+ function warnWebSearchUnsupported(toolName, modelName) {
18630
+ log(`[WebSearch] Tool call '${toolName}' detected from model '${modelName}' \u2014 not yet supported`);
18631
+ logStderr(`Warning: Model requested web search ('${toolName}') but server-side web search is not yet implemented. ` + `The tool call will pass through to the client as-is.`);
18632
+ }
18633
+ var WEB_SEARCH_NAMES;
18634
+ var init_web_search_detector = __esm(() => {
18635
+ init_logger();
18636
+ WEB_SEARCH_NAMES = new Set([
18637
+ "web_search",
18638
+ "brave_web_search",
18639
+ "tavily_search"
18640
+ ]);
18641
+ });
18642
+
18574
18643
  // src/handlers/shared/stream-parsers/openai-sse.ts
18575
18644
  function validateToolArguments(toolName, argsStr, toolSchemas, textContent) {
18576
18645
  const result = validateAndRepairToolCall(toolName, argsStr, toolSchemas, textContent);
@@ -18901,6 +18970,9 @@ data: ${JSON.stringify(d)}
18901
18970
  buffered: !!toolSchemas && toolSchemas.length > 0
18902
18971
  };
18903
18972
  state.tools.set(idx, t);
18973
+ if (isWebSearchToolCall(restoredName)) {
18974
+ warnWebSearchUnsupported(restoredName, target);
18975
+ }
18904
18976
  }
18905
18977
  if (!t.started && !t.buffered) {
18906
18978
  send("content_block_start", {
@@ -19067,6 +19139,7 @@ function estimateTokens(text) {
19067
19139
  var init_openai_sse = __esm(() => {
19068
19140
  init_logger();
19069
19141
  init_tool_call_recovery();
19142
+ init_web_search_detector();
19070
19143
  });
19071
19144
 
19072
19145
  // src/handlers/shared/openai-compat.ts
@@ -20989,7 +21062,7 @@ var init_token_tracker = __esm(() => {
20989
21062
  function createResponsesStreamHandler(c, response, opts) {
20990
21063
  const reader = response.body?.getReader();
20991
21064
  if (!reader) {
20992
- return c.json({ error: "No response body" }, 500);
21065
+ return c.json(wrapAnthropicError(500, "No response body"), 500);
20993
21066
  }
20994
21067
  const encoder = new TextEncoder;
20995
21068
  const decoder = new TextDecoder;
@@ -21272,8 +21345,24 @@ function createAnthropicPassthroughStream(c, response, opts) {
21272
21345
  const encoder = new TextEncoder;
21273
21346
  const decoder = new TextDecoder;
21274
21347
  let isClosed = false;
21348
+ let lastActivity = Date.now();
21349
+ let pingInterval = null;
21275
21350
  return c.body(new ReadableStream({
21276
21351
  async start(controller) {
21352
+ const sendPing = () => {
21353
+ if (!isClosed) {
21354
+ controller.enqueue(encoder.encode(`event: ping
21355
+ data: {"type":"ping"}
21356
+
21357
+ `));
21358
+ }
21359
+ };
21360
+ sendPing();
21361
+ pingInterval = setInterval(() => {
21362
+ if (!isClosed && Date.now() - lastActivity > 1000) {
21363
+ sendPing();
21364
+ }
21365
+ }, 1000);
21277
21366
  try {
21278
21367
  const reader = response.body.getReader();
21279
21368
  let buffer = "";
@@ -21288,6 +21377,7 @@ function createAnthropicPassthroughStream(c, response, opts) {
21288
21377
  if (done)
21289
21378
  break;
21290
21379
  buffer += decoder.decode(value, { stream: true });
21380
+ lastActivity = Date.now();
21291
21381
  const lines = buffer.split(`
21292
21382
  `);
21293
21383
  buffer = lines.pop() || "";
@@ -21330,19 +21420,31 @@ function createAnthropicPassthroughStream(c, response, opts) {
21330
21420
  opts.onTokenUpdate(inputTokens, outputTokens);
21331
21421
  }
21332
21422
  if (!isClosed) {
21333
- controller.close();
21334
21423
  isClosed = true;
21424
+ if (pingInterval) {
21425
+ clearInterval(pingInterval);
21426
+ pingInterval = null;
21427
+ }
21428
+ controller.close();
21335
21429
  }
21336
21430
  } catch (e) {
21337
21431
  log(`[AnthropicSSE] Stream error: ${e}`);
21338
21432
  if (!isClosed) {
21339
- controller.close();
21340
21433
  isClosed = true;
21434
+ if (pingInterval) {
21435
+ clearInterval(pingInterval);
21436
+ pingInterval = null;
21437
+ }
21438
+ controller.close();
21341
21439
  }
21342
21440
  }
21343
21441
  },
21344
21442
  cancel() {
21345
21443
  isClosed = true;
21444
+ if (pingInterval) {
21445
+ clearInterval(pingInterval);
21446
+ pingInterval = null;
21447
+ }
21346
21448
  }
21347
21449
  }), {
21348
21450
  headers: {
@@ -22224,6 +22326,9 @@ var init_profile_config = __esm(() => {
22224
22326
  };
22225
22327
  });
22226
22328
 
22329
+ // src/version.ts
22330
+ var VERSION = "6.11.0";
22331
+
22227
22332
  // src/telemetry.ts
22228
22333
  var exports_telemetry = {};
22229
22334
  __export(exports_telemetry, {
@@ -22240,15 +22345,8 @@ __export(exports_telemetry, {
22240
22345
  buildReport: () => buildReport
22241
22346
  });
22242
22347
  import { randomBytes } from "crypto";
22243
- import { createRequire } from "module";
22244
22348
  function getVersion() {
22245
- try {
22246
- const require2 = createRequire(import.meta.url);
22247
- const pkg = require2("../package.json");
22248
- return pkg.version ?? "unknown";
22249
- } catch {
22250
- return "unknown";
22251
- }
22349
+ return VERSION;
22252
22350
  }
22253
22351
  function detectRuntime() {
22254
22352
  if (process.versions.bun) {
@@ -23662,15 +23760,8 @@ __export(exports_stats, {
23662
23760
  handleStatsCommand: () => handleStatsCommand,
23663
23761
  flushStats: () => flushStats
23664
23762
  });
23665
- import { createRequire as createRequire2 } from "module";
23666
23763
  function getVersion2() {
23667
- try {
23668
- const require2 = createRequire2(import.meta.url);
23669
- const pkg = require2("../package.json");
23670
- return pkg.version ?? "unknown";
23671
- } catch {
23672
- return "unknown";
23673
- }
23764
+ return VERSION;
23674
23765
  }
23675
23766
  function detectTimezone() {
23676
23767
  try {
@@ -24217,7 +24308,7 @@ class ComposedHandler {
24217
24308
  invocation_mode: this.options.invocationMode ?? "auto-route"
24218
24309
  });
24219
24310
  } catch {}
24220
- return c.json({ error: { type: "connection_error", message: msg } }, 503);
24311
+ return c.json(wrapAnthropicError(503, msg, "connection_error"), 503);
24221
24312
  }
24222
24313
  throw error2;
24223
24314
  }
@@ -24279,7 +24370,7 @@ class ComposedHandler {
24279
24370
  invocation_mode: this.options.invocationMode ?? "auto-route"
24280
24371
  });
24281
24372
  } catch {}
24282
- return c.json({ error: errorText }, retryResp.status);
24373
+ return c.json(wrapAnthropicError(retryResp.status, errorText), retryResp.status);
24283
24374
  }
24284
24375
  } catch (err) {
24285
24376
  log(`[${this.provider.displayName}] Auth refresh failed: ${err.message}`);
@@ -24316,7 +24407,7 @@ class ComposedHandler {
24316
24407
  invocation_mode: this.options.invocationMode ?? "auto-route"
24317
24408
  });
24318
24409
  } catch {}
24319
- return c.json({ error: { type: "authentication_error", message: err.message } }, 401);
24410
+ return c.json(wrapAnthropicError(401, err.message, "authentication_error"), 401);
24320
24411
  }
24321
24412
  } else {
24322
24413
  const errorText = await response.text();
@@ -24369,7 +24460,7 @@ class ComposedHandler {
24369
24460
  } catch {
24370
24461
  errorBody = { error: { type: "api_error", message: errorText } };
24371
24462
  }
24372
- return c.json(errorBody, response.status);
24463
+ return c.json(ensureAnthropicErrorFormat(response.status, errorBody), response.status);
24373
24464
  }
24374
24465
  }
24375
24466
  if (droppedParams.length > 0) {
@@ -27618,12 +27709,7 @@ class KimiOAuth {
27618
27709
  return deviceId;
27619
27710
  }
27620
27711
  getVersion() {
27621
- try {
27622
- const packageJson = JSON.parse(readFileSync13(join18(__dirname, "../../package.json"), "utf-8"));
27623
- return packageJson.version;
27624
- } catch {
27625
- return "4.0.6";
27626
- }
27712
+ return VERSION;
27627
27713
  }
27628
27714
  getPlatformHeaders() {
27629
27715
  return {
@@ -27907,7 +27993,7 @@ function hasKimiOAuthCredentials() {
27907
27993
  return false;
27908
27994
  }
27909
27995
  }
27910
- var __dirname = "/home/runner/work/claudish/claudish/packages/cli/src/auth", execAsync3, OAUTH_CONFIG3;
27996
+ var execAsync3, OAUTH_CONFIG3;
27911
27997
  var init_kimi_oauth = __esm(() => {
27912
27998
  init_logger();
27913
27999
  execAsync3 = promisify3(exec3);
@@ -29228,7 +29314,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
29228
29314
  return c.json({ input_tokens: Math.ceil(txt.length / 4) });
29229
29315
  }
29230
29316
  } catch (e) {
29231
- return c.json({ error: String(e) }, 500);
29317
+ return c.json(wrapAnthropicError(500, String(e)), 500);
29232
29318
  }
29233
29319
  });
29234
29320
  app.post("/v1/messages", async (c) => {
@@ -29238,7 +29324,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
29238
29324
  return handler.handle(c, body);
29239
29325
  } catch (e) {
29240
29326
  log(`[Proxy] Error: ${e}`);
29241
- return c.json({ error: { type: "server_error", message: String(e) } }, 500);
29327
+ return c.json(wrapAnthropicError(500, String(e)), 500);
29242
29328
  }
29243
29329
  });
29244
29330
  const server = serve({ fetch: app.fetch, port, hostname: "127.0.0.1" });
@@ -44779,7 +44865,7 @@ async function fetchGLMCodingModels() {
44779
44865
  return [];
44780
44866
  }
44781
44867
  }
44782
- var __filename4, __dirname4, VERSION = "6.10.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
44868
+ var __filename4, __dirname4, CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
44783
44869
  var init_cli = __esm(() => {
44784
44870
  init_config();
44785
44871
  init_model_loader();
@@ -44791,10 +44877,6 @@ var init_cli = __esm(() => {
44791
44877
  init_provider_resolver();
44792
44878
  __filename4 = fileURLToPath3(import.meta.url);
44793
44879
  __dirname4 = dirname3(__filename4);
44794
- try {
44795
- const packageJson = JSON.parse(readFileSync19(join23(__dirname4, "../package.json"), "utf-8"));
44796
- VERSION = packageJson.version;
44797
- } catch {}
44798
44880
  CLAUDISH_CACHE_DIR2 = join23(homedir22(), ".claudish");
44799
44881
  BUNDLED_MODELS_PATH = join23(__dirname4, "../recommended-models.json");
44800
44882
  CACHED_MODELS_PATH = join23(CLAUDISH_CACHE_DIR2, "recommended-models.json");
@@ -44809,18 +44891,9 @@ __export(exports_update_checker, {
44809
44891
  clearCache: () => clearCache,
44810
44892
  checkForUpdates: () => checkForUpdates
44811
44893
  });
44812
- import { execSync } from "child_process";
44813
44894
  import { existsSync as existsSync22, mkdirSync as mkdirSync12, readFileSync as readFileSync20, unlinkSync as unlinkSync8, writeFileSync as writeFileSync13 } from "fs";
44814
44895
  import { homedir as homedir23, platform as platform2, tmpdir } from "os";
44815
44896
  import { join as join24 } from "path";
44816
- import { createInterface as createInterface2 } from "readline";
44817
- function getUpdateCommand() {
44818
- const scriptPath = process.argv[1] || "";
44819
- if (scriptPath.includes("/.bun/")) {
44820
- return "bun add -g claudish@latest";
44821
- }
44822
- return "npm install -g claudish@latest";
44823
- }
44824
44897
  function getCacheFilePath() {
44825
44898
  let cacheDir;
44826
44899
  if (isWindows) {
@@ -44903,43 +44976,8 @@ async function fetchLatestVersion() {
44903
44976
  return null;
44904
44977
  }
44905
44978
  }
44906
- function promptUser(question) {
44907
- return new Promise((resolve3) => {
44908
- const rl = createInterface2({
44909
- input: process.stdin,
44910
- output: process.stderr
44911
- });
44912
- rl.question(question, (answer) => {
44913
- rl.close();
44914
- const normalized = answer.toLowerCase().trim();
44915
- resolve3(normalized === "y" || normalized === "yes");
44916
- });
44917
- });
44918
- }
44919
- function runUpdate() {
44920
- const command = getUpdateCommand();
44921
- try {
44922
- console.error(`
44923
- [claudish] Updating...
44924
- `);
44925
- execSync(command, {
44926
- stdio: "inherit",
44927
- shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
44928
- });
44929
- console.error(`
44930
- [claudish] Update complete! Please restart claudish.
44931
- `);
44932
- return true;
44933
- } catch (error2) {
44934
- console.error(`
44935
- [claudish] Update failed. Try manually:`);
44936
- console.error(` ${command}
44937
- `);
44938
- return false;
44939
- }
44940
- }
44941
44979
  async function checkForUpdates(currentVersion, options = {}) {
44942
- const { quiet = false, skipPrompt = false } = options;
44980
+ const { quiet = false } = options;
44943
44981
  let latestVersion = null;
44944
44982
  const cache = readCache();
44945
44983
  if (cache && isCacheValid(cache)) {
@@ -44949,42 +44987,18 @@ async function checkForUpdates(currentVersion, options = {}) {
44949
44987
  writeCache(latestVersion);
44950
44988
  }
44951
44989
  if (!latestVersion) {
44952
- return false;
44990
+ return;
44953
44991
  }
44954
44992
  if (compareVersions(latestVersion, currentVersion) <= 0) {
44955
- return false;
44993
+ return;
44956
44994
  }
44957
44995
  if (!quiet) {
44958
44996
  console.error("");
44959
- console.error("\u2501".repeat(60));
44960
- console.error(` New version available: ${currentVersion} \u2192 ${latestVersion}`);
44961
- console.error("\u2501".repeat(60));
44997
+ console.error(` ${CYAN}\u250C${RESET} ${BOLD}Update available:${RESET} ${currentVersion} ${DIM}\u2192${RESET} ${GREEN}${latestVersion}${RESET} ${DIM}Run:${RESET} ${BOLD}${CYAN}claudish update${RESET}`);
44962
44998
  console.error("");
44963
44999
  }
44964
- if (skipPrompt) {
44965
- if (!quiet) {
44966
- console.error(` Update with: npm install -g claudish@latest
44967
- `);
44968
- }
44969
- return false;
44970
- }
44971
- const shouldUpdate = await promptUser(" Would you like to update now? [y/N] ");
44972
- if (!shouldUpdate) {
44973
- if (!quiet) {
44974
- console.error(`
44975
- Skipped. Update later with: npm install -g claudish@latest
44976
- `);
44977
- }
44978
- return false;
44979
- }
44980
- const success = runUpdate();
44981
- if (success) {
44982
- clearCache();
44983
- return true;
44984
- }
44985
- return false;
44986
45000
  }
44987
- var isWindows, NPM_REGISTRY_URL = "https://registry.npmjs.org/claudish/latest", CACHE_MAX_AGE_MS;
45001
+ var isWindows, NPM_REGISTRY_URL = "https://registry.npmjs.org/claudish/latest", CACHE_MAX_AGE_MS, RESET = "\x1B[0m", BOLD = "\x1B[1m", GREEN = "\x1B[32m", CYAN = "\x1B[36m", DIM = "\x1B[2m";
44988
45002
  var init_update_checker = __esm(() => {
44989
45003
  isWindows = platform2() === "win32";
44990
45004
  CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000;
@@ -44995,8 +45009,7 @@ var exports_update_command = {};
44995
45009
  __export(exports_update_command, {
44996
45010
  updateCommand: () => updateCommand
44997
45011
  });
44998
- import { execSync as execSync2 } from "child_process";
44999
- import { createInterface as createInterface3 } from "readline";
45012
+ import { execSync } from "child_process";
45000
45013
  function detectInstallationMethod() {
45001
45014
  const scriptPath = process.argv[1] || "";
45002
45015
  if (scriptPath.includes("/opt/homebrew/") || scriptPath.includes("/usr/local/Cellar/")) {
@@ -45010,7 +45023,7 @@ function detectInstallationMethod() {
45010
45023
  }
45011
45024
  return { method: "unknown", path: scriptPath };
45012
45025
  }
45013
- function getUpdateCommand2(method) {
45026
+ function getUpdateCommand(method) {
45014
45027
  switch (method) {
45015
45028
  case "npm":
45016
45029
  return "npm install -g claudish@latest";
@@ -45022,104 +45035,199 @@ function getUpdateCommand2(method) {
45022
45035
  return "";
45023
45036
  }
45024
45037
  }
45025
- function promptUser2(question) {
45026
- return new Promise((resolve3) => {
45027
- const rl = createInterface3({
45028
- input: process.stdin,
45029
- output: process.stdout
45030
- });
45031
- rl.question(question, (answer) => {
45032
- rl.close();
45033
- const normalized = answer.toLowerCase().trim();
45034
- resolve3(normalized === "y" || normalized === "yes" || normalized === "");
45035
- });
45036
- });
45037
- }
45038
45038
  async function executeUpdate(command) {
45039
45039
  try {
45040
- console.log(`
45041
- ${BOLD}Updating...${RESET}
45042
- `);
45043
- execSync2(command, {
45040
+ execSync(command, {
45044
45041
  stdio: "inherit",
45045
45042
  shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
45046
45043
  });
45047
- console.log(`
45048
- ${GREEN}\u2713${RESET} ${BOLD}Update complete!${RESET}`);
45049
- console.log(`${CYAN}Please restart any running claudish sessions.${RESET}
45050
- `);
45051
45044
  return true;
45052
- } catch (error2) {
45045
+ } catch {
45053
45046
  console.error(`
45054
- ${RED2}\u2717${RESET} ${BOLD}Update failed.${RESET}`);
45055
- console.error(`${YELLOW}Try manually:${RESET}`);
45047
+ ${RED2}\u2717${RESET2} ${BOLD2}Update failed.${RESET2}`);
45048
+ console.error(`${YELLOW}Try manually:${RESET2}`);
45056
45049
  console.error(` ${command}
45057
45050
  `);
45058
45051
  return false;
45059
45052
  }
45060
45053
  }
45054
+ function parseRelease(r) {
45055
+ const version2 = r.tag_name.replace(/^v/, "");
45056
+ let title = "";
45057
+ const name = r.name || "";
45058
+ const dashMatch = name.match(/\s[\u2014\u2013-]\s(.+)$/);
45059
+ if (dashMatch) {
45060
+ title = dashMatch[1].trim();
45061
+ }
45062
+ const items = [];
45063
+ if (!r.body)
45064
+ return { version: version2, title, items };
45065
+ const lines = r.body.split(`
45066
+ `);
45067
+ let currentType = "feat";
45068
+ for (const line of lines) {
45069
+ if (/^##\s+Install/i.test(line))
45070
+ break;
45071
+ const sectionMatch = line.match(/^###\s+(.+)$/);
45072
+ if (sectionMatch) {
45073
+ const sectionName = sectionMatch[1].trim().toLowerCase();
45074
+ const mapped = SECTION_TYPE_MAP[sectionName];
45075
+ currentType = mapped === undefined ? "chore" : mapped;
45076
+ continue;
45077
+ }
45078
+ if (currentType === null)
45079
+ continue;
45080
+ const bulletMatch = line.match(/^[\s]*[-*]\s+(.+)$/);
45081
+ if (!bulletMatch)
45082
+ continue;
45083
+ let text = bulletMatch[1].trim();
45084
+ text = text.replace(/\(\[`[a-f0-9]+`\]\([^)]*\)\)\s*$/, "").trim();
45085
+ text = text.replace(/^v\d+\.\d+\.\d+\s*[\u2014\u2013-]\s*/, "").trim();
45086
+ if (/^bump\s+to\s+v/i.test(text))
45087
+ continue;
45088
+ if (/^update\s+CHANGELOG/i.test(text))
45089
+ continue;
45090
+ if (!text)
45091
+ continue;
45092
+ items.push({ type: currentType, text });
45093
+ }
45094
+ return { version: version2, title, items };
45095
+ }
45096
+ async function fetchChangelog(currentVersion, latestVersion) {
45097
+ try {
45098
+ const controller = new AbortController;
45099
+ const timeout = setTimeout(() => controller.abort(), 5000);
45100
+ const response = await fetch("https://api.github.com/repos/MadAppGang/claudish/releases", {
45101
+ signal: controller.signal,
45102
+ headers: {
45103
+ Accept: "application/vnd.github+json",
45104
+ "User-Agent": "claudish-updater"
45105
+ }
45106
+ });
45107
+ clearTimeout(timeout);
45108
+ if (!response.ok) {
45109
+ return [];
45110
+ }
45111
+ const releases = await response.json();
45112
+ const relevant = releases.filter((r) => {
45113
+ const ver = r.tag_name.replace(/^v/, "");
45114
+ return compareVersions(ver, currentVersion) > 0 && compareVersions(ver, latestVersion) <= 0;
45115
+ });
45116
+ relevant.sort((a, b) => {
45117
+ const verA = a.tag_name.replace(/^v/, "");
45118
+ const verB = b.tag_name.replace(/^v/, "");
45119
+ return compareVersions(verB, verA);
45120
+ });
45121
+ return relevant.map((r) => parseRelease(r));
45122
+ } catch {
45123
+ return [];
45124
+ }
45125
+ }
45126
+ function itemStyle(type) {
45127
+ switch (type) {
45128
+ case "feat":
45129
+ return { symbol: "\u2726", color: GREEN2 };
45130
+ case "fix":
45131
+ return { symbol: "\u2726", color: YELLOW };
45132
+ case "breaking":
45133
+ return { symbol: "\u2726", color: MAGENTA };
45134
+ case "perf":
45135
+ return { symbol: "\u2726", color: CYAN2 };
45136
+ case "chore":
45137
+ return { symbol: "\u25AA", color: DIM2 };
45138
+ }
45139
+ }
45140
+ function displayChangelog(entries) {
45141
+ if (entries.length === 0) {
45142
+ return;
45143
+ }
45144
+ const innerWidth = 50;
45145
+ const headerLabel = ` ${YELLOW}\u2726${RESET2} ${BOLD2}What's New${RESET2}`;
45146
+ const headerVisible = 14;
45147
+ const headerPad = innerWidth - headerVisible;
45148
+ console.log("");
45149
+ console.log(`${CYAN2}\u250C${"\u2500".repeat(innerWidth + 1)}\u2510${RESET2}`);
45150
+ console.log(`${CYAN2}\u2502${RESET2}${headerLabel}${" ".repeat(headerPad)}${CYAN2}\u2502${RESET2}`);
45151
+ console.log(`${CYAN2}\u2514${"\u2500".repeat(innerWidth + 1)}\u2518${RESET2}`);
45152
+ console.log("");
45153
+ for (const entry of entries) {
45154
+ const titlePart = entry.title ? ` ${entry.title}` : "";
45155
+ console.log(` ${BOLD2}${GREEN2}v${entry.version}${RESET2}${titlePart}`);
45156
+ console.log(` ${DIM2}${"\u2500".repeat(30)}${RESET2}`);
45157
+ for (const item of entry.items) {
45158
+ const { symbol, color } = itemStyle(item.type);
45159
+ console.log(` ${color}${symbol}${RESET2} ${item.text}`);
45160
+ }
45161
+ console.log("");
45162
+ }
45163
+ console.log(`${CYAN2}Please restart any running claudish sessions.${RESET2}`);
45164
+ }
45061
45165
  function printManualInstructions() {
45062
45166
  console.log(`
45063
- ${BOLD}Unable to detect installation method.${RESET}`);
45064
- console.log(`${YELLOW}Please update manually:${RESET}
45167
+ ${BOLD2}Unable to detect installation method.${RESET2}`);
45168
+ console.log(`${YELLOW}Please update manually:${RESET2}
45065
45169
  `);
45066
- console.log(` ${CYAN}npm:${RESET} npm install -g claudish@latest`);
45067
- console.log(` ${CYAN}bun:${RESET} bun install -g claudish@latest`);
45068
- console.log(` ${CYAN}brew:${RESET} brew upgrade claudish
45170
+ console.log(` ${CYAN2}npm:${RESET2} npm install -g claudish@latest`);
45171
+ console.log(` ${CYAN2}bun:${RESET2} bun install -g claudish@latest`);
45172
+ console.log(` ${CYAN2}brew:${RESET2} brew upgrade claudish
45069
45173
  `);
45070
45174
  }
45071
45175
  async function updateCommand() {
45072
45176
  const currentVersion = getVersion3();
45073
45177
  const installInfo = detectInstallationMethod();
45074
- console.log(`claudish v${currentVersion}`);
45075
- console.log(`Installation: ${installInfo.method}`);
45076
- console.log(`
45077
- ${BOLD}Checking for updates...${RESET}
45078
- `);
45079
45178
  const latestVersion = await fetchLatestVersion();
45080
45179
  if (!latestVersion) {
45081
- console.error(`${RED2}\u2717${RESET} Unable to fetch latest version from npm registry.`);
45082
- console.error(`${YELLOW}Please check your internet connection and try again.${RESET}
45180
+ console.error(`${RED2}\u2717${RESET2} Unable to fetch latest version from npm registry.`);
45181
+ console.error(`${YELLOW}Please check your internet connection and try again.${RESET2}
45083
45182
  `);
45084
45183
  process.exit(1);
45085
45184
  }
45086
45185
  const comparison = compareVersions(latestVersion, currentVersion);
45087
45186
  if (comparison <= 0) {
45088
- console.log(`${GREEN}\u2713${RESET} ${BOLD}Already up-to-date!${RESET}`);
45089
- console.log(`${CYAN}Current version: ${currentVersion}${RESET}
45187
+ console.log(`${GREEN2}\u2713${RESET2} ${BOLD2}Already up-to-date!${RESET2}`);
45188
+ console.log(`${CYAN2}Current version: ${currentVersion}${RESET2}
45090
45189
  `);
45091
45190
  process.exit(0);
45092
45191
  }
45093
- console.log(`${BOLD}Current version:${RESET} ${YELLOW}${currentVersion}${RESET}`);
45094
- console.log(`${BOLD}Latest version:${RESET} ${GREEN}${latestVersion}${RESET}
45095
- `);
45192
+ console.log(` ${BOLD2}claudish${RESET2} ${YELLOW}v${currentVersion}${RESET2} ${DIM2}\u2192${RESET2} ${GREEN2}v${latestVersion}${RESET2} ${DIM2}(${installInfo.method})${RESET2}`);
45096
45193
  if (installInfo.method === "unknown") {
45097
45194
  printManualInstructions();
45098
45195
  process.exit(1);
45099
45196
  }
45100
- const command = getUpdateCommand2(installInfo.method);
45101
- console.log(`${BOLD}Update command:${RESET} ${command}
45102
- `);
45103
- const shouldUpdate = await promptUser2(`${BOLD}Proceed with update? [Y/n]${RESET} `);
45104
- if (!shouldUpdate) {
45105
- console.log(`
45106
- ${YELLOW}Update cancelled.${RESET}`);
45107
- console.log(`${CYAN}Update later with: ${command}${RESET}
45197
+ const command = getUpdateCommand(installInfo.method);
45198
+ console.log(`
45199
+ ${DIM2}Updating...${RESET2}
45108
45200
  `);
45109
- process.exit(0);
45110
- }
45111
45201
  const success = await executeUpdate(command);
45112
45202
  if (success) {
45203
+ console.log(`
45204
+ ${GREEN2}\u2713${RESET2} ${BOLD2}Updated successfully${RESET2}`);
45113
45205
  clearCache();
45206
+ const changelog = await fetchChangelog(currentVersion, latestVersion);
45207
+ displayChangelog(changelog);
45208
+ console.log("");
45114
45209
  process.exit(0);
45115
45210
  } else {
45116
45211
  process.exit(1);
45117
45212
  }
45118
45213
  }
45119
- var RESET = "\x1B[0m", BOLD = "\x1B[1m", GREEN = "\x1B[32m", YELLOW = "\x1B[33m", CYAN = "\x1B[36m", RED2 = "\x1B[31m";
45214
+ var RESET2 = "\x1B[0m", BOLD2 = "\x1B[1m", GREEN2 = "\x1B[32m", YELLOW = "\x1B[33m", CYAN2 = "\x1B[36m", RED2 = "\x1B[31m", MAGENTA = "\x1B[35m", DIM2 = "\x1B[2m", SECTION_TYPE_MAP;
45120
45215
  var init_update_command = __esm(() => {
45121
45216
  init_cli();
45122
45217
  init_update_checker();
45218
+ SECTION_TYPE_MAP = {
45219
+ "new features": "feat",
45220
+ features: "feat",
45221
+ "bug fixes": "fix",
45222
+ fixes: "fix",
45223
+ "breaking changes": "breaking",
45224
+ performance: "perf",
45225
+ "other changes": "chore",
45226
+ chore: "chore",
45227
+ refactor: "chore",
45228
+ documentation: null,
45229
+ docs: null
45230
+ };
45123
45231
  });
45124
45232
 
45125
45233
  // src/model-selector.ts
@@ -46561,16 +46669,16 @@ async function resolveScope(scopeFlag) {
46561
46669
  }
46562
46670
  function scopeBadge(scope, shadowed) {
46563
46671
  if (scope === "local") {
46564
- return `${MAGENTA}[local]${RESET2}`;
46672
+ return `${MAGENTA2}[local]${RESET3}`;
46565
46673
  }
46566
46674
  if (shadowed) {
46567
- return `${DIM}[global, shadowed]${RESET2}`;
46675
+ return `${DIM3}[global, shadowed]${RESET3}`;
46568
46676
  }
46569
- return `${DIM}[global]${RESET2}`;
46677
+ return `${DIM3}[global]${RESET3}`;
46570
46678
  }
46571
46679
  async function initCommand(scopeFlag) {
46572
46680
  console.log(`
46573
- ${BOLD2}${CYAN2}Claudish Setup Wizard${RESET2}
46681
+ ${BOLD3}${CYAN3}Claudish Setup Wizard${RESET3}
46574
46682
  `);
46575
46683
  const scope = await resolveScope(scopeFlag);
46576
46684
  const configPath = getConfigPathForScope(scope);
@@ -46584,27 +46692,27 @@ ${BOLD2}${CYAN2}Claudish Setup Wizard${RESET2}
46584
46692
  return;
46585
46693
  }
46586
46694
  }
46587
- console.log(`${DIM}This wizard will help you set up Claudish with your preferred models.${RESET2}
46695
+ console.log(`${DIM3}This wizard will help you set up Claudish with your preferred models.${RESET3}
46588
46696
  `);
46589
46697
  const profileName = "default";
46590
- console.log(`${BOLD2}Step 1: Select models for each Claude tier${RESET2}`);
46591
- console.log(`${DIM}These models will be used when Claude Code requests specific model types.${RESET2}
46698
+ console.log(`${BOLD3}Step 1: Select models for each Claude tier${RESET3}`);
46699
+ console.log(`${DIM3}These models will be used when Claude Code requests specific model types.${RESET3}
46592
46700
  `);
46593
46701
  const models = await selectModelsForProfile();
46594
46702
  const profile = createProfile(profileName, models, undefined, scope);
46595
46703
  setDefaultProfile(profileName, scope);
46596
46704
  console.log(`
46597
- ${GREEN2}\u2713${RESET2} Configuration saved to: ${CYAN2}${configPath}${RESET2}`);
46705
+ ${GREEN3}\u2713${RESET3} Configuration saved to: ${CYAN3}${configPath}${RESET3}`);
46598
46706
  console.log(`
46599
- ${BOLD2}Profile created:${RESET2}`);
46707
+ ${BOLD3}Profile created:${RESET3}`);
46600
46708
  printProfile(profile, true, false, scope);
46601
46709
  console.log(`
46602
- ${BOLD2}Usage:${RESET2}`);
46603
- console.log(` ${CYAN2}claudish${RESET2} # Use default profile`);
46604
- console.log(` ${CYAN2}claudish profile add${RESET2} # Add another profile`);
46710
+ ${BOLD3}Usage:${RESET3}`);
46711
+ console.log(` ${CYAN3}claudish${RESET3} # Use default profile`);
46712
+ console.log(` ${CYAN3}claudish profile add${RESET3} # Add another profile`);
46605
46713
  if (scope === "local") {
46606
46714
  console.log(`
46607
- ${DIM}Local config applies only when running from this directory.${RESET2}`);
46715
+ ${DIM3}Local config applies only when running from this directory.${RESET3}`);
46608
46716
  }
46609
46717
  console.log("");
46610
46718
  }
@@ -46620,11 +46728,11 @@ async function profileListCommand(scopeFilter) {
46620
46728
  return;
46621
46729
  }
46622
46730
  console.log(`
46623
- ${BOLD2}Claudish Profiles${RESET2}
46731
+ ${BOLD3}Claudish Profiles${RESET3}
46624
46732
  `);
46625
- console.log(`${DIM}Global: ${getConfigPath()}${RESET2}`);
46733
+ console.log(`${DIM3}Global: ${getConfigPath()}${RESET3}`);
46626
46734
  if (localConfigExists()) {
46627
- console.log(`${DIM}Local: ${getLocalConfigPath()}${RESET2}`);
46735
+ console.log(`${DIM3}Local: ${getLocalConfigPath()}${RESET3}`);
46628
46736
  }
46629
46737
  console.log("");
46630
46738
  for (const profile of profiles) {
@@ -46634,19 +46742,19 @@ ${BOLD2}Claudish Profiles${RESET2}
46634
46742
  }
46635
46743
  async function profileAddCommand(scopeFlag) {
46636
46744
  console.log(`
46637
- ${BOLD2}${CYAN2}Add New Profile${RESET2}
46745
+ ${BOLD3}${CYAN3}Add New Profile${RESET3}
46638
46746
  `);
46639
46747
  const scope = await resolveScope(scopeFlag);
46640
46748
  const existingNames = getProfileNames(scope);
46641
46749
  const name = await promptForProfileName(existingNames);
46642
46750
  const description = await promptForProfileDescription();
46643
46751
  console.log(`
46644
- ${BOLD2}Select models for this profile:${RESET2}
46752
+ ${BOLD3}Select models for this profile:${RESET3}
46645
46753
  `);
46646
46754
  const models = await selectModelsForProfile();
46647
46755
  const profile = createProfile(name, models, description, scope);
46648
46756
  console.log(`
46649
- ${GREEN2}\u2713${RESET2} Profile "${name}" created ${scopeBadge(scope)}.`);
46757
+ ${GREEN3}\u2713${RESET3} Profile "${name}" created ${scopeBadge(scope)}.`);
46650
46758
  printProfile(profile, false, false, scope);
46651
46759
  const setAsDefault = await dist_default4({
46652
46760
  message: `Set this profile as default in ${scope} config?`,
@@ -46654,7 +46762,7 @@ ${GREEN2}\u2713${RESET2} Profile "${name}" created ${scopeBadge(scope)}.`);
46654
46762
  });
46655
46763
  if (setAsDefault) {
46656
46764
  setDefaultProfile(name, scope);
46657
- console.log(`${GREEN2}\u2713${RESET2} "${name}" is now the default ${scope} profile.`);
46765
+ console.log(`${GREEN3}\u2713${RESET3} "${name}" is now the default ${scope} profile.`);
46658
46766
  }
46659
46767
  }
46660
46768
  async function profileRemoveCommand(name, scopeFlag) {
@@ -46670,7 +46778,7 @@ async function profileRemoveCommand(name, scopeFlag) {
46670
46778
  const choice = await dist_default11({
46671
46779
  message: "Select a profile to remove:",
46672
46780
  choices: selectable.map((p) => ({
46673
- name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET2}` : ""}`,
46781
+ name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET3}` : ""}`,
46674
46782
  value: `${p.scope}:${p.name}`
46675
46783
  }))
46676
46784
  });
@@ -46718,7 +46826,7 @@ async function profileRemoveCommand(name, scopeFlag) {
46718
46826
  }
46719
46827
  try {
46720
46828
  deleteProfile(profileName, scope);
46721
- console.log(`${GREEN2}\u2713${RESET2} Profile "${profileName}" deleted from ${scope} config.`);
46829
+ console.log(`${GREEN3}\u2713${RESET3} Profile "${profileName}" deleted from ${scope} config.`);
46722
46830
  } catch (error2) {
46723
46831
  console.error(`Error: ${error2}`);
46724
46832
  }
@@ -46736,7 +46844,7 @@ async function profileUseCommand(name, scopeFlag) {
46736
46844
  const choice = await dist_default11({
46737
46845
  message: "Select a profile to set as default:",
46738
46846
  choices: selectable.map((p) => ({
46739
- name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET2}` : ""}`,
46847
+ name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET3}` : ""}`,
46740
46848
  value: `${p.scope}:${p.name}`
46741
46849
  }))
46742
46850
  });
@@ -46772,7 +46880,7 @@ async function profileUseCommand(name, scopeFlag) {
46772
46880
  return;
46773
46881
  }
46774
46882
  setDefaultProfile(profileName, scope);
46775
- console.log(`${GREEN2}\u2713${RESET2} "${profileName}" is now the default ${scope} profile.`);
46883
+ console.log(`${GREEN3}\u2713${RESET3} "${profileName}" is now the default ${scope} profile.`);
46776
46884
  }
46777
46885
  async function profileShowCommand(name, scopeFlag) {
46778
46886
  let profileName = name;
@@ -46826,7 +46934,7 @@ async function profileEditCommand(name, scopeFlag) {
46826
46934
  const choice = await dist_default11({
46827
46935
  message: "Select a profile to edit:",
46828
46936
  choices: selectable.map((p) => ({
46829
- name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET2}` : ""}`,
46937
+ name: `${p.name} ${scopeBadge(p.scope)}${p.isDefault ? ` ${YELLOW2}(default)${RESET3}` : ""}`,
46830
46938
  value: `${p.scope}:${p.name}`
46831
46939
  }))
46832
46940
  });
@@ -46861,9 +46969,9 @@ async function profileEditCommand(name, scopeFlag) {
46861
46969
  return;
46862
46970
  }
46863
46971
  console.log(`
46864
- ${BOLD2}Editing profile: ${profileName}${RESET2} ${scopeBadge(scope)}
46972
+ ${BOLD3}Editing profile: ${profileName}${RESET3} ${scopeBadge(scope)}
46865
46973
  `);
46866
- console.log(`${DIM}Current models:${RESET2}`);
46974
+ console.log(`${DIM3}Current models:${RESET3}`);
46867
46975
  printModelMapping(profile.models);
46868
46976
  console.log("");
46869
46977
  const whatToEdit = await dist_default11({
@@ -46885,14 +46993,14 @@ ${BOLD2}Editing profile: ${profileName}${RESET2} ${scopeBadge(scope)}
46885
46993
  const newDescription = await promptForProfileDescription();
46886
46994
  profile.description = newDescription;
46887
46995
  setProfile(profile, scope);
46888
- console.log(`${GREEN2}\u2713${RESET2} Description updated.`);
46996
+ console.log(`${GREEN3}\u2713${RESET3} Description updated.`);
46889
46997
  return;
46890
46998
  }
46891
46999
  if (whatToEdit === "all") {
46892
47000
  const models = await selectModelsForProfile();
46893
47001
  profile.models = { ...profile.models, ...models };
46894
47002
  setProfile(profile, scope);
46895
- console.log(`${GREEN2}\u2713${RESET2} All models updated.`);
47003
+ console.log(`${GREEN3}\u2713${RESET3} All models updated.`);
46896
47004
  return;
46897
47005
  }
46898
47006
  const tier = whatToEdit;
@@ -46902,39 +47010,39 @@ ${BOLD2}Editing profile: ${profileName}${RESET2} ${scopeBadge(scope)}
46902
47010
  });
46903
47011
  profile.models[tier] = newModel;
46904
47012
  setProfile(profile, scope);
46905
- console.log(`${GREEN2}\u2713${RESET2} ${tierName} model updated to: ${newModel}`);
47013
+ console.log(`${GREEN3}\u2713${RESET3} ${tierName} model updated to: ${newModel}`);
46906
47014
  }
46907
47015
  function printProfile(profile, isDefault, verbose = false, scope) {
46908
- const defaultBadge = isDefault ? ` ${YELLOW2}(default)${RESET2}` : "";
47016
+ const defaultBadge = isDefault ? ` ${YELLOW2}(default)${RESET3}` : "";
46909
47017
  const scopeTag = scope ? ` ${scopeBadge(scope)}` : "";
46910
- console.log(`${BOLD2}${profile.name}${RESET2}${defaultBadge}${scopeTag}`);
47018
+ console.log(`${BOLD3}${profile.name}${RESET3}${defaultBadge}${scopeTag}`);
46911
47019
  if (profile.description) {
46912
- console.log(` ${DIM}${profile.description}${RESET2}`);
47020
+ console.log(` ${DIM3}${profile.description}${RESET3}`);
46913
47021
  }
46914
47022
  printModelMapping(profile.models);
46915
47023
  if (verbose) {
46916
- console.log(` ${DIM}Created: ${profile.createdAt}${RESET2}`);
46917
- console.log(` ${DIM}Updated: ${profile.updatedAt}${RESET2}`);
47024
+ console.log(` ${DIM3}Created: ${profile.createdAt}${RESET3}`);
47025
+ console.log(` ${DIM3}Updated: ${profile.updatedAt}${RESET3}`);
46918
47026
  }
46919
47027
  }
46920
47028
  function printProfileWithScope(profile) {
46921
- const defaultBadge = profile.isDefault ? ` ${YELLOW2}(default)${RESET2}` : "";
47029
+ const defaultBadge = profile.isDefault ? ` ${YELLOW2}(default)${RESET3}` : "";
46922
47030
  const badge = scopeBadge(profile.scope, profile.shadowed);
46923
- console.log(`${BOLD2}${profile.name}${RESET2}${defaultBadge} ${badge}`);
47031
+ console.log(`${BOLD3}${profile.name}${RESET3}${defaultBadge} ${badge}`);
46924
47032
  if (profile.shadowed) {
46925
- console.log(` ${DIM}(overridden by local profile of same name)${RESET2}`);
47033
+ console.log(` ${DIM3}(overridden by local profile of same name)${RESET3}`);
46926
47034
  }
46927
47035
  if (profile.description) {
46928
- console.log(` ${DIM}${profile.description}${RESET2}`);
47036
+ console.log(` ${DIM3}${profile.description}${RESET3}`);
46929
47037
  }
46930
47038
  printModelMapping(profile.models);
46931
47039
  }
46932
47040
  function printModelMapping(models) {
46933
- console.log(` ${CYAN2}opus${RESET2}: ${models.opus || DIM + "not set" + RESET2}`);
46934
- console.log(` ${CYAN2}sonnet${RESET2}: ${models.sonnet || DIM + "not set" + RESET2}`);
46935
- console.log(` ${CYAN2}haiku${RESET2}: ${models.haiku || DIM + "not set" + RESET2}`);
47041
+ console.log(` ${CYAN3}opus${RESET3}: ${models.opus || DIM3 + "not set" + RESET3}`);
47042
+ console.log(` ${CYAN3}sonnet${RESET3}: ${models.sonnet || DIM3 + "not set" + RESET3}`);
47043
+ console.log(` ${CYAN3}haiku${RESET3}: ${models.haiku || DIM3 + "not set" + RESET3}`);
46936
47044
  if (models.subagent) {
46937
- console.log(` ${CYAN2}subagent${RESET2}: ${models.subagent}`);
47045
+ console.log(` ${CYAN3}subagent${RESET3}: ${models.subagent}`);
46938
47046
  }
46939
47047
  }
46940
47048
  async function profileCommand(args) {
@@ -46974,22 +47082,22 @@ async function profileCommand(args) {
46974
47082
  }
46975
47083
  function printProfileHelp() {
46976
47084
  console.log(`
46977
- ${BOLD2}Usage:${RESET2} claudish profile <command> [options]
46978
-
46979
- ${BOLD2}Commands:${RESET2}
46980
- ${CYAN2}list${RESET2}, ${CYAN2}ls${RESET2} List all profiles
46981
- ${CYAN2}add${RESET2}, ${CYAN2}new${RESET2} Add a new profile
46982
- ${CYAN2}remove${RESET2} ${DIM}[name]${RESET2} Remove a profile
46983
- ${CYAN2}use${RESET2} ${DIM}[name]${RESET2} Set default profile
46984
- ${CYAN2}show${RESET2} ${DIM}[name]${RESET2} Show profile details
46985
- ${CYAN2}edit${RESET2} ${DIM}[name]${RESET2} Edit a profile
46986
-
46987
- ${BOLD2}Scope Flags:${RESET2}
46988
- ${CYAN2}--local${RESET2} Target .claudish.json in the current directory
46989
- ${CYAN2}--global${RESET2} Target ~/.claudish/config.json (default)
46990
- ${DIM}If neither flag is given, you'll be prompted interactively.${RESET2}
46991
-
46992
- ${BOLD2}Examples:${RESET2}
47085
+ ${BOLD3}Usage:${RESET3} claudish profile <command> [options]
47086
+
47087
+ ${BOLD3}Commands:${RESET3}
47088
+ ${CYAN3}list${RESET3}, ${CYAN3}ls${RESET3} List all profiles
47089
+ ${CYAN3}add${RESET3}, ${CYAN3}new${RESET3} Add a new profile
47090
+ ${CYAN3}remove${RESET3} ${DIM3}[name]${RESET3} Remove a profile
47091
+ ${CYAN3}use${RESET3} ${DIM3}[name]${RESET3} Set default profile
47092
+ ${CYAN3}show${RESET3} ${DIM3}[name]${RESET3} Show profile details
47093
+ ${CYAN3}edit${RESET3} ${DIM3}[name]${RESET3} Edit a profile
47094
+
47095
+ ${BOLD3}Scope Flags:${RESET3}
47096
+ ${CYAN3}--local${RESET3} Target .claudish.json in the current directory
47097
+ ${CYAN3}--global${RESET3} Target ~/.claudish/config.json (default)
47098
+ ${DIM3}If neither flag is given, you'll be prompted interactively.${RESET3}
47099
+
47100
+ ${BOLD3}Examples:${RESET3}
46993
47101
  claudish profile list
46994
47102
  claudish profile list --local
46995
47103
  claudish profile add --local
@@ -46999,7 +47107,7 @@ ${BOLD2}Examples:${RESET2}
46999
47107
  claudish init --local
47000
47108
  `);
47001
47109
  }
47002
- var RESET2 = "\x1B[0m", BOLD2 = "\x1B[1m", DIM = "\x1B[2m", GREEN2 = "\x1B[32m", YELLOW2 = "\x1B[33m", CYAN2 = "\x1B[36m", MAGENTA = "\x1B[35m";
47110
+ var RESET3 = "\x1B[0m", BOLD3 = "\x1B[1m", DIM3 = "\x1B[2m", GREEN3 = "\x1B[32m", YELLOW2 = "\x1B[33m", CYAN3 = "\x1B[36m", MAGENTA2 = "\x1B[35m";
47003
47111
  var init_profile_commands = __esm(() => {
47004
47112
  init_profile_config();
47005
47113
  init_model_selector();
@@ -106100,15 +106208,15 @@ function createTempSettingsFile(modelDisplay, port) {
106100
106208
  const scriptPath = createStatusLineScript(tokenFilePath);
106101
106209
  statusCommand = `node "${scriptPath}"`;
106102
106210
  } else {
106103
- const CYAN3 = "\\033[96m";
106211
+ const CYAN4 = "\\033[96m";
106104
106212
  const YELLOW3 = "\\033[93m";
106105
- const GREEN3 = "\\033[92m";
106106
- const MAGENTA2 = "\\033[95m";
106107
- const DIM2 = "\\033[2m";
106108
- const RESET3 = "\\033[0m";
106109
- const BOLD3 = "\\033[1m";
106213
+ const GREEN4 = "\\033[92m";
106214
+ const MAGENTA3 = "\\033[95m";
106215
+ const DIM4 = "\\033[2m";
106216
+ const RESET4 = "\\033[0m";
106217
+ const BOLD4 = "\\033[1m";
106110
106218
  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; }`;
106111
- statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX=100 && 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 [ "$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 "${CYAN3}${BOLD3}%s${RESET3} ${DIM2}\u2022${RESET3} ${YELLOW3}%s${RESET3} ${DIM2}\u2022${RESET3} ${GREEN3}%s${RESET3} ${DIM2}\u2022${RESET3} ${MAGENTA2}%s${RESET3}\\n" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"`;
106219
+ statusCommand = `JSON=$(cat) && DIR=$(basename "$(pwd)") && [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true && CTX=100 && 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 [ "$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"`;
106112
106220
  }
106113
106221
  const statusLine = {
106114
106222
  type: "command",
@@ -106428,7 +106536,7 @@ import {
106428
106536
  } from "fs";
106429
106537
  import { dirname as dirname6, join as join29 } from "path";
106430
106538
  import { fileURLToPath as fileURLToPath6 } from "url";
106431
- import { execSync as execSync3 } from "child_process";
106539
+ import { execSync as execSync2 } from "child_process";
106432
106540
  function formatElapsed(ms) {
106433
106541
  const s = Math.floor(ms / 1000);
106434
106542
  if (s < 60)
@@ -106463,7 +106571,7 @@ function findMagmuxBinary() {
106463
106571
  }
106464
106572
  } catch {}
106465
106573
  try {
106466
- const result = execSync3("which magmux", { encoding: "utf-8" }).trim();
106574
+ const result = execSync2("which magmux", { encoding: "utf-8" }).trim();
106467
106575
  if (result)
106468
106576
  return result;
106469
106577
  } catch {}
@@ -106791,7 +106899,6 @@ async function runCli() {
106791
106899
  try {
106792
106900
  const cliConfig = await parseArgs2(process.argv.slice(2));
106793
106901
  if (cliConfig.team && cliConfig.team.length > 0) {
106794
- const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
106795
106902
  let prompt = cliConfig.claudeArgs.join(" ");
106796
106903
  if (cliConfig.inputFile) {
106797
106904
  prompt = readFileSync24(cliConfig.inputFile, "utf-8");
@@ -106800,11 +106907,38 @@ async function runCli() {
106800
106907
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
106801
106908
  process.exit(1);
106802
106909
  }
106803
- const keep = cliConfig.teamKeep ?? false;
106910
+ const mode = cliConfig.teamMode ?? "default";
106804
106911
  const sessionPath = join30(process.cwd(), `.claudish-team-${Date.now()}`);
106912
+ if (mode === "json") {
106913
+ const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
106914
+ setupSession2(sessionPath, cliConfig.team, prompt);
106915
+ const status2 = await runModels2(sessionPath, {
106916
+ timeout: 300,
106917
+ claudeFlags: ["--json"]
106918
+ });
106919
+ const result = { ...status2, responses: {} };
106920
+ for (const anonId of Object.keys(status2.models)) {
106921
+ const responsePath = join30(sessionPath, `response-${anonId}.md`);
106922
+ try {
106923
+ const raw2 = readFileSync24(responsePath, "utf-8").trim();
106924
+ try {
106925
+ result.responses[anonId] = JSON.parse(raw2);
106926
+ } catch {
106927
+ result.responses[anonId] = raw2;
106928
+ }
106929
+ } catch {
106930
+ result.responses[anonId] = null;
106931
+ }
106932
+ }
106933
+ console.log(JSON.stringify(result, null, 2));
106934
+ process.exit(0);
106935
+ }
106936
+ const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
106937
+ const keep = cliConfig.teamKeep ?? false;
106805
106938
  const status = await runWithGrid2(sessionPath, cliConfig.team, prompt, {
106806
106939
  timeout: 300,
106807
- keep
106940
+ keep,
106941
+ mode
106808
106942
  });
106809
106943
  const modelIds = Object.keys(status.models).sort();
106810
106944
  console.log(`
@@ -106823,7 +106957,7 @@ Team Status`);
106823
106957
  try {
106824
106958
  const cfg = loadConfig2();
106825
106959
  if (!cfg.autoApproveConfirmedAt) {
106826
- const { createInterface: createInterface4 } = await import("readline");
106960
+ const { createInterface: createInterface2 } = await import("readline");
106827
106961
  process.stderr.write(`
106828
106962
  [claudish] Auto-approve is enabled by default.
106829
106963
  This skips Claude Code permission prompts for tools like Bash, Read, Write.
@@ -106831,7 +106965,7 @@ Team Status`);
106831
106965
 
106832
106966
  `);
106833
106967
  const answer = await new Promise((resolve4) => {
106834
- const rl = createInterface4({ input: process.stdin, output: process.stderr });
106968
+ const rl = createInterface2({ input: process.stdin, output: process.stderr });
106835
106969
  rl.question("Enable auto-approve? [Y/n] ", (ans) => {
106836
106970
  rl.close();
106837
106971
  resolve4(ans.trim().toLowerCase());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "6.10.0",
3
+ "version": "6.11.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",
@@ -13,8 +13,8 @@
13
13
  "dev:grok": "bun run src/index.ts --interactive --model x-ai/grok-code-fast-1",
14
14
  "dev:grok:debug": "bun run src/index.ts --interactive --debug --log-level info --model x-ai/grok-code-fast-1",
15
15
  "dev:info": "bun run src/index.ts --interactive --monitor",
16
- "build": "bun build src/index.ts --outdir dist --target bun && chmod +x dist/index.js",
17
- "build:binary": "bun build src/index.ts --compile --outfile claudish",
16
+ "build": "bun run scripts/generate-version.ts && bun build src/index.ts --outdir dist --target bun && chmod +x dist/index.js",
17
+ "build:binary": "bun run scripts/generate-version.ts && bun build src/index.ts --compile --outfile claudish",
18
18
  "typecheck": "tsc --noEmit",
19
19
  "lint": "biome check .",
20
20
  "format": "biome format --write .",
@@ -59,10 +59,10 @@
59
59
  "ai"
60
60
  ],
61
61
  "optionalDependencies": {
62
- "@claudish/magmux-darwin-arm64": "6.10.0",
63
- "@claudish/magmux-darwin-x64": "6.10.0",
64
- "@claudish/magmux-linux-arm64": "6.10.0",
65
- "@claudish/magmux-linux-x64": "6.10.0"
62
+ "@claudish/magmux-darwin-arm64": "6.11.0",
63
+ "@claudish/magmux-darwin-x64": "6.11.0",
64
+ "@claudish/magmux-linux-arm64": "6.11.0",
65
+ "@claudish/magmux-linux-x64": "6.11.0"
66
66
  },
67
67
  "author": "Jack Rudenko <i@madappgang.com>",
68
68
  "license": "MIT",