@peterwangze/claude-trigger-router 1.0.1 → 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/dist/cli.js CHANGED
@@ -5755,10 +5755,11 @@ function getProviderPreset2(key) {
5755
5755
  };
5756
5756
  }
5757
5757
  function buildMinimalConfig(input2) {
5758
- const models = input2.providers.map((p) => {
5758
+ const providers = input2.providers;
5759
+ const models = providers.map((p) => {
5759
5760
  const preset = p.preset ? getProviderPreset2(p.preset) : void 0;
5760
5761
  const modelDraft = {
5761
- id: p.name,
5762
+ id: p.model_id?.trim() || p.name,
5762
5763
  key: p.api_key,
5763
5764
  api_key: p.api_key,
5764
5765
  model: p.models[0] ?? "",
@@ -5881,7 +5882,7 @@ function decideSetupBranch(input2) {
5881
5882
  ensureNoLegacyAction(legacyConfigAction);
5882
5883
  return { kind: "reuse_current" };
5883
5884
  }
5884
- if (currentConfigAction === "overwrite") {
5885
+ if (currentConfigAction === "overwrite" || currentConfigAction === "fresh") {
5885
5886
  return ensureLegacyFlow(detection, legacyConfigAction);
5886
5887
  }
5887
5888
  return invalidAction();
@@ -6082,43 +6083,51 @@ function readStructuredConfigFile(filePath) {
6082
6083
  }
6083
6084
  return import_js_yaml.default.load(content);
6084
6085
  }
6085
- async function readCurrentConfig() {
6086
- const candidates = [CONFIG_FILE, CONFIG_FILE_YML, CONFIG_FILE_JSON];
6087
- const currentPath = candidates.find((filePath) => (0, import_fs6.existsSync)(filePath));
6088
- if (!currentPath) {
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) {
6089
6097
  return { kind: "missing" };
6090
6098
  }
6091
6099
  try {
6092
6100
  return {
6093
6101
  kind: "found",
6094
- path: currentPath,
6095
- format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
6096
- config: readStructuredConfigFile(currentPath) ?? {}
6102
+ path: legacyPath,
6103
+ config: readConfig(legacyPath)
6097
6104
  };
6098
6105
  } catch (error) {
6099
6106
  return {
6100
- kind: "parse_error",
6101
- path: currentPath,
6102
- format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
6107
+ kind: "read_error",
6108
+ path: legacyPath,
6103
6109
  error: error instanceof Error ? error.message : String(error)
6104
6110
  };
6105
6111
  }
6106
6112
  }
6107
- async function readLegacyConfig() {
6108
- const legacyPath = process.env.CTR_SETUP_LEGACY_CONFIG_PATH || (0, import_path6.join)((0, import_os3.homedir)(), ".ccr", "config.yaml");
6109
- if (!(0, import_fs6.existsSync)(legacyPath)) {
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) {
6110
6117
  return { kind: "missing" };
6111
6118
  }
6112
6119
  try {
6113
6120
  return {
6114
6121
  kind: "found",
6115
- path: legacyPath,
6116
- config: readStructuredConfigFile(legacyPath)
6122
+ path: currentPath,
6123
+ format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
6124
+ config: readStructuredConfigFile(currentPath) ?? {}
6117
6125
  };
6118
6126
  } catch (error) {
6119
6127
  return {
6120
- kind: "read_error",
6121
- path: legacyPath,
6128
+ kind: "parse_error",
6129
+ path: currentPath,
6130
+ format: currentPath.endsWith(".json") ? "json" : currentPath.endsWith(".yml") ? "yml" : "yaml",
6122
6131
  error: error instanceof Error ? error.message : String(error)
6123
6132
  };
6124
6133
  }
@@ -6153,6 +6162,30 @@ function mapConfigErrorsToRepairFields(errors) {
6153
6162
  const fields = getRepairFields(errors);
6154
6163
  return fields.includes("manualReview") ? { mode: "manualReview", fields } : { mode: "repair", fields };
6155
6164
  }
6165
+ function mapValidCurrentConfigChoice(choice) {
6166
+ if (choice === "reuse" || choice === "\u76F4\u63A5\u4F7F\u7528\u5F53\u524D\u914D\u7F6E\uFF08\u63A8\u8350\uFF09") {
6167
+ return "reuse";
6168
+ }
6169
+ if (choice === "overwrite" || choice === "\u68C0\u67E5\u5E76\u8C03\u6574\u5F53\u524D\u914D\u7F6E") {
6170
+ return "overwrite";
6171
+ }
6172
+ if (choice === "fresh" || choice === "\u653E\u5F03\u5F53\u524D\u914D\u7F6E\uFF0C\u91CD\u65B0\u5F00\u59CB") {
6173
+ return "fresh";
6174
+ }
6175
+ if (choice === "cancel") {
6176
+ return "cancel";
6177
+ }
6178
+ throw new Error("invalid current config action");
6179
+ }
6180
+ function mapLegacyConfigChoice(choice) {
6181
+ if (choice === "migrate" || choice === "\u8FC1\u79FB\u65E7\u914D\u7F6E\uFF08\u63A8\u8350\uFF09") {
6182
+ return "migrate";
6183
+ }
6184
+ if (choice === "skip" || choice === "\u8DF3\u8FC7\u8FC1\u79FB\uFF0C\u624B\u52A8\u65B0\u5EFA") {
6185
+ return "skip";
6186
+ }
6187
+ throw new Error("invalid legacy config action");
6188
+ }
6156
6189
  function toCapabilityBoolean(choice) {
6157
6190
  if (choice === "\u652F\u6301") {
6158
6191
  return true;
@@ -6254,25 +6287,45 @@ function toDraftFromConfig(config) {
6254
6287
  }
6255
6288
  };
6256
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
+ }
6257
6298
  async function buildFreshConfig(io) {
6258
- const presetOptions = listProviderPresetKeys("setup");
6259
- const preset = await io.choose("\u9009\u62E9 provider \u9884\u8BBE", presetOptions);
6260
- const providerName = await io.input("Provider \u540D\u79F0", preset);
6261
- const apiBaseUrl = preset === "custom" ? await io.input("API Base URL") : await io.input("API Base URL\uFF08\u7559\u7A7A\u4F7F\u7528\u9884\u8BBE\uFF09", "");
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"]);
6300
+ let preset = "custom";
6301
+ let providerName = "provider";
6302
+ let apiBaseUrl = "";
6303
+ if (connectMode === "\u4F7F\u7528\u5E38\u89C1\u63A5\u5165\u6A21\u677F") {
6304
+ const presetOptions = listProviderPresetKeys("setup");
6305
+ preset = await io.choose("\u9009\u62E9 provider \u9884\u8BBE", presetOptions);
6306
+ providerName = await io.input("Provider \u540D\u79F0", preset);
6307
+ apiBaseUrl = preset === "custom" ? await io.input("API Base URL") : await io.input("API Base URL\uFF08\u7559\u7A7A\u4F7F\u7528\u9884\u8BBE\uFF09", "");
6308
+ } else {
6309
+ providerName = await io.input("Provider \u540D\u79F0", "provider");
6310
+ apiBaseUrl = await io.input("API Base URL");
6311
+ }
6262
6312
  const apiKey = await io.input("API Key");
6263
- const model = await io.input("\u9ED8\u8BA4\u6A21\u578B");
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));
6264
6316
  const capabilityMode = await io.choose("\u662F\u5426\u914D\u7F6E capability \u63D0\u793A", ["\u4FDD\u6301\u9ED8\u8BA4", "\u914D\u7F6E capability \u63D0\u793A"]);
6265
6317
  const draft = buildMinimalConfig({
6266
6318
  providers: [
6267
6319
  {
6268
6320
  name: providerName,
6321
+ model_id: modelId,
6269
6322
  api_key: apiKey,
6270
6323
  models: [model],
6271
6324
  preset,
6272
6325
  api_base_url: apiBaseUrl
6273
6326
  }
6274
6327
  ],
6275
- defaultModel: providerName
6328
+ defaultModel: modelId
6276
6329
  });
6277
6330
  if (capabilityMode === "\u914D\u7F6E capability \u63D0\u793A" && draft.Models?.[0]) {
6278
6331
  await promptCapabilityMetadataForDraft(draft, io);
@@ -6350,11 +6403,17 @@ async function runSetupCli(customDeps) {
6350
6403
  return "create";
6351
6404
  }
6352
6405
  if (currentConfig.kind === "valid") {
6353
- deps.io.info("\u68C0\u6D4B\u5230\u73B0\u6709\u53EF\u7528\u914D\u7F6E\u3002");
6406
+ deps.io.info("\u68C0\u6D4B\u5230\u5F53\u524D claude-trigger-router \u914D\u7F6E\u5DF2\u53EF\u7528\u3002");
6354
6407
  if (currentConfig.warnings.length > 0) {
6355
6408
  deps.io.info(`\u5F53\u524D\u914D\u7F6E\u63D0\u793A\uFF1A${currentConfig.warnings.join("; ")}`);
6356
6409
  }
6357
- return await deps.io.choose("\u9009\u62E9\u4E0B\u4E00\u6B65", ["reuse", "overwrite", "cancel"]);
6410
+ return mapValidCurrentConfigChoice(
6411
+ await deps.io.choose("\u4F60\u60F3\u76F4\u63A5\u4F7F\u7528\u5B83\uFF0C\u8FD8\u662F\u91CD\u65B0\u8C03\u6574\uFF1F", [
6412
+ "\u76F4\u63A5\u4F7F\u7528\u5F53\u524D\u914D\u7F6E\uFF08\u63A8\u8350\uFF09",
6413
+ "\u68C0\u67E5\u5E76\u8C03\u6574\u5F53\u524D\u914D\u7F6E",
6414
+ "\u653E\u5F03\u5F53\u524D\u914D\u7F6E\uFF0C\u91CD\u65B0\u5F00\u59CB"
6415
+ ])
6416
+ );
6358
6417
  }
6359
6418
  if (currentConfig.kind === "invalid") {
6360
6419
  deps.io.info(`\u5F53\u524D\u914D\u7F6E\u6821\u9A8C\u5931\u8D25\uFF1A${currentConfig.errors.join("; ")}`);
@@ -6368,7 +6427,12 @@ async function runSetupCli(customDeps) {
6368
6427
  },
6369
6428
  chooseLegacyConfigAction: async ({ legacyConfig }) => {
6370
6429
  if (legacyConfig.kind === "found") {
6371
- return await deps.io.choose("\u68C0\u6D4B\u5230\u65E7 ccr \u914D\u7F6E\uFF0C\u662F\u5426\u8FC1\u79FB\uFF1F", ["migrate", "skip"]);
6430
+ return mapLegacyConfigChoice(
6431
+ await deps.io.choose("\u68C0\u6D4B\u5230\u65E7 claude-code-router \u914D\u7F6E\u3002\u662F\u5426\u8FC1\u79FB\u4E3A\u5F53\u524D\u63A8\u8350\u914D\u7F6E\uFF1F", [
6432
+ "\u8FC1\u79FB\u65E7\u914D\u7F6E\uFF08\u63A8\u8350\uFF09",
6433
+ "\u8DF3\u8FC7\u8FC1\u79FB\uFF0C\u624B\u52A8\u65B0\u5EFA"
6434
+ ])
6435
+ );
6372
6436
  }
6373
6437
  if (legacyConfig.kind === "read_error") {
6374
6438
  deps.io.info(`\u65E7 ccr \u914D\u7F6E\u8BFB\u53D6\u5931\u8D25\uFF1A${legacyConfig.error}`);
@@ -6450,6 +6514,14 @@ __export(cli_exports, {
6450
6514
  runClaudeCode: () => runClaudeCode
6451
6515
  });
6452
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
+ }
6453
6525
  function getArgs() {
6454
6526
  return process.argv.slice(2);
6455
6527
  }
@@ -6499,12 +6571,14 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
6499
6571
  \u7528\u6CD5\uFF1Actr <\u547D\u4EE4> [\u9009\u9879]
6500
6572
 
6501
6573
  \u547D\u4EE4\uFF1A
6502
- setup \u9996\u6B21\u4F7F\u7528\u5411\u5BFC\uFF08\u63A8\u8350\u65B0\u624B\uFF09
6503
- init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6\uFF08\u4ECE\u793A\u4F8B\u6A21\u677F\u590D\u5236\uFF09
6574
+ setup \u68C0\u6D4B\u5E76\u590D\u7528\u5DF2\u6709\u914D\u7F6E\uFF0C\u5FC5\u8981\u65F6\u8FC1\u79FB\u65E7\u914D\u7F6E\u6216\u65B0\u5EFA\u6700\u5C0F\u914D\u7F6E
6575
+ init \u521D\u59CB\u5316\u6700\u5C0F\u914D\u7F6E\u6A21\u677F
6504
6576
  start \u542F\u52A8\u8DEF\u7531\u670D\u52A1\uFF08\u9ED8\u8BA4\u524D\u53F0\u8FD0\u884C\uFF09
6505
6577
  stop \u505C\u6B62\u540E\u53F0\u670D\u52A1
6506
6578
  restart \u91CD\u542F\u540E\u53F0\u670D\u52A1
6507
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
6508
6582
  code \u901A\u8FC7\u8DEF\u7531\u5668\u8FD0\u884C Claude Code\uFF08\u9700\u5148\u542F\u52A8\u670D\u52A1\uFF09
6509
6583
  ui \u6253\u5F00\u7BA1\u7406 API \u8BF4\u660E\u9875\uFF08Web UI \u5F00\u53D1\u4E2D\uFF09
6510
6584
  help \u663E\u793A\u6B64\u5E2E\u52A9\u4FE1\u606F
@@ -6515,8 +6589,10 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
6515
6589
  --force \u5F3A\u5236\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\uFF08\u914D\u5408 init \u4F7F\u7528\uFF09
6516
6590
 
6517
6591
  \u4F7F\u7528\u793A\u4F8B\uFF1A
6518
- ctr setup # \u9996\u6B21\u4F7F\u7528\u5411\u5BFC\uFF08\u63A8\u8350\uFF09
6519
- ctr init # \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6
6592
+ ctr setup # \u590D\u7528\u5F53\u524D\u914D\u7F6E / \u8FC1\u79FB\u65E7\u914D\u7F6E / \u65B0\u5EFA\u6700\u5C0F\u914D\u7F6E
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
6520
6596
  ctr start # \u524D\u53F0\u542F\u52A8\uFF08\u63A8\u8350\u9996\u6B21\u4F7F\u7528\uFF0C\u4FBF\u4E8E\u67E5\u770B\u65E5\u5FD7\uFF09
6521
6597
  ctr start --daemon # \u540E\u53F0\u542F\u52A8
6522
6598
  ctr status # \u67E5\u770B\u670D\u52A1\u72B6\u6001
@@ -6533,6 +6609,58 @@ Claude Trigger Router - \u667A\u80FD\u89E6\u53D1\u8DEF\u7531\u5668
6533
6609
  \u66F4\u591A\u4FE1\u606F\uFF1Ahttps://github.com/peterwangze/claude-trigger-router
6534
6610
  `);
6535
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
+ }
6536
6664
  function initConfig2() {
6537
6665
  const force = hasArg("--force");
6538
6666
  const existingConfig = [CONFIG_FILE, CONFIG_FILE_YML, CONFIG_FILE_JSON].find(import_fs7.existsSync);
@@ -6562,9 +6690,9 @@ function initConfig2() {
6562
6690
  console.log("");
6563
6691
  console.log("\u4E0B\u4E00\u6B65\uFF1A");
6564
6692
  console.log(" 1. \u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\uFF0C\u586B\u5165\u4F60\u7684 API \u5BC6\u94A5");
6565
- console.log(" 2. \u5728 'Providers' \u4E0B\u914D\u7F6E\u4F60\u7684\u6A21\u578B\u63D0\u4F9B\u5546");
6566
- console.log(" 3. \u5C06 'Router.default' \u8BBE\u7F6E\u4E3A\u4F60\u7684\u9ED8\u8BA4\u6A21\u578B");
6567
- console.log(" 4. \u5728 'TriggerRouter.rules' \u4E0B\u81EA\u5B9A\u4E49\u89E6\u53D1\u89C4\u5219");
6693
+ console.log(" 2. \u5728 'Models' \u4E0B\u8865\u5168\u4F60\u7684\u6A21\u578B\u63A5\u5165\u4FE1\u606F");
6694
+ console.log(" 3. \u5C06 'Router.default' \u8BBE\u7F6E\u4E3A\u9ED8\u8BA4\u6A21\u578B ID");
6695
+ console.log(" 4. \u5982\u9700\u9AD8\u7EA7\u8DEF\u7531\uFF0C\u518D\u7EE7\u7EED\u914D\u7F6E\u89C4\u5219\u6216\u667A\u80FD\u8DEF\u7531");
6568
6696
  console.log(` 5. \u8FD0\u884C\uFF1Actr start`);
6569
6697
  } catch (error) {
6570
6698
  console.error("\u274C \u521B\u5EFA\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:", error.message);
@@ -6719,6 +6847,12 @@ async function main() {
6719
6847
  case "status":
6720
6848
  showStatus();
6721
6849
  break;
6850
+ case "version":
6851
+ await printVersion();
6852
+ break;
6853
+ case "upgrade":
6854
+ printUpgradeGuidance();
6855
+ break;
6722
6856
  case "restart":
6723
6857
  restartService();
6724
6858
  break;
@@ -6741,7 +6875,7 @@ async function main() {
6741
6875
  process.exit(command ? 1 : 0);
6742
6876
  }
6743
6877
  }
6744
- 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;
6745
6879
  var init_cli = __esm({
6746
6880
  "src/cli.ts"() {
6747
6881
  import_child_process2 = require("child_process");
@@ -6753,6 +6887,9 @@ var init_cli = __esm({
6753
6887
  init_constants();
6754
6888
  init_service_health();
6755
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";
6756
6893
  if (process.env.CTR_SKIP_MAIN !== "1") {
6757
6894
  main().catch((error) => {
6758
6895
  console.error("Error:", error);