release v1.0.27 to fix some bugs and enhance tools

This commit is contained in:
musistudio
2025-07-25 17:17:14 +08:00
parent 202402a123
commit 179bab605e
4 changed files with 72 additions and 30 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@musistudio/claude-code-router", "name": "@musistudio/claude-code-router",
"version": "1.0.26", "version": "1.0.27",
"description": "Use Claude Code without an Anthropics account and route it to another LLM provider", "description": "Use Claude Code without an Anthropics account and route it to another LLM provider",
"bin": { "bin": {
"ccr": "./dist/cli.js" "ccr": "./dist/cli.js"
@@ -19,8 +19,9 @@
"author": "musistudio", "author": "musistudio",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@musistudio/llms": "^1.0.12", "@musistudio/llms": "^1.0.14",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"json5": "^2.2.3",
"tiktoken": "^1.0.21", "tiktoken": "^1.0.21",
"uuid": "^11.1.0" "uuid": "^11.1.0"
}, },

21
pnpm-lock.yaml generated
View File

@@ -9,11 +9,14 @@ importers:
.: .:
dependencies: dependencies:
'@musistudio/llms': '@musistudio/llms':
specifier: ^1.0.12 specifier: ^1.0.14
version: 1.0.12(ws@8.18.3)(zod@3.25.67) version: 1.0.14(ws@8.18.3)(zod@3.25.67)
dotenv: dotenv:
specifier: ^16.4.7 specifier: ^16.4.7
version: 16.6.1 version: 16.6.1
json5:
specifier: ^2.2.3
version: 2.2.3
tiktoken: tiktoken:
specifier: ^1.0.21 specifier: ^1.0.21
version: 1.0.21 version: 1.0.21
@@ -223,8 +226,8 @@ packages:
'@modelcontextprotocol/sdk': '@modelcontextprotocol/sdk':
optional: true optional: true
'@musistudio/llms@1.0.12': '@musistudio/llms@1.0.14':
resolution: {integrity: sha512-5sRIrt8UgXDLqim1xZrnMxugUW2m6zopXMQ+wF5Px20hH06aLO0zdT3Gyq78IKJZ+Xupkj+h1FooCAtWl+6bLw==} resolution: {integrity: sha512-56+i7hAmdx4QUFBD5ey0EbWPlzQ882d9PCZB1Ky5mvMt5LLFx5x2RzfiJo0LWdvEInfPRAIufgwt8lISyApOUQ==}
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
@@ -445,6 +448,11 @@ packages:
json-schema-traverse@1.0.0: json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
hasBin: true
jwa@2.0.1: jwa@2.0.1:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
@@ -824,13 +832,14 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
'@musistudio/llms@1.0.12(ws@8.18.3)(zod@3.25.67)': '@musistudio/llms@1.0.14(ws@8.18.3)(zod@3.25.67)':
dependencies: dependencies:
'@anthropic-ai/sdk': 0.54.0 '@anthropic-ai/sdk': 0.54.0
'@fastify/cors': 11.0.1 '@fastify/cors': 11.0.1
'@google/genai': 1.8.0 '@google/genai': 1.8.0
dotenv: 16.6.1 dotenv: 16.6.1
fastify: 5.4.0 fastify: 5.4.0
json5: 2.2.3
openai: 5.8.2(ws@8.18.3)(zod@3.25.67) openai: 5.8.2(ws@8.18.3)(zod@3.25.67)
undici: 7.11.0 undici: 7.11.0
uuid: 11.1.0 uuid: 11.1.0
@@ -1115,6 +1124,8 @@ snapshots:
json-schema-traverse@1.0.0: {} json-schema-traverse@1.0.0: {}
json5@2.2.3: {}
jwa@2.0.1: jwa@2.0.1:
dependencies: dependencies:
buffer-equal-constant-time: 1.0.1 buffer-equal-constant-time: 1.0.1

View File

@@ -83,14 +83,26 @@ async function main() {
const cliPath = join(__dirname, "cli.js"); const cliPath = join(__dirname, "cli.js");
const startProcess = spawn("node", [cliPath, "start"], { const startProcess = spawn("node", [cliPath, "start"], {
detached: true, detached: true,
stdio: "ignore", stdio: ["ignore", "pipe", "pipe"],
});
let errorMessage = "";
startProcess.stderr?.on("data", (data) => {
errorMessage += data.toString();
}); });
startProcess.on("error", (error) => { startProcess.on("error", (error) => {
console.error("Failed to start service:", error); console.error("Failed to start service:", error.message);
process.exit(1); process.exit(1);
}); });
startProcess.on("close", (code) => {
if (code !== 0 && errorMessage) {
console.error("Failed to start service:", errorMessage.trim());
process.exit(1);
}
});
startProcess.unref(); startProcess.unref();
if (await waitForService()) { if (await waitForService()) {

View File

@@ -1,5 +1,6 @@
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import readline from "node:readline"; import readline from "node:readline";
import JSON5 from "json5";
import { import {
CONFIG_FILE, CONFIG_FILE,
DEFAULT_CONFIG, DEFAULT_CONFIG,
@@ -45,8 +46,18 @@ const confirm = async (query: string): Promise<boolean> => {
export const readConfigFile = async () => { export const readConfigFile = async () => {
try { try {
const config = await fs.readFile(CONFIG_FILE, "utf-8"); const config = await fs.readFile(CONFIG_FILE, "utf-8");
return JSON.parse(config); try {
} catch { // Try to parse with JSON5 first (which also supports standard JSON)
return JSON5.parse(config);
} catch (parseError) {
console.error(`Failed to parse config file at ${CONFIG_FILE}`);
console.error("Error details:", (parseError as Error).message);
console.error("Please check your config file syntax.");
process.exit(1);
}
} catch (readError: any) {
if (readError.code === "ENOENT") {
// Config file doesn't exist, prompt user for initial setup
const name = await question("Enter Provider Name: "); const name = await question("Enter Provider Name: ");
const APIKEY = await question("Enter Provider API KEY: "); const APIKEY = await question("Enter Provider API KEY: ");
const baseUrl = await question("Enter Provider URL: "); const baseUrl = await question("Enter Provider URL: ");
@@ -66,12 +77,19 @@ export const readConfigFile = async () => {
}); });
await writeConfigFile(config); await writeConfigFile(config);
return config; return config;
} else {
console.error(`Failed to read config file at ${CONFIG_FILE}`);
console.error("Error details:", readError.message);
process.exit(1);
}
} }
}; };
export const writeConfigFile = async (config: any) => { export const writeConfigFile = async (config: any) => {
await ensureDir(HOME_DIR); await ensureDir(HOME_DIR);
await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2)); // Add a comment to indicate JSON5 support
const configWithComment = `// This config file supports JSON5 format (comments, trailing commas, etc.)\n${JSON5.stringify(config, null, 2)}`;
await fs.writeFile(CONFIG_FILE, configWithComment);
}; };
export const initConfig = async () => { export const initConfig = async () => {