@peterwangze/claude-trigger-router 1.0.2 → 1.0.3
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 +5 -3
- package/dist/cli.js +115 -22
- package/dist/cli.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,8 +30,8 @@ ctr setup
|
|
|
30
30
|
`ctr setup` 会:
|
|
31
31
|
|
|
32
32
|
- 优先检查当前配置是否可直接复用
|
|
33
|
-
- 检测旧版 `~/.ccr/config.yaml` 并优先提供迁移
|
|
34
|
-
-
|
|
33
|
+
- 检测旧版 `~/.ccr/config.yaml` 或 `~/.claude-code-router/config.yaml` 并优先提供迁移
|
|
34
|
+
- 在需要新建时,先确认接入方式与 provider 预设,再带出默认模型和默认模型 ID 供确认
|
|
35
35
|
- 只生成最小可用配置(`Models + Router.default`),高级路由稍后再补
|
|
36
36
|
- 保存配置后启动服务并进入 Claude Code
|
|
37
37
|
|
|
@@ -262,7 +262,7 @@ Models:
|
|
|
262
262
|
如果你还在使用旧的 `Providers + provider,model` 配置:
|
|
263
263
|
|
|
264
264
|
- 当前版本仍然兼容旧格式
|
|
265
|
-
- `ctr setup` 会优先尝试迁移旧 `ccr` 配置
|
|
265
|
+
- `ctr setup` 会优先尝试迁移旧 `ccr` / `claude-code-router` 配置
|
|
266
266
|
- 路由字段推荐逐步改成直接引用 `Models[].id`
|
|
267
267
|
|
|
268
268
|
迁移后的核心变化是:
|
|
@@ -279,6 +279,8 @@ Models:
|
|
|
279
279
|
```bash
|
|
280
280
|
ctr setup
|
|
281
281
|
ctr init
|
|
282
|
+
ctr version
|
|
283
|
+
ctr upgrade
|
|
282
284
|
ctr start
|
|
283
285
|
ctr start --daemon
|
|
284
286
|
ctr stop
|
package/dist/cli.js
CHANGED
|
@@ -5882,7 +5882,7 @@ function decideSetupBranch(input2) {
|
|
|
5882
5882
|
ensureNoLegacyAction(legacyConfigAction);
|
|
5883
5883
|
return { kind: "reuse_current" };
|
|
5884
5884
|
}
|
|
5885
|
-
if (currentConfigAction === "overwrite") {
|
|
5885
|
+
if (currentConfigAction === "overwrite" || currentConfigAction === "fresh") {
|
|
5886
5886
|
return ensureLegacyFlow(detection, legacyConfigAction);
|
|
5887
5887
|
}
|
|
5888
5888
|
return invalidAction();
|
|
@@ -6083,43 +6083,51 @@ function readStructuredConfigFile(filePath) {
|
|
|
6083
6083
|
}
|
|
6084
6084
|
return import_js_yaml.default.load(content);
|
|
6085
6085
|
}
|
|
6086
|
-
async function
|
|
6087
|
-
const
|
|
6088
|
-
const
|
|
6089
|
-
|
|
6086
|
+
async function readLegacyConfig(deps = {}) {
|
|
6087
|
+
const baseHomeDir = deps.homeDir || (0, import_os3.homedir)();
|
|
6088
|
+
const exists = deps.exists || import_fs6.existsSync;
|
|
6089
|
+
const readConfig = deps.readConfig || readStructuredConfigFile;
|
|
6090
|
+
const overridePath = process.env.CTR_SETUP_LEGACY_CONFIG_PATH;
|
|
6091
|
+
const candidatePaths = overridePath ? [overridePath] : [
|
|
6092
|
+
(0, import_path6.join)(baseHomeDir, ".ccr", "config.yaml"),
|
|
6093
|
+
(0, import_path6.join)(baseHomeDir, ".claude-code-router", "config.yaml")
|
|
6094
|
+
];
|
|
6095
|
+
const legacyPath = candidatePaths.find((filePath) => exists(filePath));
|
|
6096
|
+
if (!legacyPath) {
|
|
6090
6097
|
return { kind: "missing" };
|
|
6091
6098
|
}
|
|
6092
6099
|
try {
|
|
6093
6100
|
return {
|
|
6094
6101
|
kind: "found",
|
|
6095
|
-
path:
|
|
6096
|
-
|
|
6097
|
-
config: readStructuredConfigFile(currentPath) ?? {}
|
|
6102
|
+
path: legacyPath,
|
|
6103
|
+
config: readConfig(legacyPath)
|
|
6098
6104
|
};
|
|
6099
6105
|
} catch (error) {
|
|
6100
6106
|
return {
|
|
6101
|
-
kind: "
|
|
6102
|
-
path:
|
|
6103
|
-
format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
|
|
6107
|
+
kind: "read_error",
|
|
6108
|
+
path: legacyPath,
|
|
6104
6109
|
error: error instanceof Error ? error.message : String(error)
|
|
6105
6110
|
};
|
|
6106
6111
|
}
|
|
6107
6112
|
}
|
|
6108
|
-
async function
|
|
6109
|
-
const
|
|
6110
|
-
|
|
6113
|
+
async function readCurrentConfig() {
|
|
6114
|
+
const candidates = [CONFIG_FILE, CONFIG_FILE_YML, CONFIG_FILE_JSON];
|
|
6115
|
+
const currentPath = candidates.find((filePath) => (0, import_fs6.existsSync)(filePath));
|
|
6116
|
+
if (!currentPath) {
|
|
6111
6117
|
return { kind: "missing" };
|
|
6112
6118
|
}
|
|
6113
6119
|
try {
|
|
6114
6120
|
return {
|
|
6115
6121
|
kind: "found",
|
|
6116
|
-
path:
|
|
6117
|
-
|
|
6122
|
+
path: currentPath,
|
|
6123
|
+
format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
|
|
6124
|
+
config: readStructuredConfigFile(currentPath) ?? {}
|
|
6118
6125
|
};
|
|
6119
6126
|
} catch (error) {
|
|
6120
6127
|
return {
|
|
6121
|
-
kind: "
|
|
6122
|
-
path:
|
|
6128
|
+
kind: "parse_error",
|
|
6129
|
+
path: currentPath,
|
|
6130
|
+
format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
|
|
6123
6131
|
error: error instanceof Error ? error.message : String(error)
|
|
6124
6132
|
};
|
|
6125
6133
|
}
|
|
@@ -6161,7 +6169,10 @@ function mapValidCurrentConfigChoice(choice) {
|
|
|
6161
6169
|
if (choice === "overwrite" || choice === "\u68C0\u67E5\u5E76\u8C03\u6574\u5F53\u524D\u914D\u7F6E") {
|
|
6162
6170
|
return "overwrite";
|
|
6163
6171
|
}
|
|
6164
|
-
if (choice === "
|
|
6172
|
+
if (choice === "fresh" || choice === "\u653E\u5F03\u5F53\u524D\u914D\u7F6E\uFF0C\u91CD\u65B0\u5F00\u59CB") {
|
|
6173
|
+
return "fresh";
|
|
6174
|
+
}
|
|
6175
|
+
if (choice === "cancel") {
|
|
6165
6176
|
return "cancel";
|
|
6166
6177
|
}
|
|
6167
6178
|
throw new Error("invalid current config action");
|
|
@@ -6276,8 +6287,15 @@ function toDraftFromConfig(config) {
|
|
|
6276
6287
|
}
|
|
6277
6288
|
};
|
|
6278
6289
|
}
|
|
6290
|
+
function toSuggestedModelId(providerName, model, preset) {
|
|
6291
|
+
const presetDefinition = getProviderPreset(preset);
|
|
6292
|
+
if (presetDefinition?.suggested_id) {
|
|
6293
|
+
return presetDefinition.suggested_id;
|
|
6294
|
+
}
|
|
6295
|
+
const source = model || providerName || "model";
|
|
6296
|
+
return source.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "model";
|
|
6297
|
+
}
|
|
6279
6298
|
async function buildFreshConfig(io) {
|
|
6280
|
-
const modelId = await io.input("\u9ED8\u8BA4\u6A21\u578B ID");
|
|
6281
6299
|
const connectMode = await io.choose("\u8FD9\u4E2A\u6A21\u578B\u63A5\u5230\u54EA\u91CC\uFF1F", ["\u4F7F\u7528\u5E38\u89C1\u63A5\u5165\u6A21\u677F", "\u624B\u52A8\u586B\u5199\u63A5\u53E3"]);
|
|
6282
6300
|
let preset = "custom";
|
|
6283
6301
|
let providerName = "provider";
|
|
@@ -6292,7 +6310,9 @@ async function buildFreshConfig(io) {
|
|
|
6292
6310
|
apiBaseUrl = await io.input("API Base URL");
|
|
6293
6311
|
}
|
|
6294
6312
|
const apiKey = await io.input("API Key");
|
|
6295
|
-
const
|
|
6313
|
+
const presetDefinition = getProviderPreset(preset);
|
|
6314
|
+
const model = await io.input("\u4E0A\u6E38\u6A21\u578B\u540D", presetDefinition?.default_model ?? "");
|
|
6315
|
+
const modelId = await io.input("\u9ED8\u8BA4\u6A21\u578B ID", toSuggestedModelId(providerName, model, preset));
|
|
6296
6316
|
const capabilityMode = await io.choose("\u662F\u5426\u914D\u7F6E capability \u63D0\u793A", ["\u4FDD\u6301\u9ED8\u8BA4", "\u914D\u7F6E capability \u63D0\u793A"]);
|
|
6297
6317
|
const draft = buildMinimalConfig({
|
|
6298
6318
|
providers: [
|
|
@@ -6494,6 +6514,14 @@ __export(cli_exports, {
|
|
|
6494
6514
|
runClaudeCode: () => runClaudeCode
|
|
6495
6515
|
});
|
|
6496
6516
|
module.exports = __toCommonJS(cli_exports);
|
|
6517
|
+
function getPackageInfo() {
|
|
6518
|
+
const content = (0, import_fs7.readFileSync)(PACKAGE_JSON_PATH, "utf-8");
|
|
6519
|
+
const pkg = JSON.parse(content);
|
|
6520
|
+
return {
|
|
6521
|
+
name: pkg.name ?? "@peterwangze/claude-trigger-router",
|
|
6522
|
+
version: pkg.version ?? "unknown"
|
|
6523
|
+
};
|
|
6524
|
+
}
|
|
6497
6525
|
function getArgs() {
|
|
6498
6526
|
return process.argv.slice(2);
|
|
6499
6527
|
}
|
|
@@ -6549,6 +6577,8 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
|
|
|
6549
6577
|
stop \u505C\u6B62\u540E\u53F0\u670D\u52A1
|
|
6550
6578
|
restart \u91CD\u542F\u540E\u53F0\u670D\u52A1
|
|
6551
6579
|
status \u67E5\u770B\u670D\u52A1\u8FD0\u884C\u72B6\u6001\uFF08PID\u3001\u7AEF\u53E3\u3001\u542F\u52A8\u65F6\u95F4\uFF09
|
|
6580
|
+
version \u67E5\u770B\u5F53\u524D\u5B89\u88C5\u7248\u672C\u4E0E\u5305\u4FE1\u606F
|
|
6581
|
+
upgrade \u67E5\u770B\u5347\u7EA7\u5230\u6700\u65B0 npm \u7248\u672C\u7684\u6307\u5F15
|
|
6552
6582
|
code \u901A\u8FC7\u8DEF\u7531\u5668\u8FD0\u884C Claude Code\uFF08\u9700\u5148\u542F\u52A8\u670D\u52A1\uFF09
|
|
6553
6583
|
ui \u6253\u5F00\u7BA1\u7406 API \u8BF4\u660E\u9875\uFF08Web UI \u5F00\u53D1\u4E2D\uFF09
|
|
6554
6584
|
help \u663E\u793A\u6B64\u5E2E\u52A9\u4FE1\u606F
|
|
@@ -6561,6 +6591,8 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
|
|
|
6561
6591
|
\u4F7F\u7528\u793A\u4F8B\uFF1A
|
|
6562
6592
|
ctr setup # \u590D\u7528\u5F53\u524D\u914D\u7F6E / \u8FC1\u79FB\u65E7\u914D\u7F6E / \u65B0\u5EFA\u6700\u5C0F\u914D\u7F6E
|
|
6563
6593
|
ctr init # \u521D\u59CB\u5316\u6700\u5C0F\u914D\u7F6E\u6A21\u677F
|
|
6594
|
+
ctr version # \u67E5\u770B\u5F53\u524D\u5B89\u88C5\u7248\u672C
|
|
6595
|
+
ctr upgrade # \u67E5\u770B\u5347\u7EA7\u5230\u6700\u65B0\u7248\u672C\u7684\u547D\u4EE4
|
|
6564
6596
|
ctr start # \u524D\u53F0\u542F\u52A8\uFF08\u63A8\u8350\u9996\u6B21\u4F7F\u7528\uFF0C\u4FBF\u4E8E\u67E5\u770B\u65E5\u5FD7\uFF09
|
|
6565
6597
|
ctr start --daemon # \u540E\u53F0\u542F\u52A8
|
|
6566
6598
|
ctr status # \u67E5\u770B\u670D\u52A1\u72B6\u6001
|
|
@@ -6577,6 +6609,58 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
|
|
|
6577
6609
|
\u66F4\u591A\u4FE1\u606F\uFF1Ahttps://github.com/peterwangze/claude-trigger-router
|
|
6578
6610
|
`);
|
|
6579
6611
|
}
|
|
6612
|
+
async function getLatestPackageVersion(timeoutMs = 1500) {
|
|
6613
|
+
try {
|
|
6614
|
+
const response = await fetch(PACKAGE_REGISTRY_LATEST_URL, {
|
|
6615
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
6616
|
+
});
|
|
6617
|
+
if (!response.ok) {
|
|
6618
|
+
return null;
|
|
6619
|
+
}
|
|
6620
|
+
const payload = await response.json();
|
|
6621
|
+
return typeof payload.version === "string" ? payload.version : null;
|
|
6622
|
+
} catch {
|
|
6623
|
+
return null;
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
function isNewerVersion(current, latest) {
|
|
6627
|
+
const currentParts = current.split(".").map((part) => Number.parseInt(part, 10));
|
|
6628
|
+
const latestParts = latest.split(".").map((part) => Number.parseInt(part, 10));
|
|
6629
|
+
const length = Math.max(currentParts.length, latestParts.length);
|
|
6630
|
+
for (let index = 0; index < length; index += 1) {
|
|
6631
|
+
const currentValue = Number.isFinite(currentParts[index]) ? currentParts[index] : 0;
|
|
6632
|
+
const latestValue = Number.isFinite(latestParts[index]) ? latestParts[index] : 0;
|
|
6633
|
+
if (latestValue > currentValue) {
|
|
6634
|
+
return true;
|
|
6635
|
+
}
|
|
6636
|
+
if (latestValue < currentValue) {
|
|
6637
|
+
return false;
|
|
6638
|
+
}
|
|
6639
|
+
}
|
|
6640
|
+
return false;
|
|
6641
|
+
}
|
|
6642
|
+
async function printVersion() {
|
|
6643
|
+
const pkg = getPackageInfo();
|
|
6644
|
+
const latestVersion = await getLatestPackageVersion();
|
|
6645
|
+
console.log(`Package: ${pkg.name}`);
|
|
6646
|
+
console.log(`Version: ${pkg.version}`);
|
|
6647
|
+
console.log(`Latest: ${latestVersion ?? "unavailable"}`);
|
|
6648
|
+
if (latestVersion && isNewerVersion(pkg.version, latestVersion)) {
|
|
6649
|
+
console.log(`Upgrade: npm install -g ${pkg.name}@latest`);
|
|
6650
|
+
}
|
|
6651
|
+
console.log(`NPM: ${PACKAGE_PAGE_URL}`);
|
|
6652
|
+
}
|
|
6653
|
+
function printUpgradeGuidance() {
|
|
6654
|
+
const pkg = getPackageInfo();
|
|
6655
|
+
console.log(`\u5F53\u524D\u5B89\u88C5\u7248\u672C\uFF1A${pkg.version}`);
|
|
6656
|
+
console.log(`\u5305\u540D\uFF1A${pkg.name}`);
|
|
6657
|
+
console.log("\u5347\u7EA7\u5230\u6700\u65B0\u7248\u672C\uFF1A");
|
|
6658
|
+
console.log(` npm install -g ${pkg.name}@latest`);
|
|
6659
|
+
console.log("\u8BF7\u5728\u5F53\u524D ctr \u8FDB\u7A0B\u5916\u6267\u884C\u5347\u7EA7\u547D\u4EE4\uFF0C\u907F\u514D\u81EA\u5347\u7EA7\u65F6\u5360\u7528\u5F53\u524D\u6587\u4EF6\u3002");
|
|
6660
|
+
console.log("\u5982\u679C\u4F60\u6700\u521D\u662F\u901A\u8FC7 GitHub \u6E90\u5B89\u88C5\uFF0C\u8BF7\u7EE7\u7EED\u4F7F\u7528\u539F\u5B89\u88C5\u6765\u6E90\uFF0C\u5F53\u524D\u547D\u4EE4\u4E0D\u4F1A\u81EA\u52A8\u5207\u6362\u6765\u6E90\u3002");
|
|
6661
|
+
console.log("\u5168\u5C40\u5B89\u88C5\u5728\u67D0\u4E9B\u73AF\u5883\u4E0B\u53EF\u80FD\u9700\u8981\u7BA1\u7406\u5458/root \u6743\u9650\u3002");
|
|
6662
|
+
console.log(`NPM: ${PACKAGE_PAGE_URL}`);
|
|
6663
|
+
}
|
|
6580
6664
|
function initConfig2() {
|
|
6581
6665
|
const force = hasArg("--force");
|
|
6582
6666
|
const existingConfig = [CONFIG_FILE, CONFIG_FILE_YML, CONFIG_FILE_JSON].find(import_fs7.existsSync);
|
|
@@ -6763,6 +6847,12 @@ async function main() {
|
|
|
6763
6847
|
case "status":
|
|
6764
6848
|
showStatus();
|
|
6765
6849
|
break;
|
|
6850
|
+
case "version":
|
|
6851
|
+
await printVersion();
|
|
6852
|
+
break;
|
|
6853
|
+
case "upgrade":
|
|
6854
|
+
printUpgradeGuidance();
|
|
6855
|
+
break;
|
|
6766
6856
|
case "restart":
|
|
6767
6857
|
restartService();
|
|
6768
6858
|
break;
|
|
@@ -6785,7 +6875,7 @@ async function main() {
|
|
|
6785
6875
|
process.exit(command ? 1 : 0);
|
|
6786
6876
|
}
|
|
6787
6877
|
}
|
|
6788
|
-
var import_child_process2, import_path7, import_openurl, import_fs7;
|
|
6878
|
+
var import_child_process2, import_path7, import_openurl, import_fs7, PACKAGE_JSON_PATH, PACKAGE_PAGE_URL, PACKAGE_REGISTRY_LATEST_URL;
|
|
6789
6879
|
var init_cli = __esm({
|
|
6790
6880
|
"src/cli.ts"() {
|
|
6791
6881
|
import_child_process2 = require("child_process");
|
|
@@ -6797,6 +6887,9 @@ var init_cli = __esm({
|
|
|
6797
6887
|
init_constants();
|
|
6798
6888
|
init_service_health();
|
|
6799
6889
|
init_setup2();
|
|
6890
|
+
PACKAGE_JSON_PATH = (0, import_path7.join)(__dirname, "..", "package.json");
|
|
6891
|
+
PACKAGE_PAGE_URL = "https://www.npmjs.com/package/@peterwangze/claude-trigger-router";
|
|
6892
|
+
PACKAGE_REGISTRY_LATEST_URL = "https://registry.npmjs.org/@peterwangze%2Fclaude-trigger-router/latest";
|
|
6800
6893
|
if (process.env.CTR_SKIP_MAIN !== "1") {
|
|
6801
6894
|
main().catch((error) => {
|
|
6802
6895
|
console.error("Error:", error);
|