@musistudio/claude-code-router 1.0.36 → 1.0.37

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/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Claude Code Router
2
2
 
3
+ I am seeking funding support for this project to better sustain its development. If you have any ideas, feel free to reach out to me: [m@musiiot.top](mailto:m@musiiot.top)
4
+
5
+
3
6
  [中文版](README_zh.md)
4
7
 
5
8
  > A powerful tool to route Claude Code requests to different models and customize any request.
package/README_zh.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Claude Code Router
2
2
 
3
+ 我正在为该项目寻求资金支持,以更好地维持其发展。如果您有任何想法,请随时与我联系: [m@musiiot.top](mailto:m@musiiot.top)
4
+
3
5
  > 一款强大的工具,可将 Claude Code 请求路由到不同的模型,并自定义任何请求。
4
6
 
5
7
  ![](blog/images/claude-code.png)
package/dist/cli.js CHANGED
@@ -1202,13 +1202,68 @@ var init_logCleanup = __esm({
1202
1202
  }
1203
1203
  });
1204
1204
 
1205
+ // src/utils/update.ts
1206
+ async function checkForUpdates(currentVersion) {
1207
+ try {
1208
+ const { stdout } = await execPromise("npm view @musistudio/claude-code-router version");
1209
+ const latestVersion = stdout.trim();
1210
+ const hasUpdate = compareVersions(latestVersion, currentVersion) > 0;
1211
+ let changelog = "";
1212
+ return { hasUpdate, latestVersion, changelog };
1213
+ } catch (error) {
1214
+ console.error("Error checking for updates:", error);
1215
+ return { hasUpdate: false, latestVersion: currentVersion, changelog: "" };
1216
+ }
1217
+ }
1218
+ async function performUpdate() {
1219
+ try {
1220
+ const { stdout, stderr } = await execPromise("npm update -g @musistudio/claude-code-router");
1221
+ if (stderr) {
1222
+ console.error("Update stderr:", stderr);
1223
+ }
1224
+ console.log("Update stdout:", stdout);
1225
+ return {
1226
+ success: true,
1227
+ message: "Update completed successfully. Please restart the application to apply changes."
1228
+ };
1229
+ } catch (error) {
1230
+ console.error("Error performing update:", error);
1231
+ return {
1232
+ success: false,
1233
+ message: `Failed to perform update: ${error instanceof Error ? error.message : "Unknown error"}`
1234
+ };
1235
+ }
1236
+ }
1237
+ function compareVersions(v1, v2) {
1238
+ const parts1 = v1.split(".").map(Number);
1239
+ const parts2 = v2.split(".").map(Number);
1240
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
1241
+ const num1 = i < parts1.length ? parts1[i] : 0;
1242
+ const num2 = i < parts2.length ? parts2[i] : 0;
1243
+ if (num1 > num2) return 1;
1244
+ if (num1 < num2) return -1;
1245
+ }
1246
+ return 0;
1247
+ }
1248
+ var import_child_process, import_util, execPromise;
1249
+ var init_update = __esm({
1250
+ "src/utils/update.ts"() {
1251
+ "use strict";
1252
+ import_child_process = require("child_process");
1253
+ import_util = require("util");
1254
+ execPromise = (0, import_util.promisify)(import_child_process.exec);
1255
+ }
1256
+ });
1257
+
1205
1258
  // src/utils/index.ts
1206
1259
  var utils_exports = {};
1207
1260
  __export(utils_exports, {
1208
1261
  backupConfigFile: () => backupConfigFile,
1262
+ checkForUpdates: () => checkForUpdates,
1209
1263
  cleanupLogFiles: () => cleanupLogFiles,
1210
1264
  initConfig: () => initConfig,
1211
1265
  initDir: () => initDir,
1266
+ performUpdate: () => performUpdate,
1212
1267
  readConfigFile: () => readConfigFile,
1213
1268
  writeConfigFile: () => writeConfigFile
1214
1269
  });
@@ -1222,6 +1277,7 @@ var init_utils = __esm({
1222
1277
  import_node_path3 = __toESM(require("node:path"));
1223
1278
  init_constants();
1224
1279
  init_logCleanup();
1280
+ init_update();
1225
1281
  interpolateEnvVars = (obj) => {
1226
1282
  if (typeof obj === "string") {
1227
1283
  return obj.replace(/\$\{([^}]+)\}|\$([A-Z_][A-Z0-9_]*)/g, (match, braced, unbraced) => {
@@ -46223,7 +46279,7 @@ var require_mock_interceptor = __commonJS({
46223
46279
  var require_mock_client = __commonJS({
46224
46280
  "node_modules/.pnpm/undici@7.11.0/node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
46225
46281
  "use strict";
46226
- var { promisify } = require("node:util");
46282
+ var { promisify: promisify2 } = require("node:util");
46227
46283
  var Client = require_client();
46228
46284
  var { buildMockDispatch } = require_mock_utils();
46229
46285
  var {
@@ -46271,7 +46327,7 @@ var require_mock_client = __commonJS({
46271
46327
  this[kDispatches] = [];
46272
46328
  }
46273
46329
  async [kClose]() {
46274
- await promisify(this[kOriginalClose])();
46330
+ await promisify2(this[kOriginalClose])();
46275
46331
  this[kConnected] = 0;
46276
46332
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
46277
46333
  }
@@ -46484,7 +46540,7 @@ var require_mock_call_history = __commonJS({
46484
46540
  var require_mock_pool = __commonJS({
46485
46541
  "node_modules/.pnpm/undici@7.11.0/node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
46486
46542
  "use strict";
46487
- var { promisify } = require("node:util");
46543
+ var { promisify: promisify2 } = require("node:util");
46488
46544
  var Pool = require_pool();
46489
46545
  var { buildMockDispatch } = require_mock_utils();
46490
46546
  var {
@@ -46532,7 +46588,7 @@ var require_mock_pool = __commonJS({
46532
46588
  this[kDispatches] = [];
46533
46589
  }
46534
46590
  async [kClose]() {
46535
- await promisify(this[kOriginalClose])();
46591
+ await promisify2(this[kOriginalClose])();
46536
46592
  this[kConnected] = 0;
46537
46593
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
46538
46594
  }
@@ -65168,6 +65224,57 @@ var require_static = __commonJS({
65168
65224
  }
65169
65225
  });
65170
65226
 
65227
+ // package.json
65228
+ var require_package3 = __commonJS({
65229
+ "package.json"(exports2, module2) {
65230
+ module2.exports = {
65231
+ name: "@musistudio/claude-code-router",
65232
+ version: "1.0.37",
65233
+ description: "Use Claude Code without an Anthropics account and route it to another LLM provider",
65234
+ bin: {
65235
+ ccr: "./dist/cli.js"
65236
+ },
65237
+ scripts: {
65238
+ build: "node scripts/build.js",
65239
+ release: "npm run build && npm publish"
65240
+ },
65241
+ keywords: [
65242
+ "claude",
65243
+ "code",
65244
+ "router",
65245
+ "llm",
65246
+ "anthropic"
65247
+ ],
65248
+ author: "musistudio",
65249
+ license: "MIT",
65250
+ dependencies: {
65251
+ "@fastify/static": "^8.2.0",
65252
+ "@musistudio/llms": "^1.0.23",
65253
+ dotenv: "^16.4.7",
65254
+ json5: "^2.2.3",
65255
+ openurl: "^1.1.1",
65256
+ "pino-rotating-file-stream": "^0.0.2",
65257
+ tiktoken: "^1.0.21",
65258
+ uuid: "^11.1.0"
65259
+ },
65260
+ devDependencies: {
65261
+ "@types/node": "^24.0.15",
65262
+ esbuild: "^0.25.1",
65263
+ fastify: "^5.4.0",
65264
+ shx: "^0.4.0",
65265
+ typescript: "^5.8.2"
65266
+ },
65267
+ publishConfig: {
65268
+ ignore: [
65269
+ "!build/",
65270
+ "src/",
65271
+ "screenshots/"
65272
+ ]
65273
+ }
65274
+ };
65275
+ }
65276
+ });
65277
+
65171
65278
  // node_modules/.pnpm/tiktoken@1.0.21/node_modules/tiktoken/tiktoken_bg.cjs
65172
65279
  var require_tiktoken_bg = __commonJS({
65173
65280
  "node_modules/.pnpm/tiktoken@1.0.21/node_modules/tiktoken/tiktoken_bg.cjs"(exports2, module2) {
@@ -65605,7 +65712,7 @@ var import_os = require("os");
65605
65712
  var import_path4 = require("path");
65606
65713
  init_utils();
65607
65714
 
65608
- // node_modules/.pnpm/@musistudio+llms@1.0.22_ws@8.18.3_zod@3.25.67/node_modules/@musistudio/llms/dist/esm/server.mjs
65715
+ // node_modules/.pnpm/@musistudio+llms@1.0.23_ws@8.18.3_zod@3.25.67/node_modules/@musistudio/llms/dist/esm/server.mjs
65609
65716
  var import_node_fs = require("node:fs");
65610
65717
  var import_node_path4 = require("node:path");
65611
65718
  var import_node_stream = __toESM(require("node:stream"), 1);
@@ -74622,7 +74729,7 @@ async function jf(r, e, t) {
74622
74729
  function Lf(r, e, t, n) {
74623
74730
  let o = new Headers({ "Content-Type": "application/json" });
74624
74731
  t.headers && Object.entries(t.headers).forEach(([f, h]) => {
74625
- o.set(f, h);
74732
+ h && o.set(f, h);
74626
74733
  });
74627
74734
  let a, u = AbortSignal.timeout(t.TIMEOUT ?? 60 * 1e3 * 60);
74628
74735
  if (t.signal) {
@@ -74630,9 +74737,9 @@ function Lf(r, e, t, n) {
74630
74737
  t.signal.addEventListener("abort", h), u.addEventListener("abort", h), a = f.signal;
74631
74738
  } else a = u;
74632
74739
  let l = { method: "POST", headers: o, body: JSON.stringify(e), signal: a };
74633
- return t.httpsProxy && (l.dispatcher = new import_undici.ProxyAgent(new URL(t.httpsProxy).toString())), n?.debug({ request: l, requestUrl: typeof r == "string" ? r : r.toString(), useProxy: t.httpsProxy }, "final request"), fetch(typeof r == "string" ? r : r.toString(), l);
74740
+ return t.httpsProxy && (l.dispatcher = new import_undici.ProxyAgent(new URL(t.httpsProxy).toString())), n?.debug({ request: l, headers: Object.fromEntries(o.entries()), requestUrl: typeof r == "string" ? r : r.toString(), useProxy: t.httpsProxy }, "final request"), fetch(typeof r == "string" ? r : r.toString(), l);
74634
74741
  }
74635
- var Uf = "1.0.22";
74742
+ var Uf = "1.0.23";
74636
74743
  async function o0(r, e, t, n) {
74637
74744
  let o = r.body, a = r.provider, u = t._server.providerService.getProvider(a);
74638
74745
  if (!u) throw bt(`Provider '${a}' not found`, 404, "provider_not_found");
@@ -74641,7 +74748,7 @@ async function o0(r, e, t, n) {
74641
74748
  }
74642
74749
  async function i0(r, e, t, n) {
74643
74750
  let o = r, a = {}, u = false;
74644
- if (u = a0(e, t, r), u && (a.headers = n), !u && typeof t.transformRequestOut == "function") {
74751
+ if (u = a0(e, t, r), u && (n instanceof Headers ? n.delete("content-length") : delete n["content-length"], a.headers = n), !u && typeof t.transformRequestOut == "function") {
74645
74752
  let l = await t.transformRequestOut(o);
74646
74753
  l.body ? (o = l.body, a = l.config || {}) : o = l;
74647
74754
  }
@@ -74663,7 +74770,7 @@ async function u0(r, e, t, n, o, a) {
74663
74770
  if (f.body) {
74664
74771
  r = f.body;
74665
74772
  let h = e.headers || {};
74666
- f.config?.headers && (h = { ...h, host: void 0, ...f.config.headers }, delete f.config.headers), e = { ...e, ...f.config, headers: h };
74773
+ f.config?.headers && (h = { ...h, ...f.config.headers }, delete h.host, delete f.config.headers), e = { ...e, ...f.config, headers: h };
74667
74774
  } else r = f;
74668
74775
  }
74669
74776
  let l = await Lf(u, r, { httpsProxy: n._server.configService.getHttpsProxy(), ...e, headers: { Authorization: `Bearer ${t.apiKey}`, ...e?.headers || {} } }, n.log);
@@ -74900,7 +75007,7 @@ var bo = class {
74900
75007
  name = "Anthropic";
74901
75008
  endPoint = "/v1/messages";
74902
75009
  async auth(e, t) {
74903
- return { body: e, config: { headers: { "x-api-key": t.apiKey, Authorization: void 0 } } };
75010
+ return { body: e, config: { headers: { "x-api-key": t.apiKey, authorization: void 0 } } };
74904
75011
  }
74905
75012
  async transformRequestOut(e) {
74906
75013
  let t = [];
@@ -74966,10 +75073,13 @@ var bo = class {
74966
75073
  }
74967
75074
  }, U = () => {
74968
75075
  if (!g) try {
74969
- u && (v(o.encode(`event: message_delta
75076
+ u ? (v(o.encode(`event: message_delta
74970
75077
  data: ${JSON.stringify(u)}
74971
75078
 
74972
- `)), u = null);
75079
+ `)), u = null) : v(o.encode(`event: message_delta
75080
+ data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "end_turn", stop_sequence: null }, usage: { input_tokens: 0, output_tokens: 0, cache_read_input_tokens: 0 } })}
75081
+
75082
+ `));
74973
75083
  let j = { type: "message_stop" };
74974
75084
  v(o.encode(`event: message_stop
74975
75085
  data: ${JSON.stringify(j)}
@@ -76646,6 +76756,7 @@ var XT = bl;
76646
76756
 
76647
76757
  // src/server.ts
76648
76758
  init_utils();
76759
+ init_utils();
76649
76760
  var import_path2 = require("path");
76650
76761
  var import_static = __toESM(require_static());
76651
76762
  var createServer = (config) => {
@@ -76673,11 +76784,6 @@ var createServer = (config) => {
76673
76784
  return { success: true, message: "Config saved successfully" };
76674
76785
  });
76675
76786
  server.app.post("/api/restart", async (req, reply) => {
76676
- const accessLevel = req.accessLevel || "restricted";
76677
- if (accessLevel !== "full") {
76678
- reply.status(403).send("Full access required to restart service");
76679
- return;
76680
- }
76681
76787
  reply.send({ success: true, message: "Service restart initiated" });
76682
76788
  setTimeout(() => {
76683
76789
  const { spawn: spawn3 } = require("child_process");
@@ -76695,6 +76801,34 @@ var createServer = (config) => {
76695
76801
  server.app.get("/ui", async (_, reply) => {
76696
76802
  return reply.redirect("/ui/");
76697
76803
  });
76804
+ server.app.get("/api/update/check", async (req, reply) => {
76805
+ try {
76806
+ const currentVersion = require_package3().version;
76807
+ const { hasUpdate, latestVersion, changelog } = await checkForUpdates(currentVersion);
76808
+ return {
76809
+ hasUpdate,
76810
+ latestVersion: hasUpdate ? latestVersion : void 0,
76811
+ changelog: hasUpdate ? changelog : void 0
76812
+ };
76813
+ } catch (error) {
76814
+ console.error("Failed to check for updates:", error);
76815
+ reply.status(500).send({ error: "Failed to check for updates" });
76816
+ }
76817
+ });
76818
+ server.app.post("/api/update/perform", async (req, reply) => {
76819
+ try {
76820
+ const accessLevel = req.accessLevel || "restricted";
76821
+ if (accessLevel !== "full") {
76822
+ reply.status(403).send("Full access required to perform updates");
76823
+ return;
76824
+ }
76825
+ const result = await performUpdate();
76826
+ return result;
76827
+ } catch (error) {
76828
+ console.error("Failed to perform update:", error);
76829
+ reply.status(500).send({ error: "Failed to perform update" });
76830
+ }
76831
+ });
76698
76832
  return server;
76699
76833
  };
76700
76834
 
@@ -76860,7 +76994,7 @@ var apiKeyAuth = (config) => async (req, reply, done) => {
76860
76994
  `http://127.0.0.1:${config.PORT || 3456}`,
76861
76995
  `http://localhost:${config.PORT || 3456}`
76862
76996
  ];
76863
- if (req.headers.origin && allowedOrigins.includes(req.headers.origin)) {
76997
+ if (req.headers.origin && !allowedOrigins.includes(req.headers.origin)) {
76864
76998
  reply.status(403).send("CORS not allowed for this origin");
76865
76999
  return;
76866
77000
  } else {
@@ -76996,13 +77130,13 @@ async function getServiceInfo() {
76996
77130
  init_constants();
76997
77131
 
76998
77132
  // node_modules/.pnpm/rotating-file-stream@3.2.6/node_modules/rotating-file-stream/dist/esm/index.js
76999
- var import_child_process = require("child_process");
77133
+ var import_child_process2 = require("child_process");
77000
77134
  var import_zlib = require("zlib");
77001
77135
  var import_stream = require("stream");
77002
77136
  var import_fs3 = require("fs");
77003
77137
  var import_promises3 = require("fs/promises");
77004
77138
  var import_path3 = require("path");
77005
- var import_util = require("util");
77139
+ var import_util2 = require("util");
77006
77140
  var import_timers = require("timers");
77007
77141
  async function exists(filename) {
77008
77142
  return new Promise((resolve) => (0, import_fs3.access)(filename, import_fs3.constants.F_OK, (error) => resolve(!error)));
@@ -77041,7 +77175,7 @@ var RotatingFileStream = class extends import_stream.Writable {
77041
77175
  const { encoding, history, maxFiles, maxSize, path: path6 } = options;
77042
77176
  super({ decodeStrings: true, defaultEncoding: encoding });
77043
77177
  this.createGzip = import_zlib.createGzip;
77044
- this.exec = import_child_process.exec;
77178
+ this.exec = import_child_process2.exec;
77045
77179
  this.filename = path6 + generator(null);
77046
77180
  this.fsCreateReadStream = import_fs3.createReadStream;
77047
77181
  this.fsCreateWriteStream = import_fs3.createWriteStream;
@@ -77481,7 +77615,7 @@ function checkSize(value) {
77481
77615
  return ret.num;
77482
77616
  }
77483
77617
  var checks = {
77484
- encoding: (type, options, value) => new import_util.TextDecoder(value),
77618
+ encoding: (type, options, value) => new import_util2.TextDecoder(value),
77485
77619
  immutable: () => {
77486
77620
  },
77487
77621
  initialRotation: () => {
@@ -77720,7 +77854,7 @@ async function showStatus() {
77720
77854
  }
77721
77855
 
77722
77856
  // src/utils/codeCommand.ts
77723
- var import_child_process2 = require("child_process");
77857
+ var import_child_process3 = require("child_process");
77724
77858
  init_utils();
77725
77859
 
77726
77860
  // src/utils/close.ts
@@ -77774,7 +77908,7 @@ async function executeCodeCommand(args = []) {
77774
77908
  const claudePath = process.env.CLAUDE_PATH || "claude";
77775
77909
  const joinedArgs = args.length > 0 ? args.map((arg) => `"${arg.replace(/\"/g, '\\"')}"`).join(" ") : "";
77776
77910
  const stdioConfig = config.NON_INTERACTIVE_MODE ? ["pipe", "inherit", "inherit"] : "inherit";
77777
- const claudeProcess = (0, import_child_process2.spawn)(claudePath + (joinedArgs ? ` ${joinedArgs}` : ""), [], {
77911
+ const claudeProcess = (0, import_child_process3.spawn)(claudePath + (joinedArgs ? ` ${joinedArgs}` : ""), [], {
77778
77912
  env,
77779
77913
  stdio: stdioConfig,
77780
77914
  shell: true
@@ -77797,11 +77931,9 @@ async function executeCodeCommand(args = []) {
77797
77931
  });
77798
77932
  }
77799
77933
 
77800
- // package.json
77801
- var version = "1.0.36";
77802
-
77803
77934
  // src/cli.ts
77804
- var import_child_process3 = require("child_process");
77935
+ var import_package = __toESM(require_package3());
77936
+ var import_child_process4 = require("child_process");
77805
77937
  init_constants();
77806
77938
  var import_fs6 = __toESM(require("fs"));
77807
77939
  var import_path6 = require("path");
@@ -77869,7 +78001,7 @@ async function main() {
77869
78001
  if (!isServiceRunning()) {
77870
78002
  console.log("Service not running, starting service...");
77871
78003
  const cliPath2 = (0, import_path6.join)(__dirname, "cli.js");
77872
- const startProcess2 = (0, import_child_process3.spawn)("node", [cliPath2, "start"], {
78004
+ const startProcess2 = (0, import_child_process4.spawn)("node", [cliPath2, "start"], {
77873
78005
  detached: true,
77874
78006
  stdio: "ignore"
77875
78007
  });
@@ -77896,7 +78028,7 @@ async function main() {
77896
78028
  if (!isServiceRunning()) {
77897
78029
  console.log("Service not running, starting service...");
77898
78030
  const cliPath2 = (0, import_path6.join)(__dirname, "cli.js");
77899
- const startProcess2 = (0, import_child_process3.spawn)("node", [cliPath2, "start"], {
78031
+ const startProcess2 = (0, import_child_process4.spawn)("node", [cliPath2, "start"], {
77900
78032
  detached: true,
77901
78033
  stdio: "ignore"
77902
78034
  });
@@ -77933,7 +78065,7 @@ async function main() {
77933
78065
  console.log(
77934
78066
  "Please edit this file with your actual configuration."
77935
78067
  );
77936
- const restartProcess = (0, import_child_process3.spawn)("node", [cliPath2, "start"], {
78068
+ const restartProcess = (0, import_child_process4.spawn)("node", [cliPath2, "start"], {
77937
78069
  detached: true,
77938
78070
  stdio: "ignore"
77939
78071
  });
@@ -77975,7 +78107,7 @@ async function main() {
77975
78107
  console.error("Unsupported platform for opening browser");
77976
78108
  process.exit(1);
77977
78109
  }
77978
- (0, import_child_process3.exec)(openCommand, (error) => {
78110
+ (0, import_child_process4.exec)(openCommand, (error) => {
77979
78111
  if (error) {
77980
78112
  console.error("Failed to open browser:", error.message);
77981
78113
  process.exit(1);
@@ -77984,7 +78116,7 @@ async function main() {
77984
78116
  break;
77985
78117
  case "-v":
77986
78118
  case "version":
77987
- console.log(`claude-code-router version: ${version}`);
78119
+ console.log(`claude-code-router version: ${import_package.version}`);
77988
78120
  break;
77989
78121
  case "restart":
77990
78122
  try {
@@ -78004,7 +78136,7 @@ async function main() {
78004
78136
  }
78005
78137
  console.log("Starting claude code router service...");
78006
78138
  const cliPath = (0, import_path6.join)(__dirname, "cli.js");
78007
- const startProcess = (0, import_child_process3.spawn)("node", [cliPath, "start"], {
78139
+ const startProcess = (0, import_child_process4.spawn)("node", [cliPath, "start"], {
78008
78140
  detached: true,
78009
78141
  stdio: "ignore"
78010
78142
  });