120 lines
3.1 KiB
JavaScript
120 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
import { run } from "./index";
|
|
import { showStatus } from "./utils/status";
|
|
import { executeCodeCommand } from "./utils/codeCommand";
|
|
import { cleanupPidFile, isServiceRunning } from "./utils/processCheck";
|
|
import { version } from "../package.json";
|
|
import { spawn } from "child_process";
|
|
import { PID_FILE, REFERENCE_COUNT_FILE } from "./constants";
|
|
import { existsSync, readFileSync } from "fs";
|
|
|
|
const command = process.argv[2];
|
|
|
|
const HELP_TEXT = `
|
|
Usage: ccr [command]
|
|
|
|
Commands:
|
|
start Start service
|
|
stop Stop service
|
|
status Show service status
|
|
code Execute code command
|
|
-v, version Show version information
|
|
-h, help Show help information
|
|
|
|
Example:
|
|
ccr start
|
|
ccr code "Write a Hello World"
|
|
`;
|
|
|
|
async function waitForService(
|
|
timeout = 10000,
|
|
initialDelay = 1000
|
|
): Promise<boolean> {
|
|
// Wait for an initial period to let the service initialize
|
|
await new Promise((resolve) => setTimeout(resolve, initialDelay));
|
|
|
|
const startTime = Date.now();
|
|
while (Date.now() - startTime < timeout) {
|
|
if (isServiceRunning()) {
|
|
// Wait for an additional short period to ensure service is fully ready
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
return true;
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
async function main() {
|
|
switch (command) {
|
|
case "start":
|
|
run();
|
|
break;
|
|
case "stop":
|
|
try {
|
|
const pid = parseInt(readFileSync(PID_FILE, "utf-8"));
|
|
process.kill(pid);
|
|
cleanupPidFile();
|
|
if (existsSync(REFERENCE_COUNT_FILE)) {
|
|
try {
|
|
require("fs").unlinkSync(REFERENCE_COUNT_FILE);
|
|
} catch (e) {
|
|
// Ignore cleanup errors
|
|
}
|
|
}
|
|
console.log(
|
|
"claude code router service has been successfully stopped."
|
|
);
|
|
} catch (e) {
|
|
console.log(
|
|
"Failed to stop the service. It may have already been stopped."
|
|
);
|
|
cleanupPidFile();
|
|
}
|
|
break;
|
|
case "status":
|
|
showStatus();
|
|
break;
|
|
case "code":
|
|
if (!isServiceRunning()) {
|
|
console.log("Service not running, starting service...");
|
|
const startProcess = spawn("ccr", ["start"], {
|
|
detached: true,
|
|
stdio: "ignore",
|
|
});
|
|
|
|
startProcess.on("error", (error) => {
|
|
console.error("Failed to start service:", error);
|
|
process.exit(1);
|
|
});
|
|
|
|
startProcess.unref();
|
|
|
|
if (await waitForService()) {
|
|
executeCodeCommand(process.argv.slice(3));
|
|
} else {
|
|
console.error(
|
|
"Service startup timeout, please manually run `ccr start` to start the service"
|
|
);
|
|
process.exit(1);
|
|
}
|
|
} else {
|
|
executeCodeCommand(process.argv.slice(3));
|
|
}
|
|
break;
|
|
case "-v":
|
|
case "version":
|
|
console.log(`claude-code-router version: ${version}`);
|
|
break;
|
|
case "-h":
|
|
case "help":
|
|
console.log(HELP_TEXT);
|
|
break;
|
|
default:
|
|
console.log(HELP_TEXT);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main().catch(console.error);
|