@musistudio/claude-code-router 1.0.55 → 1.0.56

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/cli.js +197 -190
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -67229,60 +67229,6 @@ var require_static = __commonJS({
67229
67229
  }
67230
67230
  });
67231
67231
 
67232
- // package.json
67233
- var require_package3 = __commonJS({
67234
- "package.json"(exports2, module2) {
67235
- module2.exports = {
67236
- name: "@musistudio/claude-code-router",
67237
- version: "1.0.55",
67238
- description: "Use Claude Code without an Anthropics account and route it to another LLM provider",
67239
- bin: {
67240
- ccr: "dist/cli.js"
67241
- },
67242
- scripts: {
67243
- build: "node scripts/build.js",
67244
- release: "npm run build && npm publish"
67245
- },
67246
- keywords: [
67247
- "claude",
67248
- "code",
67249
- "router",
67250
- "llm",
67251
- "anthropic"
67252
- ],
67253
- author: "musistudio",
67254
- license: "MIT",
67255
- dependencies: {
67256
- "@fastify/static": "^8.2.0",
67257
- "@musistudio/llms": "^1.0.35",
67258
- dotenv: "^16.4.7",
67259
- "find-process": "^2.0.0",
67260
- json5: "^2.2.3",
67261
- minimist: "^1.2.8",
67262
- openurl: "^1.1.1",
67263
- "rotating-file-stream": "^3.2.7",
67264
- "shell-quote": "^1.8.3",
67265
- tiktoken: "^1.0.21",
67266
- uuid: "^11.1.0"
67267
- },
67268
- devDependencies: {
67269
- "@types/node": "^24.0.15",
67270
- esbuild: "^0.25.1",
67271
- fastify: "^5.4.0",
67272
- shx: "^0.4.0",
67273
- typescript: "^5.8.2"
67274
- },
67275
- publishConfig: {
67276
- ignore: [
67277
- "!build/",
67278
- "src/",
67279
- "screenshots/"
67280
- ]
67281
- }
67282
- };
67283
- }
67284
- });
67285
-
67286
67232
  // node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken_bg.cjs
67287
67233
  var require_tiktoken_bg = __commonJS({
67288
67234
  "node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken_bg.cjs"(exports2, module2) {
@@ -67742,6 +67688,60 @@ var require_tiktoken = __commonJS({
67742
67688
  }
67743
67689
  });
67744
67690
 
67691
+ // package.json
67692
+ var require_package3 = __commonJS({
67693
+ "package.json"(exports2, module2) {
67694
+ module2.exports = {
67695
+ name: "@musistudio/claude-code-router",
67696
+ version: "1.0.55",
67697
+ description: "Use Claude Code without an Anthropics account and route it to another LLM provider",
67698
+ bin: {
67699
+ ccr: "dist/cli.js"
67700
+ },
67701
+ scripts: {
67702
+ build: "node scripts/build.js",
67703
+ release: "npm run build && npm publish"
67704
+ },
67705
+ keywords: [
67706
+ "claude",
67707
+ "code",
67708
+ "router",
67709
+ "llm",
67710
+ "anthropic"
67711
+ ],
67712
+ author: "musistudio",
67713
+ license: "MIT",
67714
+ dependencies: {
67715
+ "@fastify/static": "^8.2.0",
67716
+ "@musistudio/llms": "^1.0.35",
67717
+ dotenv: "^16.4.7",
67718
+ "find-process": "^2.0.0",
67719
+ json5: "^2.2.3",
67720
+ minimist: "^1.2.8",
67721
+ openurl: "^1.1.1",
67722
+ "rotating-file-stream": "^3.2.7",
67723
+ "shell-quote": "^1.8.3",
67724
+ tiktoken: "^1.0.21",
67725
+ uuid: "^11.1.0"
67726
+ },
67727
+ devDependencies: {
67728
+ "@types/node": "^24.0.15",
67729
+ esbuild: "^0.25.1",
67730
+ fastify: "^5.4.0",
67731
+ shx: "^0.4.0",
67732
+ typescript: "^5.8.2"
67733
+ },
67734
+ publishConfig: {
67735
+ ignore: [
67736
+ "!build/",
67737
+ "src/",
67738
+ "screenshots/"
67739
+ ]
67740
+ }
67741
+ };
67742
+ }
67743
+ });
67744
+
67745
67745
  // node_modules/.pnpm/find-process@2.0.0/node_modules/find-process/dist/utils.js
67746
67746
  var require_utils3 = __commonJS({
67747
67747
  "node_modules/.pnpm/find-process@2.0.0/node_modules/find-process/dist/utils.js"(exports2) {
@@ -80401,142 +80401,6 @@ var import_path2 = require("path");
80401
80401
  var import_static = __toESM(require_static());
80402
80402
  var import_fs2 = require("fs");
80403
80403
  var import_os = require("os");
80404
- var createServer = (config) => {
80405
- const server = new fR(config);
80406
- server.app.get("/api/config", async (req, reply) => {
80407
- return await readConfigFile();
80408
- });
80409
- server.app.get("/api/transformers", async () => {
80410
- const transformers = server.app._server.transformerService.getAllTransformers();
80411
- const transformerList = Array.from(transformers.entries()).map(
80412
- ([name, transformer]) => ({
80413
- name,
80414
- endpoint: transformer.endPoint || null
80415
- })
80416
- );
80417
- return { transformers: transformerList };
80418
- });
80419
- server.app.post("/api/config", async (req, reply) => {
80420
- const newConfig = req.body;
80421
- const backupPath = await backupConfigFile();
80422
- if (backupPath) {
80423
- console.log(`Backed up existing configuration file to ${backupPath}`);
80424
- }
80425
- await writeConfigFile(newConfig);
80426
- return { success: true, message: "Config saved successfully" };
80427
- });
80428
- server.app.post("/api/restart", async (req, reply) => {
80429
- reply.send({ success: true, message: "Service restart initiated" });
80430
- setTimeout(() => {
80431
- const { spawn: spawn3 } = require("child_process");
80432
- spawn3(process.execPath, [process.argv[1], "restart"], {
80433
- detached: true,
80434
- stdio: "ignore"
80435
- });
80436
- }, 1e3);
80437
- });
80438
- server.app.register(import_static.default, {
80439
- root: (0, import_path2.join)(__dirname, "..", "dist"),
80440
- prefix: "/ui/",
80441
- maxAge: "1h"
80442
- });
80443
- server.app.get("/ui", async (_, reply) => {
80444
- return reply.redirect("/ui/");
80445
- });
80446
- server.app.get("/api/update/check", async (req, reply) => {
80447
- try {
80448
- const currentVersion = require_package3().version;
80449
- const { hasUpdate, latestVersion, changelog } = await checkForUpdates(currentVersion);
80450
- return {
80451
- hasUpdate,
80452
- latestVersion: hasUpdate ? latestVersion : void 0,
80453
- changelog: hasUpdate ? changelog : void 0
80454
- };
80455
- } catch (error) {
80456
- console.error("Failed to check for updates:", error);
80457
- reply.status(500).send({ error: "Failed to check for updates" });
80458
- }
80459
- });
80460
- server.app.post("/api/update/perform", async (req, reply) => {
80461
- try {
80462
- const accessLevel = req.accessLevel || "restricted";
80463
- if (accessLevel !== "full") {
80464
- reply.status(403).send("Full access required to perform updates");
80465
- return;
80466
- }
80467
- const result = await performUpdate();
80468
- return result;
80469
- } catch (error) {
80470
- console.error("Failed to perform update:", error);
80471
- reply.status(500).send({ error: "Failed to perform update" });
80472
- }
80473
- });
80474
- server.app.get("/api/logs/files", async (req, reply) => {
80475
- try {
80476
- const logDir = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs");
80477
- const logFiles = [];
80478
- if ((0, import_fs2.existsSync)(logDir)) {
80479
- const files = (0, import_fs2.readdirSync)(logDir);
80480
- for (const file of files) {
80481
- if (file.endsWith(".log")) {
80482
- const filePath = (0, import_path2.join)(logDir, file);
80483
- const stats = (0, import_fs2.statSync)(filePath);
80484
- logFiles.push({
80485
- name: file,
80486
- path: filePath,
80487
- size: stats.size,
80488
- lastModified: stats.mtime.toISOString()
80489
- });
80490
- }
80491
- }
80492
- logFiles.sort((a, b) => new Date(b.lastModified).getTime() - new Date(a.lastModified).getTime());
80493
- }
80494
- return logFiles;
80495
- } catch (error) {
80496
- console.error("Failed to get log files:", error);
80497
- reply.status(500).send({ error: "Failed to get log files" });
80498
- }
80499
- });
80500
- server.app.get("/api/logs", async (req, reply) => {
80501
- try {
80502
- const filePath = req.query.file;
80503
- let logFilePath;
80504
- if (filePath) {
80505
- logFilePath = filePath;
80506
- } else {
80507
- logFilePath = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
80508
- }
80509
- if (!(0, import_fs2.existsSync)(logFilePath)) {
80510
- return [];
80511
- }
80512
- const logContent = (0, import_fs2.readFileSync)(logFilePath, "utf8");
80513
- const logLines = logContent.split("\n").filter((line) => line.trim());
80514
- return logLines;
80515
- } catch (error) {
80516
- console.error("Failed to get logs:", error);
80517
- reply.status(500).send({ error: "Failed to get logs" });
80518
- }
80519
- });
80520
- server.app.delete("/api/logs", async (req, reply) => {
80521
- try {
80522
- const filePath = req.query.file;
80523
- let logFilePath;
80524
- if (filePath) {
80525
- logFilePath = filePath;
80526
- } else {
80527
- logFilePath = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
80528
- }
80529
- if ((0, import_fs2.existsSync)(logFilePath)) {
80530
- (0, import_fs2.writeFileSync)(logFilePath, "", "utf8");
80531
- }
80532
- return { success: true, message: "Logs cleared successfully" };
80533
- } catch (error) {
80534
- console.error("Failed to clear logs:", error);
80535
- reply.status(500).send({ error: "Failed to clear logs" });
80536
- }
80537
- });
80538
- return server;
80539
- };
80540
80404
 
80541
80405
  // src/utils/router.ts
80542
80406
  var import_tiktoken = __toESM(require_tiktoken());
@@ -80716,6 +80580,149 @@ var router = async (req, _res, context) => {
80716
80580
  return;
80717
80581
  };
80718
80582
 
80583
+ // src/server.ts
80584
+ var createServer = (config) => {
80585
+ const server = new fR(config);
80586
+ server.app.post("/v1/messages/count_tokens", async (req, reply) => {
80587
+ const { messages, tools, system } = req.body;
80588
+ const tokenCount = calculateTokenCount(messages, system, tools);
80589
+ return { "input_tokens": tokenCount };
80590
+ });
80591
+ server.app.get("/api/config", async (req, reply) => {
80592
+ return await readConfigFile();
80593
+ });
80594
+ server.app.get("/api/transformers", async () => {
80595
+ const transformers = server.app._server.transformerService.getAllTransformers();
80596
+ const transformerList = Array.from(transformers.entries()).map(
80597
+ ([name, transformer]) => ({
80598
+ name,
80599
+ endpoint: transformer.endPoint || null
80600
+ })
80601
+ );
80602
+ return { transformers: transformerList };
80603
+ });
80604
+ server.app.post("/api/config", async (req, reply) => {
80605
+ const newConfig = req.body;
80606
+ const backupPath = await backupConfigFile();
80607
+ if (backupPath) {
80608
+ console.log(`Backed up existing configuration file to ${backupPath}`);
80609
+ }
80610
+ await writeConfigFile(newConfig);
80611
+ return { success: true, message: "Config saved successfully" };
80612
+ });
80613
+ server.app.post("/api/restart", async (req, reply) => {
80614
+ reply.send({ success: true, message: "Service restart initiated" });
80615
+ setTimeout(() => {
80616
+ const { spawn: spawn3 } = require("child_process");
80617
+ spawn3(process.execPath, [process.argv[1], "restart"], {
80618
+ detached: true,
80619
+ stdio: "ignore"
80620
+ });
80621
+ }, 1e3);
80622
+ });
80623
+ server.app.register(import_static.default, {
80624
+ root: (0, import_path2.join)(__dirname, "..", "dist"),
80625
+ prefix: "/ui/",
80626
+ maxAge: "1h"
80627
+ });
80628
+ server.app.get("/ui", async (_, reply) => {
80629
+ return reply.redirect("/ui/");
80630
+ });
80631
+ server.app.get("/api/update/check", async (req, reply) => {
80632
+ try {
80633
+ const currentVersion = require_package3().version;
80634
+ const { hasUpdate, latestVersion, changelog } = await checkForUpdates(currentVersion);
80635
+ return {
80636
+ hasUpdate,
80637
+ latestVersion: hasUpdate ? latestVersion : void 0,
80638
+ changelog: hasUpdate ? changelog : void 0
80639
+ };
80640
+ } catch (error) {
80641
+ console.error("Failed to check for updates:", error);
80642
+ reply.status(500).send({ error: "Failed to check for updates" });
80643
+ }
80644
+ });
80645
+ server.app.post("/api/update/perform", async (req, reply) => {
80646
+ try {
80647
+ const accessLevel = req.accessLevel || "restricted";
80648
+ if (accessLevel !== "full") {
80649
+ reply.status(403).send("Full access required to perform updates");
80650
+ return;
80651
+ }
80652
+ const result = await performUpdate();
80653
+ return result;
80654
+ } catch (error) {
80655
+ console.error("Failed to perform update:", error);
80656
+ reply.status(500).send({ error: "Failed to perform update" });
80657
+ }
80658
+ });
80659
+ server.app.get("/api/logs/files", async (req, reply) => {
80660
+ try {
80661
+ const logDir = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs");
80662
+ const logFiles = [];
80663
+ if ((0, import_fs2.existsSync)(logDir)) {
80664
+ const files = (0, import_fs2.readdirSync)(logDir);
80665
+ for (const file of files) {
80666
+ if (file.endsWith(".log")) {
80667
+ const filePath = (0, import_path2.join)(logDir, file);
80668
+ const stats = (0, import_fs2.statSync)(filePath);
80669
+ logFiles.push({
80670
+ name: file,
80671
+ path: filePath,
80672
+ size: stats.size,
80673
+ lastModified: stats.mtime.toISOString()
80674
+ });
80675
+ }
80676
+ }
80677
+ logFiles.sort((a, b) => new Date(b.lastModified).getTime() - new Date(a.lastModified).getTime());
80678
+ }
80679
+ return logFiles;
80680
+ } catch (error) {
80681
+ console.error("Failed to get log files:", error);
80682
+ reply.status(500).send({ error: "Failed to get log files" });
80683
+ }
80684
+ });
80685
+ server.app.get("/api/logs", async (req, reply) => {
80686
+ try {
80687
+ const filePath = req.query.file;
80688
+ let logFilePath;
80689
+ if (filePath) {
80690
+ logFilePath = filePath;
80691
+ } else {
80692
+ logFilePath = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
80693
+ }
80694
+ if (!(0, import_fs2.existsSync)(logFilePath)) {
80695
+ return [];
80696
+ }
80697
+ const logContent = (0, import_fs2.readFileSync)(logFilePath, "utf8");
80698
+ const logLines = logContent.split("\n").filter((line) => line.trim());
80699
+ return logLines;
80700
+ } catch (error) {
80701
+ console.error("Failed to get logs:", error);
80702
+ reply.status(500).send({ error: "Failed to get logs" });
80703
+ }
80704
+ });
80705
+ server.app.delete("/api/logs", async (req, reply) => {
80706
+ try {
80707
+ const filePath = req.query.file;
80708
+ let logFilePath;
80709
+ if (filePath) {
80710
+ logFilePath = filePath;
80711
+ } else {
80712
+ logFilePath = (0, import_path2.join)((0, import_os.homedir)(), ".claude-code-router", "logs", "app.log");
80713
+ }
80714
+ if ((0, import_fs2.existsSync)(logFilePath)) {
80715
+ (0, import_fs2.writeFileSync)(logFilePath, "", "utf8");
80716
+ }
80717
+ return { success: true, message: "Logs cleared successfully" };
80718
+ } catch (error) {
80719
+ console.error("Failed to clear logs:", error);
80720
+ reply.status(500).send({ error: "Failed to clear logs" });
80721
+ }
80722
+ });
80723
+ return server;
80724
+ };
80725
+
80719
80726
  // src/middleware/auth.ts
80720
80727
  var apiKeyAuth = (config) => async (req, reply, done) => {
80721
80728
  if (["/", "/health"].includes(req.url) || req.url.startsWith("/ui")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@musistudio/claude-code-router",
3
- "version": "1.0.55",
3
+ "version": "1.0.56",
4
4
  "description": "Use Claude Code without an Anthropics account and route it to another LLM provider",
5
5
  "bin": {
6
6
  "ccr": "dist/cli.js"