cc-linker 0.0.1 → 0.0.2

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 (5) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -117
  3. package/dist/cli.js +565 -427
  4. package/dist/cli.js.map +34 -33
  5. package/package.json +10 -8
package/dist/cli.js CHANGED
@@ -18312,16 +18312,16 @@ var require_proper_lockfile = __commonJS((exports, module) => {
18312
18312
  });
18313
18313
 
18314
18314
  // src/utils/errors.ts
18315
- var CCBridgeError;
18315
+ var CCLinkerError;
18316
18316
  var init_errors3 = __esm(() => {
18317
- CCBridgeError = class CCBridgeError extends Error {
18317
+ CCLinkerError = class CCLinkerError extends Error {
18318
18318
  code;
18319
18319
  details;
18320
18320
  constructor(code, message, details) {
18321
18321
  super(message);
18322
18322
  this.code = code;
18323
18323
  this.details = details;
18324
- this.name = "CCBridgeError";
18324
+ this.name = "CCLinkerError";
18325
18325
  }
18326
18326
  toString() {
18327
18327
  return `[${this.code}] ${this.message}`;
@@ -18410,13 +18410,13 @@ async function withLock(filePath, fn, options = {}) {
18410
18410
  elapsed += minTimeout * (attempt + 1);
18411
18411
  if (elapsed >= MAX_WAIT) {
18412
18412
  releaseInner();
18413
- throw new CCBridgeError("E007", "注册表被锁,等待超时");
18413
+ throw new CCLinkerError("E007", "注册表被锁,等待超时");
18414
18414
  }
18415
18415
  await sleep(minTimeout * (attempt + 1));
18416
18416
  }
18417
18417
  }
18418
18418
  releaseInner();
18419
- throw new CCBridgeError("E007", "注册表被锁,等待超时");
18419
+ throw new CCLinkerError("E007", "注册表被锁,等待超时");
18420
18420
  }
18421
18421
  async function withReadLock(fn) {
18422
18422
  const releaseRead = await rwLock.acquireRead();
@@ -18449,22 +18449,22 @@ function expandPath(p) {
18449
18449
  return join(process.env.HOME ?? "", p.slice(2));
18450
18450
  return p;
18451
18451
  }
18452
- var HOME, CC_BRIDGE_DIR, REGISTRY_PATH, BACKUP_DIR, SCAN_CACHE_PATH, HOOK_LOG_PATH, CONFIG_PATH, USER_MAPPING_PATH, LIST_SNAPSHOT_PATH, RUNTIME_OWNER_LOCK_PATH, RUNTIME_SESSION_EVENTS_DIR, RUNTIME_PID_FILE, RUNTIME_LOG_FILE, SPOOL_DIR, SPOOL_PENDING_DIR, SPOOL_PROCESSING_DIR, SPOOL_REPLIED_DIR, SPOOL_DONE_DIR, SPOOL_FAILED_DIR, SPOOL_RECEIPTS_DIR, SPOOL_DELIVERIES_DIR, CLAUDE_PROJECTS_DIR, CLAUDE_SETTINGS_PATH;
18452
+ var HOME, CC_LINKER_DIR, REGISTRY_PATH, BACKUP_DIR, SCAN_CACHE_PATH, HOOK_LOG_PATH, CONFIG_PATH, USER_MAPPING_PATH, LIST_SNAPSHOT_PATH, RUNTIME_OWNER_LOCK_PATH, RUNTIME_SESSION_EVENTS_DIR, RUNTIME_PID_FILE, RUNTIME_LOG_FILE, SPOOL_DIR, SPOOL_PENDING_DIR, SPOOL_PROCESSING_DIR, SPOOL_REPLIED_DIR, SPOOL_DONE_DIR, SPOOL_FAILED_DIR, SPOOL_RECEIPTS_DIR, SPOOL_DELIVERIES_DIR, CLAUDE_PROJECTS_DIR, CLAUDE_SETTINGS_PATH;
18453
18453
  var init_paths = __esm(() => {
18454
18454
  HOME = getHome();
18455
- CC_BRIDGE_DIR = process.env.CC_BRIDGE_DIR ?? join(HOME, ".cc-bridge");
18456
- REGISTRY_PATH = process.env.CC_BRIDGE_REGISTRY_PATH ?? join(CC_BRIDGE_DIR, "registry.json");
18457
- BACKUP_DIR = join(CC_BRIDGE_DIR, "backups");
18458
- SCAN_CACHE_PATH = join(CC_BRIDGE_DIR, "scan_cache.json");
18459
- HOOK_LOG_PATH = join(CC_BRIDGE_DIR, "hook.log");
18460
- CONFIG_PATH = process.env.CC_BRIDGE_CONFIG_PATH ?? join(CC_BRIDGE_DIR, "config.toml");
18461
- USER_MAPPING_PATH = join(CC_BRIDGE_DIR, "user-mapping.json");
18462
- LIST_SNAPSHOT_PATH = join(CC_BRIDGE_DIR, "list-snapshot.json");
18463
- RUNTIME_OWNER_LOCK_PATH = join(CC_BRIDGE_DIR, "owner.lock");
18464
- RUNTIME_SESSION_EVENTS_DIR = join(CC_BRIDGE_DIR, "session-events");
18465
- RUNTIME_PID_FILE = join(CC_BRIDGE_DIR, "cc-bridge.pid");
18466
- RUNTIME_LOG_FILE = join(CC_BRIDGE_DIR, "cc-bridge.log");
18467
- SPOOL_DIR = join(CC_BRIDGE_DIR, "spool");
18455
+ CC_LINKER_DIR = process.env.CC_LINKER_DIR ?? join(HOME, ".cc-linker");
18456
+ REGISTRY_PATH = process.env.CC_LINKER_REGISTRY_PATH ?? join(CC_LINKER_DIR, "registry.json");
18457
+ BACKUP_DIR = join(CC_LINKER_DIR, "backups");
18458
+ SCAN_CACHE_PATH = join(CC_LINKER_DIR, "scan_cache.json");
18459
+ HOOK_LOG_PATH = join(CC_LINKER_DIR, "hook.log");
18460
+ CONFIG_PATH = process.env.CC_LINKER_CONFIG_PATH ?? join(CC_LINKER_DIR, "config.toml");
18461
+ USER_MAPPING_PATH = join(CC_LINKER_DIR, "user-mapping.json");
18462
+ LIST_SNAPSHOT_PATH = join(CC_LINKER_DIR, "list-snapshot.json");
18463
+ RUNTIME_OWNER_LOCK_PATH = join(CC_LINKER_DIR, "owner.lock");
18464
+ RUNTIME_SESSION_EVENTS_DIR = join(CC_LINKER_DIR, "session-events");
18465
+ RUNTIME_PID_FILE = join(CC_LINKER_DIR, "cc-linker.pid");
18466
+ RUNTIME_LOG_FILE = join(CC_LINKER_DIR, "cc-linker.log");
18467
+ SPOOL_DIR = join(CC_LINKER_DIR, "spool");
18468
18468
  SPOOL_PENDING_DIR = join(SPOOL_DIR, "pending");
18469
18469
  SPOOL_PROCESSING_DIR = join(SPOOL_DIR, "processing");
18470
18470
  SPOOL_REPLIED_DIR = join(SPOOL_DIR, "replied");
@@ -20600,22 +20600,22 @@ class ConfigManager {
20600
20600
  }
20601
20601
  loadEnv() {
20602
20602
  const mappings = [
20603
- ["CC_BRIDGE_REGISTRY_PATH", "general", "registry_path"],
20604
- ["CC_BRIDGE_LOG_LEVEL", "general", "log_level"],
20605
- ["CC_BRIDGE_LOG_PATH", "general", "log_path"],
20606
- ["CC_BRIDGE_FEISHU_APP_ID", "feishu_bot", "app_id"],
20607
- ["CC_BRIDGE_FEISHU_APP_SECRET", "feishu_bot", "app_secret"],
20608
- ["CC_BRIDGE_FEISHU_OWNER_OPEN_ID", "feishu_bot", "owner_open_id"],
20609
- ["CC_BRIDGE_FEISHU_DEFAULT_CWD", "feishu_bot", "default_cwd"],
20610
- ["CC_BRIDGE_MAX_CONCURRENT_SESSIONS", "runtime", "max_concurrent_sessions"],
20611
- ["CC_BRIDGE_SESSION_LOCK_TIMEOUT_MS", "runtime", "session_lock_timeout_ms"],
20612
- ["CC_BRIDGE_MAX_QUEUE_SIZE", "queue", "max_pending"],
20613
- ["CC_BRIDGE_CONFIRM_RISKY_ACTIONS", "security", "confirm_risky_actions"],
20614
- ["CC_BRIDGE_STREAM_ENABLED", "stream", "enabled"],
20615
- ["CC_BRIDGE_STREAM_THROTTLE_MS", "stream", "throttle_ms"],
20616
- ["CC_BRIDGE_STREAM_SHOW_THINKING", "stream", "show_thinking"],
20617
- ["CC_BRIDGE_STREAM_MAX_CARD_BYTES", "stream", "max_card_bytes"],
20618
- ["CC_BRIDGE_STREAM_FALLBACK_TO_TEXT", "stream", "fallback_to_text"]
20603
+ ["CC_LINKER_REGISTRY_PATH", "general", "registry_path"],
20604
+ ["CC_LINKER_LOG_LEVEL", "general", "log_level"],
20605
+ ["CC_LINKER_LOG_PATH", "general", "log_path"],
20606
+ ["CC_LINKER_FEISHU_APP_ID", "feishu_bot", "app_id"],
20607
+ ["CC_LINKER_FEISHU_APP_SECRET", "feishu_bot", "app_secret"],
20608
+ ["CC_LINKER_FEISHU_OWNER_OPEN_ID", "feishu_bot", "owner_open_id"],
20609
+ ["CC_LINKER_FEISHU_DEFAULT_CWD", "feishu_bot", "default_cwd"],
20610
+ ["CC_LINKER_MAX_CONCURRENT_SESSIONS", "runtime", "max_concurrent_sessions"],
20611
+ ["CC_LINKER_SESSION_LOCK_TIMEOUT_MS", "runtime", "session_lock_timeout_ms"],
20612
+ ["CC_LINKER_MAX_QUEUE_SIZE", "queue", "max_pending"],
20613
+ ["CC_LINKER_CONFIRM_RISKY_ACTIONS", "security", "confirm_risky_actions"],
20614
+ ["CC_LINKER_STREAM_ENABLED", "stream", "enabled"],
20615
+ ["CC_LINKER_STREAM_THROTTLE_MS", "stream", "throttle_ms"],
20616
+ ["CC_LINKER_STREAM_SHOW_THINKING", "stream", "show_thinking"],
20617
+ ["CC_LINKER_STREAM_MAX_CARD_BYTES", "stream", "max_card_bytes"],
20618
+ ["CC_LINKER_STREAM_FALLBACK_TO_TEXT", "stream", "fallback_to_text"]
20619
20619
  ];
20620
20620
  for (const [envKey, section, key] of mappings) {
20621
20621
  const value = process.env[envKey];
@@ -20630,7 +20630,7 @@ class ConfigManager {
20630
20630
  }
20631
20631
  }
20632
20632
  }
20633
- const legacyOwner = process.env.CC_BRIDGE_FEISHU_OWNER_USER_ID;
20633
+ const legacyOwner = process.env.CC_LINKER_FEISHU_OWNER_USER_ID;
20634
20634
  if (legacyOwner && !this.data.feishu_bot.owner_open_id) {
20635
20635
  this.data.feishu_bot.owner_open_id = legacyOwner;
20636
20636
  }
@@ -20695,7 +20695,7 @@ var init_config = __esm(() => {
20695
20695
  enabled: false
20696
20696
  },
20697
20697
  hook: {
20698
- log_path: "~/.cc-bridge/hook.log",
20698
+ log_path: "~/.cc-linker/hook.log",
20699
20699
  timeout: 10
20700
20700
  },
20701
20701
  stream: {
@@ -20758,7 +20758,7 @@ class RegistryManager {
20758
20758
  this.basePath = basePath;
20759
20759
  this.registryPath = join2(this.basePath, "registry.json");
20760
20760
  } else {
20761
- const configuredPath = this.expandPath(config2.get("general.registry_path", join2(CC_BRIDGE_DIR, "registry.json")));
20761
+ const configuredPath = this.expandPath(config2.get("general.registry_path", join2(CC_LINKER_DIR, "registry.json")));
20762
20762
  this.registryPath = configuredPath;
20763
20763
  this.basePath = dirname2(configuredPath);
20764
20764
  }
@@ -21892,7 +21892,7 @@ class StateCoordinator2 {
21892
21892
  }
21893
21893
  static assertNotRunning(lockPath) {
21894
21894
  if (StateCoordinator2.isLocked(lockPath)) {
21895
- throw new CCBridgeError("E013", "Bot 进程正在运行,请使用飞书命令操作会话,而非直接 CLI 操作");
21895
+ throw new CCLinkerError("E013", "Bot 进程正在运行,请使用飞书命令操作会话,而非直接 CLI 操作");
21896
21896
  }
21897
21897
  }
21898
21898
  isHeld() {
@@ -46541,7 +46541,7 @@ async function fileExists(path3) {
46541
46541
  class ProviderManager {
46542
46542
  providers = new Map;
46543
46543
  source = "none";
46544
- autoProviderDir = join11(CC_BRIDGE_DIR, "auto-providers");
46544
+ autoProviderDir = join11(CC_LINKER_DIR, "auto-providers");
46545
46545
  getSource() {
46546
46546
  return this.source;
46547
46547
  }
@@ -46591,7 +46591,7 @@ class ProviderManager {
46591
46591
  const rawAlias = basename2(file2, ".json");
46592
46592
  try {
46593
46593
  const content = JSON.parse(readFileSync13(path3, "utf8"));
46594
- const baseAlias = content.alias ? this.sanitizeName(content.alias) : this.generateShortAlias(rawAlias);
46594
+ const baseAlias = content.alias ? this.sanitizeName(content.alias) : isTemp ? rawAlias : this.generateShortAlias(rawAlias);
46595
46595
  const alias = this.resolveAliasConflict(baseAlias);
46596
46596
  const name = content.name ?? rawAlias;
46597
46597
  if (this.providers.has(alias)) {
@@ -46622,17 +46622,18 @@ class ProviderManager {
46622
46622
  try {
46623
46623
  const cleanConfig = this.sanitizeSettingsConfig(row.settings_config);
46624
46624
  const baseAlias = cleanConfig.alias ? this.sanitizeName(cleanConfig.alias) : this.generateShortAlias(row.name);
46625
- const alias = this.resolveAliasConflict(baseAlias);
46626
- const filePath = join11(this.autoProviderDir, `${alias}.json`);
46625
+ let alias = baseAlias;
46626
+ let filePath = join11(this.autoProviderDir, `${alias}.json`);
46627
+ let counter = 2;
46628
+ while (existsSync19(filePath)) {
46629
+ alias = `${baseAlias}-${counter}`;
46630
+ filePath = join11(this.autoProviderDir, `${alias}.json`);
46631
+ counter++;
46632
+ }
46627
46633
  const tmpPath = filePath + ".tmp";
46628
46634
  const configWithName = { ...cleanConfig, name: row.name, alias: cleanConfig.alias };
46629
46635
  writeFileSync12(tmpPath, JSON.stringify(configWithName, null, 2), { mode: 384 });
46630
46636
  renameSync6(tmpPath, filePath);
46631
- if (this.providers.has(alias)) {
46632
- const existing = this.providers.get(alias);
46633
- logger.warn(`Provider alias conflict in CC Switch: "${alias}" (from "${row.name}") overrides existing from ${existing.path}`);
46634
- }
46635
- this.providers.set(alias, { alias, name: row.name, path: filePath, isTemp: true });
46636
46637
  } catch (err) {
46637
46638
  logger.warn(`Skipping CC Switch provider "${row.name}": ${err}`);
46638
46639
  }
@@ -46784,7 +46785,8 @@ class FeishuBot {
46784
46785
  await this.replyFn(`消息过长(${text.length} 字符),请控制在 ${MAX_MESSAGE_LENGTH} 字符以内,或将内容分段发送。`, { messageId: event.message_id, openId: event.open_id, requestUuid: stableUuid(event.message_id) });
46785
46786
  return;
46786
46787
  }
46787
- const target = text.startsWith("/bridge") ? { type: "no_target", openId: event.open_id, mappingVersion: this.userManager.getVersion() } : await this.resolveChatTarget(event.open_id, event.message_id);
46788
+ const isCommand = text.startsWith("/") && text.length > 1 && text[1] !== " ";
46789
+ const target = isCommand ? { type: "no_target", openId: event.open_id, mappingVersion: this.userManager.getVersion() } : await this.resolveChatTarget(event.open_id, event.message_id);
46788
46790
  const serialKey = target.type === "session" && target.sessionUuid ? target.sessionUuid : `new:${event.open_id}`;
46789
46791
  const spoolMsg = {
46790
46792
  messageId: event.message_id,
@@ -46892,6 +46894,16 @@ class FeishuBot {
46892
46894
  await this.replyFn(reply, { messageId, openId, requestUuid: uniqueUuid() });
46893
46895
  return reply;
46894
46896
  }
46897
+ case "select_model": {
46898
+ const reply = await this.doSelectModel(openId, sessionId, messageId);
46899
+ await this.replyFn(reply, { messageId, openId, requestUuid: uniqueUuid() });
46900
+ return reply;
46901
+ }
46902
+ case "clear_model": {
46903
+ const reply = await this.doClearModel(openId, messageId);
46904
+ await this.replyFn(reply, { messageId, openId, requestUuid: uniqueUuid() });
46905
+ return reply;
46906
+ }
46895
46907
  case "status": {
46896
46908
  const reply = await this.doStatus(openId);
46897
46909
  await this.replyFn(reply, { messageId, openId, requestUuid: uniqueUuid() });
@@ -46922,7 +46934,7 @@ class FeishuBot {
46922
46934
  try {
46923
46935
  if (msg.responseText) {
46924
46936
  await this.replyAndFinalize(msg, msg.responseText);
46925
- } else if (msg.text.startsWith("/bridge")) {
46937
+ } else if (msg.text.startsWith("/") && msg.text.length > 1 && msg.text[1] !== " ") {
46926
46938
  await this.handleCommand(msg);
46927
46939
  } else {
46928
46940
  await this.handleChat(msg);
@@ -46946,7 +46958,7 @@ class FeishuBot {
46946
46958
  }
46947
46959
  async handleCommand(msg) {
46948
46960
  const parts = msg.text.split(/\s+/);
46949
- const cmd = parts[1]?.toLowerCase();
46961
+ const cmd = parts[0]?.replace(/^\/+/, "")?.toLowerCase();
46950
46962
  switch (cmd) {
46951
46963
  case "help":
46952
46964
  await this.replyAndFinalize(msg, this.helpText());
@@ -46955,16 +46967,16 @@ class FeishuBot {
46955
46967
  await this.handleList(msg);
46956
46968
  return;
46957
46969
  case "new":
46958
- await this.handleNew(msg, msg.text.replace(/^\/bridge\s+new\s*/i, ""));
46970
+ await this.handleNew(msg, msg.text.replace(/^\/new\b\s*/i, ""));
46959
46971
  return;
46960
46972
  case "switch":
46961
- await this.handleSwitch(msg, parts.slice(2).join(" "));
46973
+ await this.handleSwitch(msg, parts.slice(1).join(" "));
46962
46974
  return;
46963
46975
  case "model":
46964
- await this.handleModel(msg, parts.slice(2).join(" "));
46976
+ await this.handleModel(msg, parts.slice(1).join(" "));
46965
46977
  return;
46966
46978
  case "resume":
46967
- await this.handleResume(msg, parts.slice(2).join(" "));
46979
+ await this.handleResume(msg, parts.slice(1).join(" "));
46968
46980
  return;
46969
46981
  case "status":
46970
46982
  await this.handleStatus(msg);
@@ -46975,7 +46987,7 @@ class FeishuBot {
46975
46987
  将其填入 config.toml 的 feishu_bot.owner_open_id 可限制仅你本人使用。`);
46976
46988
  return;
46977
46989
  default:
46978
- await this.replyAndFinalize(msg, `未知命令: /bridge ${cmd}
46990
+ await this.replyAndFinalize(msg, `未知命令: /${cmd}
46979
46991
 
46980
46992
  ${this.helpText()}`);
46981
46993
  return;
@@ -46998,11 +47010,11 @@ ${this.helpText()}`);
46998
47010
  const claimMessageId = msg.target.claimMessageId ?? msg.messageId;
46999
47011
  const claimResult = await this.userManager.claimPendingNewSession(msg.openId, claimMessageId);
47000
47012
  if (claimResult.status === "creating") {
47001
- await this.replyAndFinalize(msg, "新会话正在创建,请稍后重试,或执行 /bridge list 查看是否已生成。");
47013
+ await this.replyAndFinalize(msg, "新会话正在创建,请稍后重试,或执行 /list 查看是否已生成。");
47002
47014
  return;
47003
47015
  }
47004
47016
  if (claimResult.status !== "claimed") {
47005
- await this.replyAndFinalize(msg, "新会话创建入口已失效,请重新执行 /bridge new。");
47017
+ await this.replyAndFinalize(msg, "新会话创建入口已失效,请重新执行 /new。");
47006
47018
  return;
47007
47019
  }
47008
47020
  if (config2.get("stream.enabled", false)) {
@@ -47013,16 +47025,16 @@ ${this.helpText()}`);
47013
47025
  return;
47014
47026
  }
47015
47027
  case "new_session_creating":
47016
- await this.replyAndFinalize(msg, "新会话正在创建,请稍后重试,或执行 /bridge list 查看是否已生成。");
47028
+ await this.replyAndFinalize(msg, "新会话正在创建,请稍后重试,或执行 /list 查看是否已生成。");
47017
47029
  return;
47018
47030
  case "no_target":
47019
47031
  default:
47020
47032
  await this.replyAndFinalize(msg, [
47021
47033
  "当前没有活跃会话。",
47022
47034
  "请先执行以下任一命令:",
47023
- "1. /bridge list",
47024
- "2. /bridge switch <ID>",
47025
- "3. /bridge new [cwd] [-- prompt]"
47035
+ "1. /list",
47036
+ "2. /switch <ID>",
47037
+ "3. /new [cwd] [-- prompt]"
47026
47038
  ].join(`
47027
47039
  `));
47028
47040
  return;
@@ -47271,7 +47283,7 @@ ${this.helpText()}`);
47271
47283
  const provider = this.providerManager.resolve(providerAlias);
47272
47284
  if (!provider) {
47273
47285
  await this.replyAndFinalize(msg, `未知模型: "${providerAlias}"
47274
- 请使用 /bridge model 查看可用列表`);
47286
+ 请使用 /model 查看可用列表`);
47275
47287
  return;
47276
47288
  }
47277
47289
  const entry = this.userManager.getEntry(msg.openId);
@@ -47284,7 +47296,7 @@ ${this.helpText()}`);
47284
47296
  await this.userManager.compareAndSwap(msg.openId, entry ?? null, newEntry);
47285
47297
  }
47286
47298
  if (!cwd) {
47287
- await this.replyAndFinalize(msg, "请使用 /bridge new <cwd>,或在配置里设置 feishu_bot.default_cwd。");
47299
+ await this.replyAndFinalize(msg, "请使用 /new <cwd>,或在配置里设置 feishu_bot.default_cwd。");
47288
47300
  return;
47289
47301
  }
47290
47302
  const validationError = validateCwd(cwd);
@@ -47335,26 +47347,26 @@ ${this.helpText()}`);
47335
47347
  }
47336
47348
  async handleSwitch(msg, target) {
47337
47349
  if (!target) {
47338
- await this.replyAndFinalize(msg, "用法: /bridge switch <序号或 UUID>");
47350
+ await this.replyAndFinalize(msg, "用法: /switch <序号或 UUID>");
47339
47351
  return;
47340
47352
  }
47341
47353
  const index = parseInt(target, 10);
47342
47354
  const uuid3 = Number.isNaN(index) ? this.registry.findByPrefix(target)?.[0] ?? null : this.listSnapshotManager.resolveIndex(index, msg.openId);
47343
47355
  if (!uuid3) {
47344
- await this.replyAndFinalize(msg, `未找到 "${target}" 对应的会话(或匹配到多个),请先执行 /bridge list 查看完整列表。`);
47356
+ await this.replyAndFinalize(msg, `未找到 "${target}" 对应的会话(或匹配到多个),请先执行 /list 查看完整列表。`);
47345
47357
  return;
47346
47358
  }
47347
47359
  await this.doSwitch(msg.openId, uuid3, msg.messageId, msg);
47348
47360
  }
47349
47361
  async handleResume(msg, target) {
47350
47362
  if (!target) {
47351
- await this.replyAndFinalize(msg, "用法: /bridge resume <序号或 UUID>");
47363
+ await this.replyAndFinalize(msg, "用法: /resume <序号或 UUID>");
47352
47364
  return;
47353
47365
  }
47354
47366
  const index = parseInt(target, 10);
47355
47367
  const uuid3 = Number.isNaN(index) ? this.registry.findByPrefix(target)?.[0] ?? null : this.listSnapshotManager.resolveIndex(index, msg.openId);
47356
47368
  if (!uuid3) {
47357
- await this.replyAndFinalize(msg, `未找到 "${target}" 对应的会话(或匹配到多个),请先执行 /bridge list 查看完整列表。`);
47369
+ await this.replyAndFinalize(msg, `未找到 "${target}" 对应的会话(或匹配到多个),请先执行 /list 查看完整列表。`);
47358
47370
  return;
47359
47371
  }
47360
47372
  await this.doResumeReply(msg.openId, uuid3, msg);
@@ -47368,33 +47380,46 @@ ${this.helpText()}`);
47368
47380
  if (!target) {
47369
47381
  const entry2 = this.userManager.getEntry(msg.openId);
47370
47382
  const currentAlias = entry2?.defaultProvider ?? null;
47371
- const lines = [];
47372
- if (currentAlias) {
47373
- const provider2 = this.providerManager.resolve(currentAlias);
47374
- lines.push(`当前默认模型: ${provider2?.name ?? currentAlias}`);
47375
- } else {
47376
- lines.push("当前默认模型: 未设置(跟随 Claude 全局配置)");
47377
- }
47378
47383
  const providers = this.providerManager.list();
47379
- if (providers.length > 0) {
47384
+ if (providers.length === 0) {
47385
+ const lines = [
47386
+ "当前默认模型: 未设置(跟随 Claude 全局配置)",
47387
+ "",
47388
+ "未检测到可切换模型。",
47389
+ "请安装 CC Switch 或手动创建 ~/.claude/providers/*.json"
47390
+ ];
47391
+ await this.replyAndFinalize(msg, lines.join(`
47392
+ `));
47393
+ return;
47394
+ }
47395
+ const card = buildModelCard(providers, currentAlias);
47396
+ const replyId = await this.cardReplyFn(card, { messageId: msg.messageId, openId: msg.openId });
47397
+ if (replyId) {
47398
+ this.spoolQueue.recordDelivery(msg.messageId, "sent", stableUuid(msg.messageId, 0), 0, replyId, 1);
47399
+ this.spoolQueue.markReplied(msg.messageId, msg.serialKey, replyId);
47400
+ this.spoolQueue.markDone(msg.messageId, msg.serialKey, replyId);
47401
+ } else {
47402
+ const lines = [];
47403
+ if (currentAlias) {
47404
+ const provider2 = this.providerManager.resolve(currentAlias);
47405
+ lines.push(`当前默认模型: ${provider2?.name ?? currentAlias}`);
47406
+ } else {
47407
+ lines.push("当前默认模型: 未设置(跟随 Claude 全局配置)");
47408
+ }
47380
47409
  lines.push("");
47381
47410
  lines.push("可用模型:");
47382
47411
  providers.forEach((p, i) => {
47383
47412
  const marker = p.alias === currentAlias ? "●" : " ";
47384
47413
  lines.push(` ${marker} ${i + 1}. ${p.name} (${p.alias})`);
47385
47414
  });
47386
- } else {
47387
47415
  lines.push("");
47388
- lines.push("未检测到可切换模型。");
47389
- lines.push("请安装 CC Switch 或手动创建 ~/.claude/providers/*.json");
47390
- }
47391
- lines.push("");
47392
- lines.push("用法:");
47393
- lines.push(" /bridge model <序号|别名> 设置默认模型");
47394
- lines.push(" /bridge model --clear 清除默认设置");
47395
- lines.push(" /bridge new /path --model <别名> 创建会话时指定模型");
47396
- await this.replyAndFinalize(msg, lines.join(`
47416
+ lines.push("用法:");
47417
+ lines.push(" /model <序号|别名> 设置默认模型");
47418
+ lines.push(" /model --clear 清除默认设置");
47419
+ lines.push(" /new /path --model <别名> 创建会话时指定模型");
47420
+ await this.replyAndFinalize(msg, lines.join(`
47397
47421
  `));
47422
+ }
47398
47423
  return;
47399
47424
  }
47400
47425
  if (target === "--clear") {
@@ -47410,7 +47435,7 @@ ${this.helpText()}`);
47410
47435
  const provider = this.providerManager.resolve(target);
47411
47436
  if (!provider) {
47412
47437
  await this.replyAndFinalize(msg, `未知模型: "${target}"
47413
- 请使用 /bridge model 查看可用列表`);
47438
+ 请使用 /model 查看可用列表`);
47414
47439
  return;
47415
47440
  }
47416
47441
  const entry = this.userManager.getEntry(msg.openId);
@@ -47426,17 +47451,17 @@ ${this.helpText()}`);
47426
47451
  helpText() {
47427
47452
  return [
47428
47453
  "可用命令:",
47429
- " /bridge help - 显示此帮助",
47430
- " /bridge list - 列出会话",
47431
- " /bridge new [路径] [-- prompt] - 创建新会话",
47432
- " /bridge new [路径] --model <别名> [-- p] - 指定模型创建会话",
47433
- " /bridge switch <序号|UUID> - 切换会话",
47434
- " /bridge model - 查看可用模型和默认设置",
47435
- " /bridge model <序号|别名> - 设置默认模型",
47436
- " /bridge model --clear - 清除默认设置",
47437
- " /bridge resume <序号|UUID> - 获取安全恢复建议",
47438
- " /bridge status - 查看状态",
47439
- " /bridge whoami - 获取你的 open_id"
47454
+ " /help - 显示此帮助",
47455
+ " /list - 列出会话",
47456
+ " /new [路径] [-- prompt] - 创建新会话",
47457
+ " /new [路径] --model <别名> [-- p] - 指定模型创建会话",
47458
+ " /switch <序号|UUID> - 切换会话",
47459
+ " /model - 查看可用模型和默认设置",
47460
+ " /model <序号|别名> - 设置默认模型",
47461
+ " /model --clear - 清除默认设置",
47462
+ " /resume <序号|UUID> - 获取安全恢复建议",
47463
+ " /status - 查看状态",
47464
+ " /whoami - 获取你的 open_id"
47440
47465
  ].join(`
47441
47466
  `);
47442
47467
  }
@@ -47626,7 +47651,7 @@ ${this.helpText()}`);
47626
47651
  async doSwitch(openId, uuid3, messageId, msg) {
47627
47652
  const session = this.registry.get(uuid3);
47628
47653
  if (!session) {
47629
- const reply2 = "未找到对应会话,请先执行 /bridge list。";
47654
+ const reply2 = "未找到对应会话,请先执行 /list。";
47630
47655
  if (msg)
47631
47656
  await this.replyAndFinalize(msg, reply2);
47632
47657
  else
@@ -47649,16 +47674,45 @@ ${this.helpText()}`);
47649
47674
  this.spoolQueue.recordReceipt(messageId ?? "");
47650
47675
  return reply;
47651
47676
  }
47677
+ async doSelectModel(openId, alias, messageId) {
47678
+ const provider = this.providerManager.resolve(alias);
47679
+ if (!provider) {
47680
+ return `未知模型: "${alias}"
47681
+ 请使用 /model 查看可用列表`;
47682
+ }
47683
+ const entry = this.userManager.getEntry(openId);
47684
+ const newEntry = entry ? { ...entry, defaultProvider: provider.alias } : {
47685
+ type: "pending_new_session",
47686
+ sessionUuid: null,
47687
+ createdAt: new Date().toISOString(),
47688
+ defaultProvider: provider.alias
47689
+ };
47690
+ const swapped = await this.userManager.compareAndSwap(openId, entry ?? null, newEntry);
47691
+ if (!swapped)
47692
+ return "⚠️ 设置失败,请重试";
47693
+ this.spoolQueue.recordReceipt(messageId ?? "");
47694
+ return `✅ 默认模型已设置为 ${provider.name} (${provider.alias})`;
47695
+ }
47696
+ async doClearModel(openId, messageId) {
47697
+ const entry = this.userManager.getEntry(openId);
47698
+ if (!entry) {
47699
+ this.spoolQueue.recordReceipt(messageId ?? "");
47700
+ return "⚠️ 无当前会话状态,无需清除";
47701
+ }
47702
+ const swapped = await this.userManager.compareAndSwap(openId, entry, { ...entry, defaultProvider: undefined });
47703
+ this.spoolQueue.recordReceipt(messageId ?? "");
47704
+ return swapped ? "✅ 已清除默认模型设置" : "⚠️ 清除失败,请重试";
47705
+ }
47652
47706
  async doResume(openId, uuid3, messageId) {
47653
47707
  const entry = this.registry.get(uuid3);
47654
47708
  if (!entry)
47655
- return "未找到对应会话,请先执行 /bridge list。";
47709
+ return "未找到对应会话,请先执行 /list。";
47656
47710
  if (entry.status === "corrupted")
47657
47711
  return `会话 ${uuid3.slice(0, 8)} 已损坏,不能直接恢复。`;
47658
47712
  if (entry.status === "provisioning" || entry.status === "degraded") {
47659
- return `会话 ${uuid3.slice(0, 8)} 状态为 ${entry.status},建议先保持 cc-bridge 运行让系统自动修复。`;
47713
+ return `会话 ${uuid3.slice(0, 8)} 状态为 ${entry.status},建议先保持 cc-linker 运行让系统自动修复。`;
47660
47714
  }
47661
- return `在终端执行: cc-link resume ${uuid3.slice(0, 8)}`;
47715
+ return `在终端执行: cc-linker resume ${uuid3.slice(0, 8)}`;
47662
47716
  }
47663
47717
  async doResumeReply(openId, uuid3, msg) {
47664
47718
  const reply = await this.doResume(openId, uuid3);
@@ -47670,7 +47724,7 @@ ${this.helpText()}`);
47670
47724
  const sessions = Object.values(this.registry.sessions);
47671
47725
  const provider = entry?.defaultProvider ? this.providerManager.resolve(entry.defaultProvider) : null;
47672
47726
  return [
47673
- "cc-link 状态",
47727
+ "cc-linker 状态",
47674
47728
  "─".repeat(30),
47675
47729
  `队列消息: ${queueSize}`,
47676
47730
  `总会话数: ${sessions.length}`,
@@ -47718,6 +47772,58 @@ ID: \`${uuid3.slice(0, 8)}\` | ${entry.message_count}条 | ${formatTimeAgo(entry
47718
47772
  header: { title: { tag: "plain_text", content: `\uD83D\uDCCB 我的会话(${sessions.length}/${total})` }, template: "blue" }
47719
47773
  };
47720
47774
  }
47775
+ function buildModelCard(providers, currentAlias) {
47776
+ const elements = [];
47777
+ if (currentAlias) {
47778
+ const current = providers.find((p) => p.alias === currentAlias);
47779
+ elements.push({
47780
+ tag: "markdown",
47781
+ content: `**当前默认:** ${current?.name ?? currentAlias} (\`${currentAlias}\`)`
47782
+ });
47783
+ elements.push({ tag: "hr" });
47784
+ }
47785
+ for (let i = 0;i < providers.length; i++) {
47786
+ const p = providers[i];
47787
+ const isCurrent = p.alias === currentAlias;
47788
+ elements.push({
47789
+ tag: "markdown",
47790
+ content: `${i + 1}. **${p.name}** \`${p.alias}\`${isCurrent ? " ✅" : ""}`
47791
+ });
47792
+ elements.push({
47793
+ tag: "action",
47794
+ actions: [
47795
+ {
47796
+ tag: "button",
47797
+ text: { tag: "plain_text", content: isCurrent ? "✅ 已选择" : "\uD83C\uDFAF 选择" },
47798
+ type: isCurrent ? "default" : "primary",
47799
+ value: { tag: "select_model", sessionId: p.alias }
47800
+ }
47801
+ ]
47802
+ });
47803
+ if (i < providers.length - 1) {
47804
+ elements.push({ tag: "hr" });
47805
+ }
47806
+ }
47807
+ if (currentAlias) {
47808
+ elements.push({ tag: "hr" });
47809
+ elements.push({
47810
+ tag: "action",
47811
+ actions: [
47812
+ {
47813
+ tag: "button",
47814
+ text: { tag: "plain_text", content: "\uD83E\uDDF9 清除默认" },
47815
+ type: "danger",
47816
+ value: { tag: "clear_model", sessionId: "" }
47817
+ }
47818
+ ]
47819
+ });
47820
+ }
47821
+ return {
47822
+ config: { wide_screen_mode: true },
47823
+ elements,
47824
+ header: { title: { tag: "plain_text", content: "\uD83E\uDD16 模型选择" }, template: "blue" }
47825
+ };
47826
+ }
47721
47827
  function preview(text, maxLength = 80) {
47722
47828
  const normalized = text.replace(/\s+/g, " ").trim();
47723
47829
  return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 3)}...` : normalized;
@@ -69724,7 +69830,7 @@ var require_index_minimal = __commonJS((exports) => {
69724
69830
 
69725
69831
  // node_modules/@larksuiteoapi/node-sdk/lib/index.js
69726
69832
  var require_lib5 = __commonJS((exports) => {
69727
- var __dirname = "/Users/wuyujun/Git/cc-bridge/node_modules/@larksuiteoapi/node-sdk/lib";
69833
+ var __dirname = "/Users/wuyujun/Git/cc-linker/node_modules/@larksuiteoapi/node-sdk/lib";
69728
69834
  Object.defineProperty(exports, "__esModule", { value: true });
69729
69835
  var axios = require_axios();
69730
69836
  var fs = __require("fs");
@@ -129031,7 +129137,7 @@ import { dirname as dirname6, join as join15 } from "path";
129031
129137
  import { homedir as homedir5 } from "os";
129032
129138
  import { spawnSync as spawnSync3 } from "child_process";
129033
129139
  async function start2(registry2, opts = {}) {
129034
- if (process.env.CC_BRIDGE_DAEMON === "1") {
129140
+ if (process.env.CC_LINKER_DAEMON === "1") {
129035
129141
  await startDaemonChild2(registry2, opts);
129036
129142
  return;
129037
129143
  }
@@ -129039,7 +129145,7 @@ async function start2(registry2, opts = {}) {
129039
129145
  if (isRunning2()) {
129040
129146
  const pid = readPid2();
129041
129147
  console.log(source_default.yellow(`⚠️ Bot 已在后台运行 (PID: ${pid})`));
129042
- console.log(source_default.cyan(` 停止: cc-bridge stop`));
129148
+ console.log(source_default.cyan(` 停止: cc-linker stop`));
129043
129149
  return;
129044
129150
  }
129045
129151
  await startDaemon2();
@@ -129047,7 +129153,7 @@ async function start2(registry2, opts = {}) {
129047
129153
  }
129048
129154
  const sc = new StateCoordinator2;
129049
129155
  if (StateCoordinator2.isLocked()) {
129050
- console.log(source_default.red("❌ Bot 进程正在运行,请先执行 cc-bridge stop"));
129156
+ console.log(source_default.red("❌ Bot 进程正在运行,请先执行 cc-linker stop"));
129051
129157
  process.exit(1);
129052
129158
  }
129053
129159
  await startForeground2(registry2, opts);
@@ -129068,7 +129174,7 @@ function readPid2() {
129068
129174
  }
129069
129175
  async function stop2() {
129070
129176
  let stopped = false;
129071
- const plistPath = join15(homedir5(), "Library", "LaunchAgents", "com.ccbridge.daemon.plist");
129177
+ const plistPath = join15(homedir5(), "Library", "LaunchAgents", "com.cclinker.daemon.plist");
129072
129178
  if (existsSync24(plistPath)) {
129073
129179
  try {
129074
129180
  spawnSync3("launchctl", ["unload", plistPath]);
@@ -129109,7 +129215,7 @@ async function stop2() {
129109
129215
  }
129110
129216
  try {
129111
129217
  const { execSync } = await import("child_process");
129112
- const pids = execSync("pgrep -f 'cc-bridge.*daemon' 2>/dev/null || true", { encoding: "utf8" }).trim().split(`
129218
+ const pids = execSync("pgrep -f 'cc-linker.*daemon' 2>/dev/null || true", { encoding: "utf8" }).trim().split(`
129113
129219
  `).filter(Boolean);
129114
129220
  for (const pidStr of pids) {
129115
129221
  const p = parseInt(pidStr, 10);
@@ -129134,7 +129240,7 @@ async function daemonStatus() {
129134
129240
  const pid = readPid2();
129135
129241
  console.log(source_default.green(`✅ Bot 正在运行 (PID: ${pid})`));
129136
129242
  console.log(source_default.gray(` 日志: ${RUNTIME_LOG_FILE}`));
129137
- console.log(source_default.gray(` 停止: cc-bridge stop`));
129243
+ console.log(source_default.gray(` 停止: cc-linker stop`));
129138
129244
  if (existsSync24(RUNTIME_LOG_FILE)) {
129139
129245
  const log = readFileSync17(RUNTIME_LOG_FILE, "utf8");
129140
129246
  const lines = log.trim().split(`
@@ -129344,7 +129450,7 @@ async function createBotRuntime2(registry2, log, wsLogLevel) {
129344
129450
  return { bot, wsClient, stateCoordinator: stateCoordinator3, shutdown };
129345
129451
  }
129346
129452
  async function startForeground2(registry2, opts) {
129347
- console.log(source_default.blue("\uD83D\uDE80 启动 cc-bridge..."));
129453
+ console.log(source_default.blue("\uD83D\uDE80 启动 cc-linker..."));
129348
129454
  const { bot, stateCoordinator: stateCoordinator3, shutdown } = await createBotRuntime2(registry2, (level, msg) => {
129349
129455
  if (level === "ERROR") {
129350
129456
  console.error(source_default.red(msg));
@@ -129359,7 +129465,7 @@ async function startForeground2(registry2, opts) {
129359
129465
  logger.info(msg);
129360
129466
  }
129361
129467
  });
129362
- console.log(source_default.green("✅ cc-bridge 已启动"));
129468
+ console.log(source_default.green("✅ cc-linker 已启动"));
129363
129469
  let shuttingDown = false;
129364
129470
  const gracefulShutdown = async (signal) => {
129365
129471
  if (shuttingDown)
@@ -129368,7 +129474,7 @@ async function startForeground2(registry2, opts) {
129368
129474
  console.log(source_default.yellow(`
129369
129475
  收到 ${signal},优雅停机中...`));
129370
129476
  await shutdown(signal);
129371
- logger.info("cc-bridge 已停止");
129477
+ logger.info("cc-linker 已停止");
129372
129478
  process.exit(0);
129373
129479
  };
129374
129480
  process.on("SIGINT", () => gracefulShutdown("SIGINT"));
@@ -129409,13 +129515,13 @@ async function startDaemonChild2(registry2, opts) {
129409
129515
  if (existsSync24(RUNTIME_PID_FILE))
129410
129516
  unlinkSync9(RUNTIME_PID_FILE);
129411
129517
  } catch {}
129412
- log("INFO", "cc-bridge 已停止");
129518
+ log("INFO", "cc-linker 已停止");
129413
129519
  process.exit(0);
129414
129520
  };
129415
129521
  process.on("SIGTERM", () => baseShutdown("SIGTERM"));
129416
129522
  process.on("SIGINT", () => baseShutdown("SIGINT"));
129417
129523
  const { bot, shutdown } = await createBotRuntime2(registry2, log);
129418
- log("INFO", "cc-bridge daemon started");
129524
+ log("INFO", "cc-linker daemon started");
129419
129525
  const daemonShutdown = async (signal) => {
129420
129526
  if (shuttingDown)
129421
129527
  return;
@@ -129426,7 +129532,7 @@ async function startDaemonChild2(registry2, opts) {
129426
129532
  if (existsSync24(RUNTIME_PID_FILE))
129427
129533
  unlinkSync9(RUNTIME_PID_FILE);
129428
129534
  } catch {}
129429
- log("INFO", "cc-bridge 已停止");
129535
+ log("INFO", "cc-linker 已停止");
129430
129536
  process.exit(0);
129431
129537
  };
129432
129538
  process.removeAllListeners("SIGTERM");
@@ -129443,12 +129549,12 @@ async function startDaemonChild2(registry2, opts) {
129443
129549
  }
129444
129550
  function getExecutablePath2() {
129445
129551
  const argv0 = process.argv[0];
129446
- if (argv0.endsWith("cc-bridge"))
129552
+ if (argv0.endsWith("cc-linker"))
129447
129553
  return argv0;
129448
- const distPath = join15(process.cwd(), "dist", "cc-bridge");
129554
+ const distPath = join15(process.cwd(), "dist", "cc-linker");
129449
129555
  if (existsSync24(distPath))
129450
129556
  return distPath;
129451
- return "cc-bridge";
129557
+ return "cc-linker";
129452
129558
  }
129453
129559
  async function startDaemon2() {
129454
129560
  const { spawn: spawn2 } = await import("child_process");
@@ -129457,7 +129563,7 @@ async function startDaemon2() {
129457
129563
  const child = spawn2(exe, args, {
129458
129564
  detached: true,
129459
129565
  stdio: "ignore",
129460
- env: { ...process.env, CC_BRIDGE_DAEMON: "1" }
129566
+ env: { ...process.env, CC_LINKER_DAEMON: "1" }
129461
129567
  });
129462
129568
  child.unref();
129463
129569
  await new Promise((r) => setTimeout(r, 1500));
@@ -129466,10 +129572,10 @@ async function startDaemon2() {
129466
129572
  process.exit(1);
129467
129573
  }
129468
129574
  const pid = readPid2();
129469
- console.log(source_default.green(`✅ cc-bridge 已在后台启动 (PID: ${pid})`));
129575
+ console.log(source_default.green(`✅ cc-linker 已在后台启动 (PID: ${pid})`));
129470
129576
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
129471
- console.log(source_default.cyan(` 停止: cc-bridge stop`));
129472
- console.log(source_default.cyan(` 状态: cc-bridge daemon status`));
129577
+ console.log(source_default.cyan(` 停止: cc-linker stop`));
129578
+ console.log(source_default.cyan(` 状态: cc-linker daemon status`));
129473
129579
  process.exit(0);
129474
129580
  }
129475
129581
  var init_start = __esm(() => {
@@ -129498,15 +129604,15 @@ import { join as join16, dirname as dirname7 } from "path";
129498
129604
  import { spawnSync as spawnSync4 } from "child_process";
129499
129605
  function getExecutablePath3() {
129500
129606
  const exe = process.argv[0];
129501
- if (exe.endsWith("cc-bridge"))
129607
+ if (exe.endsWith("cc-linker"))
129502
129608
  return exe;
129503
- return "cc-link";
129609
+ return "cc-linker";
129504
129610
  }
129505
129611
  function getMacOSPlistPath() {
129506
- return join16(HOME2, "Library", "LaunchAgents", "com.ccbridge.daemon.plist");
129612
+ return join16(HOME2, "Library", "LaunchAgents", "com.cclinker.daemon.plist");
129507
129613
  }
129508
129614
  function getLinuxServicePath() {
129509
- return join16(HOME2, ".config", "systemd", "user", "cc-bridge.service");
129615
+ return join16(HOME2, ".config", "systemd", "user", "cc-linker.service");
129510
129616
  }
129511
129617
  function generateMacOSPlist() {
129512
129618
  const exe = getExecutablePath3();
@@ -129516,7 +129622,7 @@ function generateMacOSPlist() {
129516
129622
  <plist version="1.0">
129517
129623
  <dict>
129518
129624
  <key>Label</key>
129519
- <string>com.ccbridge.daemon</string>
129625
+ <string>com.cclinker.daemon</string>
129520
129626
  <key>ProgramArguments</key>
129521
129627
  <array>
129522
129628
  <string>${exe}</string>
@@ -129545,7 +129651,7 @@ function generateLinuxService() {
129545
129651
  const exe = getExecutablePath3();
129546
129652
  const cwd = dirname7(exe) === "." ? process.cwd() : dirname7(exe);
129547
129653
  return `[Unit]
129548
- Description=cc-bridge Feishu Bot Daemon
129654
+ Description=cc-linker Feishu Bot Daemon
129549
129655
  After=network.target
129550
129656
 
129551
129657
  [Service]
@@ -129563,7 +129669,7 @@ Environment=PATH=/usr/local/bin:/usr/bin:${process.env.PATH || ""}
129563
129669
  WantedBy=default.target`;
129564
129670
  }
129565
129671
  async function installDaemon() {
129566
- console.log(source_default.blue(`=== cc-bridge 开机自启配置 ===
129672
+ console.log(source_default.blue(`=== cc-linker 开机自启配置 ===
129567
129673
  `));
129568
129674
  if (IS_MACOS) {
129569
129675
  await installMacOS();
@@ -129596,15 +129702,15 @@ async function installMacOS() {
129596
129702
  if (loadResult.status !== 0 && !loadResult.stderr.toString().includes("already loaded")) {
129597
129703
  console.log(source_default.yellow(`⚠️ launchctl load 警告: ${loadResult.stderr.toString().trim()}`));
129598
129704
  }
129599
- const startResult = spawnSync4("launchctl", ["start", "com.ccbridge.daemon"]);
129705
+ const startResult = spawnSync4("launchctl", ["start", "com.cclinker.daemon"]);
129600
129706
  console.log(source_default.green("✅ 开机自启已配置"));
129601
129707
  console.log(source_default.cyan(` 配置: ${plistPath}`));
129602
129708
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
129603
129709
  console.log(source_default.gray(`
129604
129710
  操作:`));
129605
- console.log(source_default.gray(` 停止: launchctl stop com.ccbridge.daemon`));
129606
- console.log(source_default.gray(` 卸载: cc-bridge daemon uninstall`));
129607
- console.log(source_default.gray(` 状态: cc-bridge daemon status`));
129711
+ console.log(source_default.gray(` 停止: launchctl stop com.cclinker.daemon`));
129712
+ console.log(source_default.gray(` 卸载: cc-linker daemon uninstall`));
129713
+ console.log(source_default.gray(` 状态: cc-linker daemon status`));
129608
129714
  }
129609
129715
  async function installLinux() {
129610
129716
  const servicePath = getLinuxServicePath();
@@ -129627,19 +129733,19 @@ async function installLinux() {
129627
129733
  if (reloadResult.status !== 0) {
129628
129734
  console.log(source_default.yellow(`⚠️ systemctl daemon-reload 警告: ${reloadResult.stderr.toString().trim()}`));
129629
129735
  }
129630
- const enableResult = spawnSync4("systemctl", ["--user", "enable", "cc-bridge.service"]);
129736
+ const enableResult = spawnSync4("systemctl", ["--user", "enable", "cc-linker.service"]);
129631
129737
  if (enableResult.status !== 0) {
129632
129738
  console.log(source_default.yellow(`⚠️ systemctl enable 警告: ${enableResult.stderr.toString().trim()}`));
129633
129739
  }
129634
- const startResult = spawnSync4("systemctl", ["--user", "start", "cc-bridge.service"]);
129740
+ const startResult = spawnSync4("systemctl", ["--user", "start", "cc-linker.service"]);
129635
129741
  console.log(source_default.green("✅ 开机自启已配置"));
129636
129742
  console.log(source_default.cyan(` 配置: ${servicePath}`));
129637
129743
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
129638
129744
  console.log(source_default.gray(`
129639
129745
  操作:`));
129640
- console.log(source_default.gray(` 停止: systemctl --user stop cc-bridge.service`));
129641
- console.log(source_default.gray(` 卸载: cc-bridge daemon uninstall`));
129642
- console.log(source_default.gray(` 状态: cc-bridge daemon status`));
129746
+ console.log(source_default.gray(` 停止: systemctl --user stop cc-linker.service`));
129747
+ console.log(source_default.gray(` 卸载: cc-linker daemon uninstall`));
129748
+ console.log(source_default.gray(` 状态: cc-linker daemon status`));
129643
129749
  }
129644
129750
  async function uninstallDaemon() {
129645
129751
  console.log(source_default.blue(`=== 卸载开机自启 ===
@@ -129669,25 +129775,25 @@ async function uninstallLinux() {
129669
129775
  console.log(source_default.yellow("⚠️ systemd 配置不存在"));
129670
129776
  return;
129671
129777
  }
129672
- spawnSync4("systemctl", ["--user", "disable", "cc-bridge.service"]);
129673
- spawnSync4("systemctl", ["--user", "stop", "cc-bridge.service"]);
129778
+ spawnSync4("systemctl", ["--user", "disable", "cc-linker.service"]);
129779
+ spawnSync4("systemctl", ["--user", "stop", "cc-linker.service"]);
129674
129780
  spawnSync4("systemctl", ["--user", "daemon-reload"]);
129675
129781
  unlinkSync10(servicePath);
129676
129782
  console.log(source_default.green("✅ 开机自启已卸载"));
129677
129783
  }
129678
129784
  async function daemonStatus2() {
129679
- console.log(source_default.blue(`=== cc-bridge 服务状态 ===
129785
+ console.log(source_default.blue(`=== cc-linker 服务状态 ===
129680
129786
  `));
129681
129787
  if (existsSync25(RUNTIME_PID_FILE)) {
129682
129788
  try {
129683
129789
  const pid = parseInt(readFileSync18(RUNTIME_PID_FILE, "utf8").trim(), 10);
129684
129790
  process.kill(pid, 0);
129685
- console.log(source_default.green(`✅ cc-bridge 正在运行 (PID: ${pid})`));
129791
+ console.log(source_default.green(`✅ cc-linker 正在运行 (PID: ${pid})`));
129686
129792
  } catch {
129687
- console.log(source_default.red("❌ cc-bridge PID 存在但进程不存在"));
129793
+ console.log(source_default.red("❌ cc-linker PID 存在但进程不存在"));
129688
129794
  }
129689
129795
  } else {
129690
- console.log(source_default.yellow("⚠️ cc-bridge 未在运行"));
129796
+ console.log(source_default.yellow("⚠️ cc-linker 未在运行"));
129691
129797
  }
129692
129798
  console.log(source_default.cyan(`
129693
129799
  开机自启配置:`));
@@ -129697,7 +129803,7 @@ async function daemonStatus2() {
129697
129803
  console.log(source_default.green(` ✅ launchd 已配置 (${plistPath})`));
129698
129804
  } else {
129699
129805
  console.log(source_default.gray(" ️ 未配置 launchd"));
129700
- console.log(source_default.gray(" 执行: cc-bridge daemon install"));
129806
+ console.log(source_default.gray(" 执行: cc-linker daemon install"));
129701
129807
  }
129702
129808
  } else if (IS_LINUX) {
129703
129809
  const servicePath = getLinuxServicePath();
@@ -129705,7 +129811,7 @@ async function daemonStatus2() {
129705
129811
  console.log(source_default.green(` ✅ systemd 已配置 (${servicePath})`));
129706
129812
  } else {
129707
129813
  console.log(source_default.gray(" ⏸️ 未配置 systemd"));
129708
- console.log(source_default.gray(" 执行: cc-bridge daemon install"));
129814
+ console.log(source_default.gray(" 执行: cc-linker daemon install"));
129709
129815
  }
129710
129816
  }
129711
129817
  if (existsSync25(RUNTIME_LOG_FILE)) {
@@ -129731,6 +129837,151 @@ var init_daemon = __esm(() => {
129731
129837
  IS_LINUX = platform() === "linux";
129732
129838
  });
129733
129839
 
129840
+ // src/cli/commands/init-feishu.ts
129841
+ import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync18, mkdirSync as mkdirSync14 } from "fs";
129842
+ import { dirname as dirname9 } from "path";
129843
+ import { homedir as homedir8, platform as platform3 } from "os";
129844
+ function isDaemonRunning2() {
129845
+ if (!existsSync27(RUNTIME_PID_FILE))
129846
+ return false;
129847
+ try {
129848
+ const pid = parseInt(readFileSync20(RUNTIME_PID_FILE, "utf8").trim(), 10);
129849
+ process.kill(pid, 0);
129850
+ return true;
129851
+ } catch {
129852
+ return false;
129853
+ }
129854
+ }
129855
+ async function getTenantToken2(appId, appSecret) {
129856
+ try {
129857
+ const resp = await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", {
129858
+ method: "POST",
129859
+ headers: { "Content-Type": "application/json" },
129860
+ body: JSON.stringify({ app_id: appId, app_secret: appSecret })
129861
+ });
129862
+ const data = await resp.json();
129863
+ return data.code === 0 ? data.tenant_access_token : null;
129864
+ } catch {
129865
+ return null;
129866
+ }
129867
+ }
129868
+ async function getBotName2(token) {
129869
+ try {
129870
+ const resp = await fetch("https://open.feishu.cn/open-apis/bot/v3/info", {
129871
+ headers: { Authorization: `Bearer ${token}` }
129872
+ });
129873
+ const data = await resp.json();
129874
+ return data.bot?.app_name ?? null;
129875
+ } catch {
129876
+ return null;
129877
+ }
129878
+ }
129879
+ async function captureOpenId2(appId, appSecret) {
129880
+ const Lark = await Promise.resolve().then(() => __toESM(require_lib5(), 1));
129881
+ const { WSClient, EventDispatcher, Domain, LoggerLevel } = Lark;
129882
+ return new Promise((resolve2) => {
129883
+ let settled = false;
129884
+ let wsClient = null;
129885
+ let timer = null;
129886
+ const settle = (id) => {
129887
+ if (settled)
129888
+ return;
129889
+ settled = true;
129890
+ if (timer)
129891
+ clearTimeout(timer);
129892
+ if (wsClient && typeof wsClient.close === "function") {
129893
+ try {
129894
+ wsClient.close();
129895
+ } catch {}
129896
+ }
129897
+ resolve2(id);
129898
+ };
129899
+ const eventDispatcher = new EventDispatcher({}).register({
129900
+ "im.message.receive_v1": async (data) => {
129901
+ const openId = data?.sender?.sender_id?.open_id;
129902
+ if (openId)
129903
+ settle(openId);
129904
+ }
129905
+ });
129906
+ wsClient = new WSClient({
129907
+ appId,
129908
+ appSecret,
129909
+ domain: Domain.Feishu,
129910
+ loggerLevel: LoggerLevel.warn,
129911
+ autoReconnect: false,
129912
+ onReady: () => {
129913
+ console.log(source_default.green(" ✅ WebSocket 已连接,等待消息..."));
129914
+ },
129915
+ onError: (err) => {
129916
+ console.log(source_default.red(` ❌ 连接失败: ${err.message}`));
129917
+ settle(null);
129918
+ }
129919
+ });
129920
+ wsClient.start({ eventDispatcher });
129921
+ timer = setTimeout(() => {
129922
+ console.log(source_default.yellow(" ⏰ 超时"));
129923
+ settle(null);
129924
+ }, 120000);
129925
+ });
129926
+ }
129927
+ function loadExistingConfig2() {
129928
+ if (!existsSync27(CONFIG_PATH))
129929
+ return {};
129930
+ try {
129931
+ return $parse(readFileSync20(CONFIG_PATH, "utf8"));
129932
+ } catch {
129933
+ return {};
129934
+ }
129935
+ }
129936
+ function formatTomlValue2(v) {
129937
+ if (Array.isArray(v)) {
129938
+ return `[${v.map((item) => JSON.stringify(item)).join(", ")}]`;
129939
+ }
129940
+ if (typeof v === "object" && v !== null) {
129941
+ return JSON.stringify(v);
129942
+ }
129943
+ return JSON.stringify(v);
129944
+ }
129945
+ function saveConfig2(config3) {
129946
+ const dir = dirname9(CONFIG_PATH);
129947
+ mkdirSync14(dir, { recursive: true });
129948
+ const lines = [];
129949
+ for (const section of ["general", "feishu_bot", "queue", "runtime", "security", "scanner", "cli_proxy", "hook"]) {
129950
+ const values = config3[section];
129951
+ if (!values || typeof values !== "object")
129952
+ continue;
129953
+ lines.push(`[${section}]`);
129954
+ for (const [k, v] of Object.entries(values)) {
129955
+ if (v === undefined || v === null)
129956
+ continue;
129957
+ lines.push(`${k} = ${formatTomlValue2(v)}`);
129958
+ }
129959
+ lines.push("");
129960
+ delete config3[section];
129961
+ }
129962
+ for (const [section, values] of Object.entries(config3)) {
129963
+ if (typeof values !== "object" || values === null)
129964
+ continue;
129965
+ lines.push(`[${section}]`);
129966
+ for (const [k, v] of Object.entries(values)) {
129967
+ if (v === undefined || v === null)
129968
+ continue;
129969
+ lines.push(`${k} = ${formatTomlValue2(v)}`);
129970
+ }
129971
+ lines.push("");
129972
+ }
129973
+ writeFileSync18(CONFIG_PATH, lines.join(`
129974
+ `), { mode: 384 });
129975
+ }
129976
+ var IS_MACOS3, IS_LINUX3;
129977
+ var init_init_feishu = __esm(() => {
129978
+ init_source();
129979
+ init_paths();
129980
+ init_toml();
129981
+ IS_MACOS3 = platform3() === "darwin";
129982
+ IS_LINUX3 = platform3() === "linux";
129983
+ });
129984
+
129734
129985
  // src/cli/commands/hook.ts
129735
129986
  var exports_hook = {};
129736
129987
  __export(exports_hook, {
@@ -129746,7 +129997,7 @@ function isHookInstalled2(sessionStart) {
129746
129997
  return sessionStart.some((matcher) => {
129747
129998
  if (!matcher?.hooks)
129748
129999
  return false;
129749
- return matcher.hooks.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge"));
130000
+ return matcher.hooks.some((h) => h?.command?.includes("cc-linker"));
129750
130001
  });
129751
130002
  }
129752
130003
  function hookInstall2() {
@@ -129767,12 +130018,12 @@ function hookInstall2() {
129767
130018
  return;
129768
130019
  }
129769
130020
  settings.hooks = settings.hooks ?? {};
129770
- const ccBridgeMatcher = {
130021
+ const ccLinkerMatcher = {
129771
130022
  matcher: "startup|resume|clear|compact",
129772
130023
  hooks: [
129773
130024
  {
129774
130025
  type: "command",
129775
- command: "cc-link hook session-start",
130026
+ command: "cc-linker hook session-start",
129776
130027
  timeout: 10
129777
130028
  }
129778
130029
  ]
@@ -129780,14 +130031,14 @@ function hookInstall2() {
129780
130031
  if (!Array.isArray(settings.hooks.SessionStart)) {
129781
130032
  settings.hooks.SessionStart = [];
129782
130033
  }
129783
- const existingIndex = settings.hooks.SessionStart.findIndex((m) => m?.hooks?.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge")));
130034
+ const existingIndex = settings.hooks.SessionStart.findIndex((m) => m?.hooks?.some((h) => h?.command?.includes("cc-linker") || h?.command?.includes("cc-linker")));
129784
130035
  if (existingIndex === -1) {
129785
- settings.hooks.SessionStart.push(ccBridgeMatcher);
130036
+ settings.hooks.SessionStart.push(ccLinkerMatcher);
129786
130037
  }
129787
130038
  writeFileSync19(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2), { mode: 384 });
129788
130039
  console.log(source_default.green("Hook 安装成功"));
129789
130040
  console.log(`已添加到 ${CLAUDE_SETTINGS_PATH}:`);
129790
- console.log(JSON.stringify({ hooks: { SessionStart: [ccBridgeMatcher] } }, null, 2));
130041
+ console.log(JSON.stringify({ hooks: { SessionStart: [ccLinkerMatcher] } }, null, 2));
129791
130042
  }
129792
130043
  function hookUninstall2() {
129793
130044
  if (!existsSync28(CLAUDE_SETTINGS_PATH)) {
@@ -129807,7 +130058,7 @@ function hookUninstall2() {
129807
130058
  settings.hooks.SessionStart = settings.hooks.SessionStart.filter((m) => {
129808
130059
  if (!m?.hooks)
129809
130060
  return true;
129810
- return !m.hooks.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge"));
130061
+ return !m.hooks.some((h) => h?.command?.includes("cc-linker") || h?.command?.includes("cc-linker"));
129811
130062
  });
129812
130063
  if (settings.hooks.SessionStart.length === 0) {
129813
130064
  delete settings.hooks.SessionStart;
@@ -129851,6 +130102,29 @@ var init_hook = __esm(() => {
129851
130102
  init_session_start();
129852
130103
  });
129853
130104
 
130105
+ // src/cli/commands/restart.ts
130106
+ var exports_restart = {};
130107
+ __export(exports_restart, {
130108
+ restart: () => restart
130109
+ });
130110
+ async function restart(registry2, deps = { isDaemonRunning: isDaemonRunning2, stop: stop2, start: start2 }) {
130111
+ const wasRunning = deps.isDaemonRunning();
130112
+ if (wasRunning) {
130113
+ console.log(source_default.cyan("\uD83D\uDD04 正在重启 cc-linker..."));
130114
+ await deps.stop();
130115
+ console.log(source_default.gray(" 等待进程完全停止..."));
130116
+ await new Promise((r) => setTimeout(r, 1500));
130117
+ } else {
130118
+ console.log(source_default.cyan("\uD83D\uDE80 Bot 未运行,直接启动..."));
130119
+ }
130120
+ await deps.start(registry2, { daemon: true });
130121
+ }
130122
+ var init_restart = __esm(() => {
130123
+ init_source();
130124
+ init_start();
130125
+ init_init_feishu();
130126
+ });
130127
+
129854
130128
  // node_modules/commander/esm.mjs
129855
130129
  var import__ = __toESM(require_commander(), 1);
129856
130130
  var {
@@ -129892,34 +130166,34 @@ async function syncBeforeCommand(registry2, cachePath, claudeDir, skipFlush = fa
129892
130166
  }
129893
130167
 
129894
130168
  // src/utils/errors.ts
129895
- class CCBridgeError2 extends Error {
130169
+ class CCLinkerError2 extends Error {
129896
130170
  code;
129897
130171
  details;
129898
130172
  constructor(code, message, details) {
129899
130173
  super(message);
129900
130174
  this.code = code;
129901
130175
  this.details = details;
129902
- this.name = "CCBridgeError";
130176
+ this.name = "CCLinkerError";
129903
130177
  }
129904
130178
  toString() {
129905
130179
  return `[${this.code}] ${this.message}`;
129906
130180
  }
129907
130181
  }
129908
130182
  function handleError(err) {
129909
- if (err instanceof CCBridgeError2) {
130183
+ if (err instanceof CCLinkerError2) {
129910
130184
  console.error(`错误 [${err.code}]: ${err.message}`);
129911
130185
  if (err.details) {
129912
130186
  console.error(`详情: ${JSON.stringify(err.details)}`);
129913
130187
  }
129914
130188
  const suggestions = {
129915
- E001: ["运行 cc-link init 初始化 registry"],
129916
- E002: ["会话已被清理,无法恢复", "运行 cc-link sync 重新扫描"],
129917
- E007: ["等待其他进程完成", "或删除 ~/.cc-bridge/registry.json.lock"],
130189
+ E001: ["运行 cc-linker init 初始化 registry"],
130190
+ E002: ["会话已被清理,无法恢复", "运行 cc-linker sync 重新扫描"],
130191
+ E007: ["等待其他进程完成", "或删除 ~/.cc-linker/registry.json.lock"],
129918
130192
  E008: ["会话创建目录已被删除,使用 --cwd 指定替代目录"],
129919
- E010: ["会话处于降级状态,执行 cc-link start 触发自动修复"],
130193
+ E010: ["会话处于降级状态,执行 cc-linker start 触发自动修复"],
129920
130194
  E011: ["会话仍在创建中,请稍后重试"],
129921
- E012: ["会话已损坏,请使用 /bridge switch 切换到其他会话"],
129922
- E013: ["服务正在运行,请先执行 cc-link stop 后再执行此命令"]
130195
+ E012: ["会话已损坏,请使用 /switch 切换到其他会话"],
130196
+ E013: ["服务正在运行,请先执行 cc-linker stop 后再执行此命令"]
129923
130197
  };
129924
130198
  if (suggestions[err.code]) {
129925
130199
  console.error("建议:");
@@ -130016,7 +130290,7 @@ class StateCoordinator {
130016
130290
  }
130017
130291
  static assertNotRunning(lockPath) {
130018
130292
  if (StateCoordinator.isLocked(lockPath)) {
130019
- throw new CCBridgeError("E013", "Bot 进程正在运行,请使用飞书命令操作会话,而非直接 CLI 操作");
130293
+ throw new CCLinkerError("E013", "Bot 进程正在运行,请使用飞书命令操作会话,而非直接 CLI 操作");
130020
130294
  }
130021
130295
  }
130022
130296
  isHeld() {
@@ -130047,9 +130321,9 @@ async function init(registry2) {
130047
130321
  console.log(source_default.green(`✅ Registered ${sessions.length} sessions total`));
130048
130322
  console.log(`
130049
130323
  Next steps:`);
130050
- console.log(" 1. Run 'cc-link start' to launch the Feishu bot");
130051
- console.log(" 2. Run 'cc-link list' to view all sessions");
130052
- console.log(" 3. Run 'cc-link resume' to resume a session");
130324
+ console.log(" 1. Run 'cc-linker start' to launch the Feishu bot");
130325
+ console.log(" 2. Run 'cc-linker list' to view all sessions");
130326
+ console.log(" 3. Run 'cc-linker resume' to resume a session");
130053
130327
  }
130054
130328
 
130055
130329
  // src/cli/commands/list.ts
@@ -130094,7 +130368,7 @@ async function list(registry2, opts) {
130094
130368
  }
130095
130369
  console.log(formatTable(sessions));
130096
130370
  console.log(`
130097
- 共 ${sessions.length} 个会话。使用 cc-link resume <Ref> 或完整 UUID 恢复会话。`);
130371
+ 共 ${sessions.length} 个会话。使用 cc-linker resume <Ref> 或完整 UUID 恢复会话。`);
130098
130372
  }
130099
130373
  }
130100
130374
 
@@ -130126,9 +130400,9 @@ async function resume(registry2, target, opts = {}) {
130126
130400
  if (!match) {
130127
130401
  const count = Object.keys(registry2.sessions).filter((u) => u.startsWith(target)).length;
130128
130402
  if (count > 1) {
130129
- throw new CCBridgeError("E006", `前缀 "${target}" 匹配到 ${count} 个会话,请输入更长的前缀`);
130403
+ throw new CCLinkerError("E006", `前缀 "${target}" 匹配到 ${count} 个会话,请输入更长的前缀`);
130130
130404
  }
130131
- throw new CCBridgeError("E002", `未找到匹配 "${target}" 的会话`);
130405
+ throw new CCLinkerError("E002", `未找到匹配 "${target}" 的会话`);
130132
130406
  }
130133
130407
  uuid3 = match[0];
130134
130408
  } else {
@@ -130136,7 +130410,7 @@ async function resume(registry2, target, opts = {}) {
130136
130410
  }
130137
130411
  let entry = registry2.get(uuid3);
130138
130412
  if (!entry)
130139
- throw new CCBridgeError("E002", "会话不存在");
130413
+ throw new CCLinkerError("E002", "会话不存在");
130140
130414
  entry = await attemptRepairSession(registry2, uuid3, entry);
130141
130415
  const status = entry.status ?? "active";
130142
130416
  if (status === "archived") {} else if (status in STATUS_ERRORS) {
@@ -130145,7 +130419,7 @@ async function resume(registry2, target, opts = {}) {
130145
130419
  if (status === "degraded" && entry.last_error) {
130146
130420
  msg += `, 原因: ${entry.last_error}`;
130147
130421
  }
130148
- throw new CCBridgeError(err.code, msg);
130422
+ throw new CCLinkerError(err.code, msg);
130149
130423
  }
130150
130424
  const busy = isSessionBusy(uuid3);
130151
130425
  if (busy) {
@@ -130173,7 +130447,7 @@ async function resume(registry2, target, opts = {}) {
130173
130447
  } else {
130174
130448
  registry2.upsert(uuid3, { status: "corrupted" });
130175
130449
  await registry2.flush();
130176
- throw new CCBridgeError("E002", "JSONL 文件不存在,会话可能已被清理(已标记 status=corrupted)");
130450
+ throw new CCLinkerError("E002", "JSONL 文件不存在,会话可能已被清理(已标记 status=corrupted)");
130177
130451
  }
130178
130452
  } else if (!entry.jsonl_path) {
130179
130453
  const found = findJsonlFile(uuid3);
@@ -130202,7 +130476,7 @@ async function resume(registry2, target, opts = {}) {
130202
130476
  return;
130203
130477
  }
130204
130478
  if (!existsSync8(targetCwd)) {
130205
- throw new CCBridgeError("E008", `工作目录不存在: ${targetCwd},使用 --cwd 指定替代目录`);
130479
+ throw new CCLinkerError("E008", `工作目录不存在: ${targetCwd},使用 --cwd 指定替代目录`);
130206
130480
  }
130207
130481
  console.log(source_default.green(`恢复会话: ${entry.title ?? uuid3}`));
130208
130482
  if (entry.jsonl_path && existsSync8(entry.jsonl_path)) {
@@ -130225,7 +130499,7 @@ function findLatestSession(registry2, project) {
130225
130499
  sessions = sessions.filter(([_2, s]) => s.project_name?.includes(project));
130226
130500
  }
130227
130501
  if (sessions.length === 0) {
130228
- throw new CCBridgeError("E002", "没有找到活跃会话");
130502
+ throw new CCLinkerError("E002", "没有找到活跃会话");
130229
130503
  }
130230
130504
  sessions.sort((a, b) => b[1].last_active.localeCompare(a[1].last_active));
130231
130505
  return sessions[0][0];
@@ -130233,7 +130507,7 @@ function findLatestSession(registry2, project) {
130233
130507
  async function searchAndSelect(registry2, query) {
130234
130508
  let matches = Object.entries(registry2.sessions).filter(([_2, s]) => s.title?.toLowerCase().includes(query.toLowerCase()));
130235
130509
  if (matches.length === 0) {
130236
- throw new CCBridgeError("E002", `未找到包含 "${query}" 的会话`);
130510
+ throw new CCLinkerError("E002", `未找到包含 "${query}" 的会话`);
130237
130511
  }
130238
130512
  if (matches.length === 1)
130239
130513
  return matches[0][0];
@@ -130252,7 +130526,7 @@ async function interactiveSelect(registry2) {
130252
130526
  let sessions = Object.entries(registry2.sessions).filter(([_2, s]) => !s.status || s.status === "active");
130253
130527
  sessions = sessions.sort((a, b) => b[1].last_active.localeCompare(a[1].last_active)).slice(0, 20);
130254
130528
  if (sessions.length === 0) {
130255
- throw new CCBridgeError("E002", "没有找到会话");
130529
+ throw new CCLinkerError("E002", "没有找到会话");
130256
130530
  }
130257
130531
  const { selected } = await dist_default14.prompt([{
130258
130532
  type: "list",
@@ -130319,9 +130593,9 @@ async function show(registry2, target) {
130319
130593
  if (!match) {
130320
130594
  const count = Object.keys(registry2.sessions).filter((u) => u.startsWith(target)).length;
130321
130595
  if (count > 1) {
130322
- throw new CCBridgeError("E006", `前缀 "${target}" 匹配到 ${count} 个会话,请输入更长的前缀`);
130596
+ throw new CCLinkerError("E006", `前缀 "${target}" 匹配到 ${count} 个会话,请输入更长的前缀`);
130323
130597
  }
130324
- throw new CCBridgeError("E002", `未找到匹配 "${target}" 的会话`);
130598
+ throw new CCLinkerError("E002", `未找到匹配 "${target}" 的会话`);
130325
130599
  }
130326
130600
  const [uuid3, s] = match;
130327
130601
  console.log(source_default.bold("会话详情"));
@@ -130339,7 +130613,7 @@ async function show(registry2, target) {
130339
130613
  JSONL 文件: ${s.jsonl_path}`);
130340
130614
  console.log(`
130341
130615
  操作:`);
130342
- console.log(` cc-link resume ${uuid3.slice(0, 8)} 恢复此会话`);
130616
+ console.log(` cc-linker resume ${uuid3.slice(0, 8)} 恢复此会话`);
130343
130617
  }
130344
130618
 
130345
130619
  // src/cli/commands/sync.ts
@@ -130390,7 +130664,7 @@ async function status(registry2) {
130390
130664
  const fromCli = sessions.filter((s) => s.origin === "cli").length;
130391
130665
  const fromFeishu = sessions.filter((s) => s.origin === "feishu").length;
130392
130666
  const archivedOrCorrupted = sessions.filter((s) => s.status === "archived" || s.status === "corrupted" || s.status === "degraded" || s.status === "provisioning").length;
130393
- console.log(source_default.bold("cc-link Status"));
130667
+ console.log(source_default.bold("cc-linker Status"));
130394
130668
  console.log("─".repeat(40));
130395
130669
  console.log(`Registry: ${registry2.path}`);
130396
130670
  if (existsSync10(registry2.path)) {
@@ -130412,17 +130686,17 @@ Runtime:`);
130412
130686
  const settings = JSON.parse(readFileSync9(CLAUDE_SETTINGS_PATH, "utf8"));
130413
130687
  const sessionStart = settings.hooks?.SessionStart;
130414
130688
  if (Array.isArray(sessionStart)) {
130415
- hookInstalled = sessionStart.some((matcher) => matcher?.hooks?.some((h) => h?.command?.includes("cc-link")));
130689
+ hookInstalled = sessionStart.some((matcher) => matcher?.hooks?.some((h) => h?.command?.includes("cc-linker")));
130416
130690
  }
130417
130691
  } catch {}
130418
130692
  }
130419
130693
  console.log(` Claude Code hook: ${hookInstalled ? source_default.green("installed") : source_default.red("not installed")}`);
130420
130694
  console.log(`
130421
130695
  Commands:`);
130422
- console.log(" cc-link start Launch Feishu bot");
130423
- console.log(" cc-link list List all sessions");
130424
- console.log(" cc-link resume Resume a session");
130425
- console.log(" cc-link sync Sync sessions");
130696
+ console.log(" cc-linker start Launch Feishu bot");
130697
+ console.log(" cc-linker list List all sessions");
130698
+ console.log(" cc-linker resume Resume a session");
130699
+ console.log(" cc-linker sync Sync sessions");
130426
130700
  }
130427
130701
 
130428
130702
  // src/cli/commands/hook.ts
@@ -130436,7 +130710,7 @@ function isHookInstalled(sessionStart) {
130436
130710
  return sessionStart.some((matcher) => {
130437
130711
  if (!matcher?.hooks)
130438
130712
  return false;
130439
- return matcher.hooks.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge"));
130713
+ return matcher.hooks.some((h) => h?.command?.includes("cc-linker"));
130440
130714
  });
130441
130715
  }
130442
130716
  function hookInstall() {
@@ -130457,12 +130731,12 @@ function hookInstall() {
130457
130731
  return;
130458
130732
  }
130459
130733
  settings.hooks = settings.hooks ?? {};
130460
- const ccBridgeMatcher = {
130734
+ const ccLinkerMatcher = {
130461
130735
  matcher: "startup|resume|clear|compact",
130462
130736
  hooks: [
130463
130737
  {
130464
130738
  type: "command",
130465
- command: "cc-link hook session-start",
130739
+ command: "cc-linker hook session-start",
130466
130740
  timeout: 10
130467
130741
  }
130468
130742
  ]
@@ -130470,14 +130744,14 @@ function hookInstall() {
130470
130744
  if (!Array.isArray(settings.hooks.SessionStart)) {
130471
130745
  settings.hooks.SessionStart = [];
130472
130746
  }
130473
- const existingIndex = settings.hooks.SessionStart.findIndex((m) => m?.hooks?.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge")));
130747
+ const existingIndex = settings.hooks.SessionStart.findIndex((m) => m?.hooks?.some((h) => h?.command?.includes("cc-linker") || h?.command?.includes("cc-linker")));
130474
130748
  if (existingIndex === -1) {
130475
- settings.hooks.SessionStart.push(ccBridgeMatcher);
130749
+ settings.hooks.SessionStart.push(ccLinkerMatcher);
130476
130750
  }
130477
130751
  writeFileSync9(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2), { mode: 384 });
130478
130752
  console.log(source_default.green("Hook 安装成功"));
130479
130753
  console.log(`已添加到 ${CLAUDE_SETTINGS_PATH}:`);
130480
- console.log(JSON.stringify({ hooks: { SessionStart: [ccBridgeMatcher] } }, null, 2));
130754
+ console.log(JSON.stringify({ hooks: { SessionStart: [ccLinkerMatcher] } }, null, 2));
130481
130755
  }
130482
130756
  function hookUninstall() {
130483
130757
  if (!existsSync12(CLAUDE_SETTINGS_PATH)) {
@@ -130497,7 +130771,7 @@ function hookUninstall() {
130497
130771
  settings.hooks.SessionStart = settings.hooks.SessionStart.filter((m) => {
130498
130772
  if (!m?.hooks)
130499
130773
  return true;
130500
- return !m.hooks.some((h) => h?.command?.includes("cc-link") || h?.command?.includes("cc-bridge"));
130774
+ return !m.hooks.some((h) => h?.command?.includes("cc-linker") || h?.command?.includes("cc-linker"));
130501
130775
  });
130502
130776
  if (settings.hooks.SessionStart.length === 0) {
130503
130777
  delete settings.hooks.SessionStart;
@@ -130541,11 +130815,11 @@ init_types();
130541
130815
  init_errors3();
130542
130816
  async function registerSession(registry2, uuid3, opts = {}) {
130543
130817
  if (!isValidUUID(uuid3)) {
130544
- throw new CCBridgeError("E005", `无效的 UUID 格式: ${uuid3}`);
130818
+ throw new CCLinkerError("E005", `无效的 UUID 格式: ${uuid3}`);
130545
130819
  }
130546
130820
  const originResult = OriginSchema.safeParse(opts.origin ?? "cli");
130547
130821
  if (!originResult.success) {
130548
- throw new CCBridgeError("E005", `无效的 origin 值: ${opts.origin}`);
130822
+ throw new CCLinkerError("E005", `无效的 origin 值: ${opts.origin}`);
130549
130823
  }
130550
130824
  const entry = {
130551
130825
  origin: originResult.data,
@@ -130579,9 +130853,9 @@ async function exportSession(registry2, target, opts = {}) {
130579
130853
  if (!match) {
130580
130854
  const count2 = Object.keys(registry2.sessions).filter((u) => u.startsWith(target)).length;
130581
130855
  if (count2 > 1) {
130582
- throw new CCBridgeError("E006", `前缀 "${target}" 匹配到 ${count2} 个会话,请输入更长的前缀`);
130856
+ throw new CCLinkerError("E006", `前缀 "${target}" 匹配到 ${count2} 个会话,请输入更长的前缀`);
130583
130857
  }
130584
- throw new CCBridgeError("E002", `未找到匹配 "${target}" 的会话`);
130858
+ throw new CCLinkerError("E002", `未找到匹配 "${target}" 的会话`);
130585
130859
  }
130586
130860
  const [uuid3, entry] = match;
130587
130861
  const format = opts.format ?? "markdown";
@@ -130589,11 +130863,11 @@ async function exportSession(registry2, target, opts = {}) {
130589
130863
  const maxMessages = opts.maxMessages ? (() => {
130590
130864
  const n = parseInt(opts.maxMessages, 10);
130591
130865
  if (isNaN(n))
130592
- throw new CCBridgeError("E005", `无效的消息数: ${opts.maxMessages}`);
130866
+ throw new CCLinkerError("E005", `无效的消息数: ${opts.maxMessages}`);
130593
130867
  return n;
130594
130868
  })() : undefined;
130595
130869
  if (!entry.jsonl_path || !existsSync13(entry.jsonl_path)) {
130596
- throw new CCBridgeError("E002", `JSONL 文件不存在: ${entry.jsonl_path ?? uuid3}`);
130870
+ throw new CCLinkerError("E002", `JSONL 文件不存在: ${entry.jsonl_path ?? uuid3}`);
130597
130871
  }
130598
130872
  const stat = statSync3(entry.jsonl_path);
130599
130873
  if (stat.size > MAX_FILE_SIZE) {
@@ -130706,7 +130980,7 @@ async function exportSession(registry2, target, opts = {}) {
130706
130980
  await new Promise((resolve, reject) => {
130707
130981
  writeStream.on("close", () => {
130708
130982
  if (writeError)
130709
- reject(new CCBridgeError("E010", `写入文件失败: ${writeError}`));
130983
+ reject(new CCLinkerError("E010", `写入文件失败: ${writeError}`));
130710
130984
  else
130711
130985
  resolve();
130712
130986
  });
@@ -130800,7 +131074,7 @@ async function clean(registry2, opts = {}) {
130800
131074
  const olderThanDays = opts.olderThan ? (() => {
130801
131075
  const n = parseInt(opts.olderThan, 10);
130802
131076
  if (isNaN(n))
130803
- throw new CCBridgeError("E005", `无效的天数: ${opts.olderThan}`);
131077
+ throw new CCLinkerError("E005", `无效的天数: ${opts.olderThan}`);
130804
131078
  return n;
130805
131079
  })() : undefined;
130806
131080
  const cutoff = olderThanDays ? new Date(Date.now() - olderThanDays * 24 * 60 * 60 * 1000).toISOString() : null;
@@ -130849,7 +131123,7 @@ import { dirname as dirname5, join as join14 } from "path";
130849
131123
  import { homedir as homedir4 } from "os";
130850
131124
  import { spawnSync as spawnSync2 } from "child_process";
130851
131125
  async function start(registry2, opts = {}) {
130852
- if (process.env.CC_BRIDGE_DAEMON === "1") {
131126
+ if (process.env.CC_LINKER_DAEMON === "1") {
130853
131127
  await startDaemonChild(registry2, opts);
130854
131128
  return;
130855
131129
  }
@@ -130857,7 +131131,7 @@ async function start(registry2, opts = {}) {
130857
131131
  if (isRunning()) {
130858
131132
  const pid = readPid();
130859
131133
  console.log(source_default.yellow(`⚠️ Bot 已在后台运行 (PID: ${pid})`));
130860
- console.log(source_default.cyan(` 停止: cc-bridge stop`));
131134
+ console.log(source_default.cyan(` 停止: cc-linker stop`));
130861
131135
  return;
130862
131136
  }
130863
131137
  await startDaemon();
@@ -130865,7 +131139,7 @@ async function start(registry2, opts = {}) {
130865
131139
  }
130866
131140
  const sc = new StateCoordinator2;
130867
131141
  if (StateCoordinator2.isLocked()) {
130868
- console.log(source_default.red("❌ Bot 进程正在运行,请先执行 cc-bridge stop"));
131142
+ console.log(source_default.red("❌ Bot 进程正在运行,请先执行 cc-linker stop"));
130869
131143
  process.exit(1);
130870
131144
  }
130871
131145
  await startForeground(registry2, opts);
@@ -130886,7 +131160,7 @@ function readPid() {
130886
131160
  }
130887
131161
  async function stop() {
130888
131162
  let stopped = false;
130889
- const plistPath = join14(homedir4(), "Library", "LaunchAgents", "com.ccbridge.daemon.plist");
131163
+ const plistPath = join14(homedir4(), "Library", "LaunchAgents", "com.cclinker.daemon.plist");
130890
131164
  if (existsSync23(plistPath)) {
130891
131165
  try {
130892
131166
  spawnSync2("launchctl", ["unload", plistPath]);
@@ -130927,7 +131201,7 @@ async function stop() {
130927
131201
  }
130928
131202
  try {
130929
131203
  const { execSync } = await import("child_process");
130930
- const pids = execSync("pgrep -f 'cc-bridge.*daemon' 2>/dev/null || true", { encoding: "utf8" }).trim().split(`
131204
+ const pids = execSync("pgrep -f 'cc-linker.*daemon' 2>/dev/null || true", { encoding: "utf8" }).trim().split(`
130931
131205
  `).filter(Boolean);
130932
131206
  for (const pidStr of pids) {
130933
131207
  const p = parseInt(pidStr, 10);
@@ -131140,7 +131414,7 @@ async function createBotRuntime(registry2, log, wsLogLevel) {
131140
131414
  return { bot, wsClient, stateCoordinator: stateCoordinator3, shutdown };
131141
131415
  }
131142
131416
  async function startForeground(registry2, opts) {
131143
- console.log(source_default.blue("\uD83D\uDE80 启动 cc-bridge..."));
131417
+ console.log(source_default.blue("\uD83D\uDE80 启动 cc-linker..."));
131144
131418
  const { bot, stateCoordinator: stateCoordinator3, shutdown } = await createBotRuntime(registry2, (level, msg) => {
131145
131419
  if (level === "ERROR") {
131146
131420
  console.error(source_default.red(msg));
@@ -131155,7 +131429,7 @@ async function startForeground(registry2, opts) {
131155
131429
  logger.info(msg);
131156
131430
  }
131157
131431
  });
131158
- console.log(source_default.green("✅ cc-bridge 已启动"));
131432
+ console.log(source_default.green("✅ cc-linker 已启动"));
131159
131433
  let shuttingDown = false;
131160
131434
  const gracefulShutdown = async (signal) => {
131161
131435
  if (shuttingDown)
@@ -131164,7 +131438,7 @@ async function startForeground(registry2, opts) {
131164
131438
  console.log(source_default.yellow(`
131165
131439
  收到 ${signal},优雅停机中...`));
131166
131440
  await shutdown(signal);
131167
- logger.info("cc-bridge 已停止");
131441
+ logger.info("cc-linker 已停止");
131168
131442
  process.exit(0);
131169
131443
  };
131170
131444
  process.on("SIGINT", () => gracefulShutdown("SIGINT"));
@@ -131205,13 +131479,13 @@ async function startDaemonChild(registry2, opts) {
131205
131479
  if (existsSync23(RUNTIME_PID_FILE))
131206
131480
  unlinkSync8(RUNTIME_PID_FILE);
131207
131481
  } catch {}
131208
- log("INFO", "cc-bridge 已停止");
131482
+ log("INFO", "cc-linker 已停止");
131209
131483
  process.exit(0);
131210
131484
  };
131211
131485
  process.on("SIGTERM", () => baseShutdown("SIGTERM"));
131212
131486
  process.on("SIGINT", () => baseShutdown("SIGINT"));
131213
131487
  const { bot, shutdown } = await createBotRuntime(registry2, log);
131214
- log("INFO", "cc-bridge daemon started");
131488
+ log("INFO", "cc-linker daemon started");
131215
131489
  const daemonShutdown = async (signal) => {
131216
131490
  if (shuttingDown)
131217
131491
  return;
@@ -131222,7 +131496,7 @@ async function startDaemonChild(registry2, opts) {
131222
131496
  if (existsSync23(RUNTIME_PID_FILE))
131223
131497
  unlinkSync8(RUNTIME_PID_FILE);
131224
131498
  } catch {}
131225
- log("INFO", "cc-bridge 已停止");
131499
+ log("INFO", "cc-linker 已停止");
131226
131500
  process.exit(0);
131227
131501
  };
131228
131502
  process.removeAllListeners("SIGTERM");
@@ -131239,12 +131513,12 @@ async function startDaemonChild(registry2, opts) {
131239
131513
  }
131240
131514
  function getExecutablePath() {
131241
131515
  const argv0 = process.argv[0];
131242
- if (argv0.endsWith("cc-bridge"))
131516
+ if (argv0.endsWith("cc-linker"))
131243
131517
  return argv0;
131244
- const distPath = join14(process.cwd(), "dist", "cc-bridge");
131518
+ const distPath = join14(process.cwd(), "dist", "cc-linker");
131245
131519
  if (existsSync23(distPath))
131246
131520
  return distPath;
131247
- return "cc-bridge";
131521
+ return "cc-linker";
131248
131522
  }
131249
131523
  async function startDaemon() {
131250
131524
  const { spawn: spawn2 } = await import("child_process");
@@ -131253,7 +131527,7 @@ async function startDaemon() {
131253
131527
  const child = spawn2(exe, args, {
131254
131528
  detached: true,
131255
131529
  stdio: "ignore",
131256
- env: { ...process.env, CC_BRIDGE_DAEMON: "1" }
131530
+ env: { ...process.env, CC_LINKER_DAEMON: "1" }
131257
131531
  });
131258
131532
  child.unref();
131259
131533
  await new Promise((r) => setTimeout(r, 1500));
@@ -131262,10 +131536,10 @@ async function startDaemon() {
131262
131536
  process.exit(1);
131263
131537
  }
131264
131538
  const pid = readPid();
131265
- console.log(source_default.green(`✅ cc-bridge 已在后台启动 (PID: ${pid})`));
131539
+ console.log(source_default.green(`✅ cc-linker 已在后台启动 (PID: ${pid})`));
131266
131540
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
131267
- console.log(source_default.cyan(` 停止: cc-bridge stop`));
131268
- console.log(source_default.cyan(` 状态: cc-bridge daemon status`));
131541
+ console.log(source_default.cyan(` 停止: cc-linker stop`));
131542
+ console.log(source_default.cyan(` 状态: cc-linker daemon status`));
131269
131543
  process.exit(0);
131270
131544
  }
131271
131545
 
@@ -131282,10 +131556,10 @@ import { spawnSync as spawnSync5 } from "child_process";
131282
131556
  var IS_MACOS2 = platform2() === "darwin";
131283
131557
  var IS_LINUX2 = platform2() === "linux";
131284
131558
  function getMacOSPlistPath2() {
131285
- return join17(homedir7(), "Library", "LaunchAgents", "com.ccbridge.daemon.plist");
131559
+ return join17(homedir7(), "Library", "LaunchAgents", "com.cclinker.daemon.plist");
131286
131560
  }
131287
131561
  function getLinuxServicePath2() {
131288
- return join17(homedir7(), ".config", "systemd", "user", "cc-bridge.service");
131562
+ return join17(homedir7(), ".config", "systemd", "user", "cc-linker.service");
131289
131563
  }
131290
131564
  function isDaemonRunning() {
131291
131565
  if (!existsSync26(RUNTIME_PID_FILE))
@@ -131312,7 +131586,7 @@ function disableAutoStartTemporarily() {
131312
131586
  spawnSync5("launchctl", ["unload", plistPath]);
131313
131587
  }
131314
131588
  } else if (IS_LINUX2) {
131315
- spawnSync5("systemctl", ["--user", "stop", "cc-bridge.service"]);
131589
+ spawnSync5("systemctl", ["--user", "stop", "cc-linker.service"]);
131316
131590
  }
131317
131591
  }
131318
131592
  async function getTenantToken(appId, appSecret) {
@@ -131437,7 +131711,7 @@ function saveConfig(config3) {
131437
131711
  `), { mode: 384 });
131438
131712
  }
131439
131713
  async function initFeishu() {
131440
- console.log(source_default.blue(`=== cc-bridge 飞书配置向导 ===
131714
+ console.log(source_default.blue(`=== cc-linker 飞书配置向导 ===
131441
131715
  `));
131442
131716
  let skipCapture = false;
131443
131717
  if (isDaemonRunning()) {
@@ -131507,7 +131781,7 @@ async function initFeishu() {
131507
131781
  const { manualId } = await dist_default14.prompt([{
131508
131782
  type: "input",
131509
131783
  name: "manualId",
131510
- message: "请输入 owner_open_id(在飞书发送 /bridge whoami 可获取):",
131784
+ message: "请输入 owner_open_id(在飞书发送 /whoami 可获取):",
131511
131785
  default: feishu.owner_open_id || undefined,
131512
131786
  validate: (v) => v.trim() ? true : "open_id 不能为空"
131513
131787
  }]);
@@ -131539,8 +131813,8 @@ async function initFeishu() {
131539
131813
  const { defaultCwd } = await dist_default14.prompt([{
131540
131814
  type: "input",
131541
131815
  name: "defaultCwd",
131542
- message: "默认工作目录(/bridge new 未指定路径时使用):",
131543
- default: feishu.default_cwd || "~/Git/cc-bridge"
131816
+ message: "默认工作目录(/new 未指定路径时使用):",
131817
+ default: feishu.default_cwd || "~/Git/cc-linker"
131544
131818
  }]);
131545
131819
  existing.feishu_bot = {
131546
131820
  app_id: appId.trim(),
@@ -131574,12 +131848,12 @@ async function initFeishu() {
131574
131848
  if (startNow) {
131575
131849
  console.log(source_default.cyan(`
131576
131850
  启动 Bot 服务...`));
131577
- let exePath = "cc-bridge";
131851
+ let exePath = "cc-linker";
131578
131852
  const argv0 = process.argv[0];
131579
- if (argv0.endsWith("cc-bridge")) {
131853
+ if (argv0.endsWith("cc-linker")) {
131580
131854
  exePath = argv0;
131581
131855
  } else {
131582
- const distPath = join17(process.cwd(), "dist", "cc-bridge");
131856
+ const distPath = join17(process.cwd(), "dist", "cc-linker");
131583
131857
  if (existsSync26(distPath))
131584
131858
  exePath = distPath;
131585
131859
  }
@@ -131588,9 +131862,9 @@ async function initFeishu() {
131588
131862
  });
131589
131863
  if (result.status === 0) {
131590
131864
  botStarted = true;
131591
- console.log(source_default.gray("运行 cc-link list 可查看会话"));
131865
+ console.log(source_default.gray("运行 cc-linker list 可查看会话"));
131592
131866
  } else {
131593
- console.log(source_default.yellow("⚠️ 自动启动失败,请手动执行: cc-link start --daemon"));
131867
+ console.log(source_default.yellow("⚠️ 自动启动失败,请手动执行: cc-linker start --daemon"));
131594
131868
  }
131595
131869
  }
131596
131870
  const { autoStart } = await dist_default14.prompt([{
@@ -131612,10 +131886,10 @@ async function initFeishu() {
131612
131886
  console.log(source_default.gray(` 开机自启: ${autoStart ? "已配置" : "未配置"}`));
131613
131887
  console.log(source_default.cyan(`
131614
131888
  常用命令:`));
131615
- console.log(source_default.white(" cc-link list — 查看会话"));
131616
- console.log(source_default.white(" cc-link daemon status — 查看服务状态"));
131617
- console.log(source_default.white(" cc-link daemon uninstall — 移除开机自启"));
131618
- console.log(source_default.white(" cc-link stop — 停止 Bot 服务"));
131889
+ console.log(source_default.white(" cc-linker list — 查看会话"));
131890
+ console.log(source_default.white(" cc-linker daemon status — 查看服务状态"));
131891
+ console.log(source_default.white(" cc-linker daemon uninstall — 移除开机自启"));
131892
+ console.log(source_default.white(" cc-linker stop — 停止 Bot 服务"));
131619
131893
  process.exit(0);
131620
131894
  }
131621
131895
 
@@ -131624,151 +131898,8 @@ init_source();
131624
131898
  init_dist18();
131625
131899
  init_scanner();
131626
131900
  init_paths();
131901
+ init_init_feishu();
131627
131902
  import { existsSync as existsSync29, readFileSync as readFileSync22 } from "fs";
131628
-
131629
- // src/cli/commands/init-feishu.ts
131630
- init_source();
131631
- init_paths();
131632
- init_toml();
131633
- import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync18, mkdirSync as mkdirSync14 } from "fs";
131634
- import { dirname as dirname9 } from "path";
131635
- import { homedir as homedir8, platform as platform3 } from "os";
131636
- var IS_MACOS3 = platform3() === "darwin";
131637
- var IS_LINUX3 = platform3() === "linux";
131638
- function isDaemonRunning2() {
131639
- if (!existsSync27(RUNTIME_PID_FILE))
131640
- return false;
131641
- try {
131642
- const pid = parseInt(readFileSync20(RUNTIME_PID_FILE, "utf8").trim(), 10);
131643
- process.kill(pid, 0);
131644
- return true;
131645
- } catch {
131646
- return false;
131647
- }
131648
- }
131649
- async function getTenantToken2(appId, appSecret) {
131650
- try {
131651
- const resp = await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", {
131652
- method: "POST",
131653
- headers: { "Content-Type": "application/json" },
131654
- body: JSON.stringify({ app_id: appId, app_secret: appSecret })
131655
- });
131656
- const data = await resp.json();
131657
- return data.code === 0 ? data.tenant_access_token : null;
131658
- } catch {
131659
- return null;
131660
- }
131661
- }
131662
- async function getBotName2(token) {
131663
- try {
131664
- const resp = await fetch("https://open.feishu.cn/open-apis/bot/v3/info", {
131665
- headers: { Authorization: `Bearer ${token}` }
131666
- });
131667
- const data = await resp.json();
131668
- return data.bot?.app_name ?? null;
131669
- } catch {
131670
- return null;
131671
- }
131672
- }
131673
- async function captureOpenId2(appId, appSecret) {
131674
- const Lark = await Promise.resolve().then(() => __toESM(require_lib5(), 1));
131675
- const { WSClient, EventDispatcher, Domain, LoggerLevel } = Lark;
131676
- return new Promise((resolve2) => {
131677
- let settled = false;
131678
- let wsClient = null;
131679
- let timer = null;
131680
- const settle = (id) => {
131681
- if (settled)
131682
- return;
131683
- settled = true;
131684
- if (timer)
131685
- clearTimeout(timer);
131686
- if (wsClient && typeof wsClient.close === "function") {
131687
- try {
131688
- wsClient.close();
131689
- } catch {}
131690
- }
131691
- resolve2(id);
131692
- };
131693
- const eventDispatcher = new EventDispatcher({}).register({
131694
- "im.message.receive_v1": async (data) => {
131695
- const openId = data?.sender?.sender_id?.open_id;
131696
- if (openId)
131697
- settle(openId);
131698
- }
131699
- });
131700
- wsClient = new WSClient({
131701
- appId,
131702
- appSecret,
131703
- domain: Domain.Feishu,
131704
- loggerLevel: LoggerLevel.warn,
131705
- autoReconnect: false,
131706
- onReady: () => {
131707
- console.log(source_default.green(" ✅ WebSocket 已连接,等待消息..."));
131708
- },
131709
- onError: (err) => {
131710
- console.log(source_default.red(` ❌ 连接失败: ${err.message}`));
131711
- settle(null);
131712
- }
131713
- });
131714
- wsClient.start({ eventDispatcher });
131715
- timer = setTimeout(() => {
131716
- console.log(source_default.yellow(" ⏰ 超时"));
131717
- settle(null);
131718
- }, 120000);
131719
- });
131720
- }
131721
- function loadExistingConfig2() {
131722
- if (!existsSync27(CONFIG_PATH))
131723
- return {};
131724
- try {
131725
- return $parse(readFileSync20(CONFIG_PATH, "utf8"));
131726
- } catch {
131727
- return {};
131728
- }
131729
- }
131730
- function formatTomlValue2(v) {
131731
- if (Array.isArray(v)) {
131732
- return `[${v.map((item) => JSON.stringify(item)).join(", ")}]`;
131733
- }
131734
- if (typeof v === "object" && v !== null) {
131735
- return JSON.stringify(v);
131736
- }
131737
- return JSON.stringify(v);
131738
- }
131739
- function saveConfig2(config3) {
131740
- const dir = dirname9(CONFIG_PATH);
131741
- mkdirSync14(dir, { recursive: true });
131742
- const lines = [];
131743
- for (const section of ["general", "feishu_bot", "queue", "runtime", "security", "scanner", "cli_proxy", "hook"]) {
131744
- const values = config3[section];
131745
- if (!values || typeof values !== "object")
131746
- continue;
131747
- lines.push(`[${section}]`);
131748
- for (const [k, v] of Object.entries(values)) {
131749
- if (v === undefined || v === null)
131750
- continue;
131751
- lines.push(`${k} = ${formatTomlValue2(v)}`);
131752
- }
131753
- lines.push("");
131754
- delete config3[section];
131755
- }
131756
- for (const [section, values] of Object.entries(config3)) {
131757
- if (typeof values !== "object" || values === null)
131758
- continue;
131759
- lines.push(`[${section}]`);
131760
- for (const [k, v] of Object.entries(values)) {
131761
- if (v === undefined || v === null)
131762
- continue;
131763
- lines.push(`${k} = ${formatTomlValue2(v)}`);
131764
- }
131765
- lines.push("");
131766
- }
131767
- writeFileSync18(CONFIG_PATH, lines.join(`
131768
- `), { mode: 384 });
131769
- }
131770
-
131771
- // src/cli/commands/setup.ts
131772
131903
  function isHookInstalled3() {
131773
131904
  if (!existsSync29(CLAUDE_SETTINGS_PATH))
131774
131905
  return false;
@@ -131776,7 +131907,7 @@ function isHookInstalled3() {
131776
131907
  const settings = JSON.parse(readFileSync22(CLAUDE_SETTINGS_PATH, "utf8"));
131777
131908
  if (!Array.isArray(settings.hooks?.SessionStart))
131778
131909
  return false;
131779
- return settings.hooks.SessionStart.some((matcher) => matcher?.hooks?.some((h) => h?.command?.includes("cc-bridge")));
131910
+ return settings.hooks.SessionStart.some((matcher) => matcher?.hooks?.some((h) => h?.command?.includes("cc-linker")));
131780
131911
  } catch {
131781
131912
  return false;
131782
131913
  }
@@ -131784,7 +131915,7 @@ function isHookInstalled3() {
131784
131915
  async function setup(registry2, opts = {}) {
131785
131916
  const totalSteps = opts.skipFeishu ? 2 : 3;
131786
131917
  console.log(source_default.blue("═══════════════════════════════════════════"));
131787
- console.log(source_default.blue(" cc-link 一键配置向导"));
131918
+ console.log(source_default.blue(" cc-linker 一键配置向导"));
131788
131919
  console.log(source_default.blue(`═══════════════════════════════════════════
131789
131920
  `));
131790
131921
  console.log(source_default.gray("本向导将引导你完成以下配置:"));
@@ -131815,7 +131946,7 @@ async function setup(registry2, opts = {}) {
131815
131946
  hookInstalled = true;
131816
131947
  } catch (err) {
131817
131948
  console.log(source_default.red(` ❌ Hook 安装失败: ${err}`));
131818
- console.log(source_default.yellow(" 提示:你可以稍后手动执行 cc-link hook install"));
131949
+ console.log(source_default.yellow(" 提示:你可以稍后手动执行 cc-linker hook install"));
131819
131950
  }
131820
131951
  }
131821
131952
  console.log("");
@@ -131840,7 +131971,7 @@ async function setup(registry2, opts = {}) {
131840
131971
  feishuResult = { configured: true, appId: existingAppId, started: isDaemonRunning2(), autoStart: false };
131841
131972
  console.log(source_default.green(" ✅ 使用现有飞书配置"));
131842
131973
  } else {
131843
- feishuResult = await runFeishuWizard();
131974
+ feishuResult = await runFeishuWizard(existingAppId, existingAppSecret);
131844
131975
  }
131845
131976
  } else {
131846
131977
  const { setupFeishu } = await dist_default14.prompt([{
@@ -131858,8 +131989,9 @@ async function setup(registry2, opts = {}) {
131858
131989
  console.log("");
131859
131990
  }
131860
131991
  printSummary(sessionCount, hookInstalled, feishuResult);
131992
+ process.exit(0);
131861
131993
  }
131862
- async function runFeishuWizard() {
131994
+ async function runFeishuWizard(existingAppId = "", existingAppSecret = "") {
131863
131995
  const result = { configured: false, appId: "", started: false, autoStart: false };
131864
131996
  let skipCapture = false;
131865
131997
  if (isDaemonRunning2()) {
@@ -131894,12 +132026,14 @@ async function runFeishuWizard() {
131894
132026
  type: "input",
131895
132027
  name: "appId",
131896
132028
  message: "飞书 App ID:",
132029
+ default: existingAppId || undefined,
131897
132030
  validate: (v) => v.trim() ? true : "App ID 不能为空"
131898
132031
  }]);
131899
132032
  const { appSecret } = await dist_default14.prompt([{
131900
132033
  type: "input",
131901
132034
  name: "appSecret",
131902
132035
  message: "飞书 App Secret:",
132036
+ default: existingAppSecret || undefined,
131903
132037
  validate: (v) => v.trim() ? true : "App Secret 不能为空"
131904
132038
  }]);
131905
132039
  console.log(source_default.gray(" 验证凭据..."));
@@ -131919,7 +132053,7 @@ async function runFeishuWizard() {
131919
132053
  const { manualId } = await dist_default14.prompt([{
131920
132054
  type: "input",
131921
132055
  name: "manualId",
131922
- message: "请输入 owner_open_id(在飞书发送 /bridge whoami 可获取):",
132056
+ message: "请输入 owner_open_id(在飞书发送 /whoami 可获取):",
131923
132057
  validate: (v) => v.trim() ? true : "open_id 不能为空"
131924
132058
  }]);
131925
132059
  openId = manualId.trim();
@@ -131949,7 +132083,7 @@ async function runFeishuWizard() {
131949
132083
  const { defaultCwd } = await dist_default14.prompt([{
131950
132084
  type: "input",
131951
132085
  name: "defaultCwd",
131952
- message: "默认工作目录(/bridge new 未指定路径时使用):",
132086
+ message: "默认工作目录(/new 未指定路径时使用):",
131953
132087
  default: process.env.HOME || "~/Git"
131954
132088
  }]);
131955
132089
  const existing = loadExistingConfig2();
@@ -131976,12 +132110,12 @@ async function runFeishuWizard() {
131976
132110
  const { spawnSync: spawnSync6 } = await import("child_process");
131977
132111
  const { join: join18 } = await import("path");
131978
132112
  const { existsSync: existsSync30 } = await import("fs");
131979
- let exePath = "cc-bridge";
132113
+ let exePath = "cc-linker";
131980
132114
  const argv0 = process.argv[0];
131981
- if (argv0.endsWith("cc-bridge")) {
132115
+ if (argv0.endsWith("cc-linker")) {
131982
132116
  exePath = argv0;
131983
132117
  } else {
131984
- const distPath = join18(process.cwd(), "dist", "cc-bridge");
132118
+ const distPath = join18(process.cwd(), "dist", "cc-linker");
131985
132119
  if (existsSync30(distPath))
131986
132120
  exePath = distPath;
131987
132121
  }
@@ -131990,7 +132124,7 @@ async function runFeishuWizard() {
131990
132124
  if (result.started) {
131991
132125
  console.log(source_default.green(" ✅ Bot 已启动"));
131992
132126
  } else {
131993
- console.log(source_default.yellow(" ⚠️ 自动启动失败,请手动执行: cc-link start --daemon"));
132127
+ console.log(source_default.yellow(" ⚠️ 自动启动失败,请手动执行: cc-linker start --daemon"));
131994
132128
  }
131995
132129
  }
131996
132130
  const { autoStart } = await dist_default14.prompt([{
@@ -132044,25 +132178,25 @@ function printSummary(sessionCount, hookInstalled, feishu) {
132044
132178
  console.log(source_default.gray(` Claude Code 钩子: ${hookInstalled ? "✅ 已安装" : "⏸️ 未安装"}`));
132045
132179
  if (feishu.configured) {
132046
132180
  console.log(source_default.gray(` 飞书 Bot: ✅ 已配置 (App ID: ${feishu.appId.slice(0, 6)}****)`));
132047
- console.log(source_default.gray(` Bot 运行: ${feishu.started ? "✅ 运行中" : "⏸️ 未启动 (cc-link start --daemon)"}`));
132181
+ console.log(source_default.gray(` Bot 运行: ${feishu.started ? "✅ 运行中" : "⏸️ 未启动 (cc-linker start --daemon)"}`));
132048
132182
  } else {
132049
132183
  console.log(source_default.gray(" 飞书 Bot: ⏸️ 未配置(终端侧功能已就绪)"));
132050
132184
  }
132051
132185
  console.log("");
132052
132186
  console.log(source_default.cyan(" 常用命令:"));
132053
- console.log(source_default.white(" cc-link list — 查看会话"));
132054
- console.log(source_default.white(" cc-link resume <ID> — 恢复会话到终端"));
132055
- console.log(source_default.white(" cc-link daemon status — 查看 Bot 状态"));
132056
- console.log(source_default.white(" cc-link daemon uninstall — 移除开机自启"));
132057
- console.log(source_default.white(" cc-link stop — 停止 Bot 服务"));
132187
+ console.log(source_default.white(" cc-linker list — 查看会话"));
132188
+ console.log(source_default.white(" cc-linker resume <ID> — 恢复会话到终端"));
132189
+ console.log(source_default.white(" cc-linker daemon status — 查看 Bot 状态"));
132190
+ console.log(source_default.white(" cc-linker daemon uninstall — 移除开机自启"));
132191
+ console.log(source_default.white(" cc-linker stop — 停止 Bot 服务"));
132058
132192
  console.log("");
132059
132193
  if (feishu.configured) {
132060
132194
  console.log(source_default.cyan(" 飞书端可用命令:"));
132061
- console.log(source_default.white(" /bridge list — 列出会话"));
132062
- console.log(source_default.white(" /bridge new [路径] -- 提示 — 创建新会话"));
132063
- console.log(source_default.white(" /bridge switch <序号> — 切换会话"));
132064
- console.log(source_default.white(" /bridge model — 管理模型"));
132065
- console.log(source_default.white(" /bridge status — 查看状态"));
132195
+ console.log(source_default.white(" /list — 列出会话"));
132196
+ console.log(source_default.white(" /new [路径] -- 提示 — 创建新会话"));
132197
+ console.log(source_default.white(" /switch <序号> — 切换会话"));
132198
+ console.log(source_default.white(" /model — 管理模型"));
132199
+ console.log(source_default.white(" /status — 查看状态"));
132066
132200
  console.log("");
132067
132201
  }
132068
132202
  }
@@ -132080,15 +132214,15 @@ var IS_MACOS4 = platform4() === "darwin";
132080
132214
  var IS_LINUX4 = platform4() === "linux";
132081
132215
  function getExecutablePath4() {
132082
132216
  const exe = process.argv[0];
132083
- if (exe.endsWith("cc-bridge"))
132217
+ if (exe.endsWith("cc-linker"))
132084
132218
  return exe;
132085
- return "cc-link";
132219
+ return "cc-linker";
132086
132220
  }
132087
132221
  function getMacOSPlistPath3() {
132088
- return join18(HOME3, "Library", "LaunchAgents", "com.ccbridge.daemon.plist");
132222
+ return join18(HOME3, "Library", "LaunchAgents", "com.cclinker.daemon.plist");
132089
132223
  }
132090
132224
  function getLinuxServicePath3() {
132091
- return join18(HOME3, ".config", "systemd", "user", "cc-bridge.service");
132225
+ return join18(HOME3, ".config", "systemd", "user", "cc-linker.service");
132092
132226
  }
132093
132227
  function generateMacOSPlist2() {
132094
132228
  const exe = getExecutablePath4();
@@ -132098,7 +132232,7 @@ function generateMacOSPlist2() {
132098
132232
  <plist version="1.0">
132099
132233
  <dict>
132100
132234
  <key>Label</key>
132101
- <string>com.ccbridge.daemon</string>
132235
+ <string>com.cclinker.daemon</string>
132102
132236
  <key>ProgramArguments</key>
132103
132237
  <array>
132104
132238
  <string>${exe}</string>
@@ -132127,7 +132261,7 @@ function generateLinuxService2() {
132127
132261
  const exe = getExecutablePath4();
132128
132262
  const cwd = dirname10(exe) === "." ? process.cwd() : dirname10(exe);
132129
132263
  return `[Unit]
132130
- Description=cc-bridge Feishu Bot Daemon
132264
+ Description=cc-linker Feishu Bot Daemon
132131
132265
  After=network.target
132132
132266
 
132133
132267
  [Service]
@@ -132145,7 +132279,7 @@ Environment=PATH=/usr/local/bin:/usr/bin:${process.env.PATH || ""}
132145
132279
  WantedBy=default.target`;
132146
132280
  }
132147
132281
  async function installDaemon2() {
132148
- console.log(source_default.blue(`=== cc-bridge 开机自启配置 ===
132282
+ console.log(source_default.blue(`=== cc-linker 开机自启配置 ===
132149
132283
  `));
132150
132284
  if (IS_MACOS4) {
132151
132285
  await installMacOS2();
@@ -132178,15 +132312,15 @@ async function installMacOS2() {
132178
132312
  if (loadResult.status !== 0 && !loadResult.stderr.toString().includes("already loaded")) {
132179
132313
  console.log(source_default.yellow(`⚠️ launchctl load 警告: ${loadResult.stderr.toString().trim()}`));
132180
132314
  }
132181
- const startResult = spawnSync6("launchctl", ["start", "com.ccbridge.daemon"]);
132315
+ const startResult = spawnSync6("launchctl", ["start", "com.cclinker.daemon"]);
132182
132316
  console.log(source_default.green("✅ 开机自启已配置"));
132183
132317
  console.log(source_default.cyan(` 配置: ${plistPath}`));
132184
132318
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
132185
132319
  console.log(source_default.gray(`
132186
132320
  操作:`));
132187
- console.log(source_default.gray(` 停止: launchctl stop com.ccbridge.daemon`));
132188
- console.log(source_default.gray(` 卸载: cc-bridge daemon uninstall`));
132189
- console.log(source_default.gray(` 状态: cc-bridge daemon status`));
132321
+ console.log(source_default.gray(` 停止: launchctl stop com.cclinker.daemon`));
132322
+ console.log(source_default.gray(` 卸载: cc-linker daemon uninstall`));
132323
+ console.log(source_default.gray(` 状态: cc-linker daemon status`));
132190
132324
  }
132191
132325
  async function installLinux2() {
132192
132326
  const servicePath = getLinuxServicePath3();
@@ -132209,19 +132343,19 @@ async function installLinux2() {
132209
132343
  if (reloadResult.status !== 0) {
132210
132344
  console.log(source_default.yellow(`⚠️ systemctl daemon-reload 警告: ${reloadResult.stderr.toString().trim()}`));
132211
132345
  }
132212
- const enableResult = spawnSync6("systemctl", ["--user", "enable", "cc-bridge.service"]);
132346
+ const enableResult = spawnSync6("systemctl", ["--user", "enable", "cc-linker.service"]);
132213
132347
  if (enableResult.status !== 0) {
132214
132348
  console.log(source_default.yellow(`⚠️ systemctl enable 警告: ${enableResult.stderr.toString().trim()}`));
132215
132349
  }
132216
- const startResult = spawnSync6("systemctl", ["--user", "start", "cc-bridge.service"]);
132350
+ const startResult = spawnSync6("systemctl", ["--user", "start", "cc-linker.service"]);
132217
132351
  console.log(source_default.green("✅ 开机自启已配置"));
132218
132352
  console.log(source_default.cyan(` 配置: ${servicePath}`));
132219
132353
  console.log(source_default.cyan(` 日志: ${RUNTIME_LOG_FILE}`));
132220
132354
  console.log(source_default.gray(`
132221
132355
  操作:`));
132222
- console.log(source_default.gray(` 停止: systemctl --user stop cc-bridge.service`));
132223
- console.log(source_default.gray(` 卸载: cc-bridge daemon uninstall`));
132224
- console.log(source_default.gray(` 状态: cc-bridge daemon status`));
132356
+ console.log(source_default.gray(` 停止: systemctl --user stop cc-linker.service`));
132357
+ console.log(source_default.gray(` 卸载: cc-linker daemon uninstall`));
132358
+ console.log(source_default.gray(` 状态: cc-linker daemon status`));
132225
132359
  }
132226
132360
  async function uninstallDaemon2() {
132227
132361
  console.log(source_default.blue(`=== 卸载开机自启 ===
@@ -132251,25 +132385,25 @@ async function uninstallLinux2() {
132251
132385
  console.log(source_default.yellow("⚠️ systemd 配置不存在"));
132252
132386
  return;
132253
132387
  }
132254
- spawnSync6("systemctl", ["--user", "disable", "cc-bridge.service"]);
132255
- spawnSync6("systemctl", ["--user", "stop", "cc-bridge.service"]);
132388
+ spawnSync6("systemctl", ["--user", "disable", "cc-linker.service"]);
132389
+ spawnSync6("systemctl", ["--user", "stop", "cc-linker.service"]);
132256
132390
  spawnSync6("systemctl", ["--user", "daemon-reload"]);
132257
132391
  unlinkSync11(servicePath);
132258
132392
  console.log(source_default.green("✅ 开机自启已卸载"));
132259
132393
  }
132260
132394
  async function daemonStatus3() {
132261
- console.log(source_default.blue(`=== cc-bridge 服务状态 ===
132395
+ console.log(source_default.blue(`=== cc-linker 服务状态 ===
132262
132396
  `));
132263
132397
  if (existsSync30(RUNTIME_PID_FILE)) {
132264
132398
  try {
132265
132399
  const pid = parseInt(readFileSync23(RUNTIME_PID_FILE, "utf8").trim(), 10);
132266
132400
  process.kill(pid, 0);
132267
- console.log(source_default.green(`✅ cc-bridge 正在运行 (PID: ${pid})`));
132401
+ console.log(source_default.green(`✅ cc-linker 正在运行 (PID: ${pid})`));
132268
132402
  } catch {
132269
- console.log(source_default.red("❌ cc-bridge PID 存在但进程不存在"));
132403
+ console.log(source_default.red("❌ cc-linker PID 存在但进程不存在"));
132270
132404
  }
132271
132405
  } else {
132272
- console.log(source_default.yellow("⚠️ cc-bridge 未在运行"));
132406
+ console.log(source_default.yellow("⚠️ cc-linker 未在运行"));
132273
132407
  }
132274
132408
  console.log(source_default.cyan(`
132275
132409
  开机自启配置:`));
@@ -132279,7 +132413,7 @@ async function daemonStatus3() {
132279
132413
  console.log(source_default.green(` ✅ launchd 已配置 (${plistPath})`));
132280
132414
  } else {
132281
132415
  console.log(source_default.gray(" ️ 未配置 launchd"));
132282
- console.log(source_default.gray(" 执行: cc-bridge daemon install"));
132416
+ console.log(source_default.gray(" 执行: cc-linker daemon install"));
132283
132417
  }
132284
132418
  } else if (IS_LINUX4) {
132285
132419
  const servicePath = getLinuxServicePath3();
@@ -132287,7 +132421,7 @@ async function daemonStatus3() {
132287
132421
  console.log(source_default.green(` ✅ systemd 已配置 (${servicePath})`));
132288
132422
  } else {
132289
132423
  console.log(source_default.gray(" ⏸️ 未配置 systemd"));
132290
- console.log(source_default.gray(" 执行: cc-bridge daemon install"));
132424
+ console.log(source_default.gray(" 执行: cc-linker daemon install"));
132291
132425
  }
132292
132426
  }
132293
132427
  if (existsSync30(RUNTIME_LOG_FILE)) {
@@ -132306,7 +132440,7 @@ async function daemonStatus3() {
132306
132440
 
132307
132441
  // src/index.ts
132308
132442
  var program2 = new Command;
132309
- program2.name("cc-link").description("\u98DE\u4E66 \u2194 Claude Code CLI \u6865\u63A5\u5DE5\u5177").version("0.2.0");
132443
+ program2.name("cc-linker").description("\u98DE\u4E66 \u2194 Claude Code CLI \u6865\u63A5\u5DE5\u5177").version("0.2.0");
132310
132444
  async function withSync(fn, skipSync = false) {
132311
132445
  const registry2 = new RegistryManager;
132312
132446
  if (!skipSync) {
@@ -132356,6 +132490,10 @@ program2.command("start").description("\u542F\u52A8\u98DE\u4E66 Bot \u8FDB\u7A0B
132356
132490
  await start(registry2, { daemon: opts.daemon });
132357
132491
  }, true));
132358
132492
  program2.command("stop").description("\u505C\u6B62\u540E\u53F0\u8FD0\u884C\u7684 Bot \u670D\u52A1").action(() => stop());
132493
+ program2.command("restart").description("\u91CD\u542F Bot \u670D\u52A1\uFF08\u5148 stop \u518D start --daemon\uFF09").action(() => withSync(async (registry2) => {
132494
+ const { restart: restart2 } = await Promise.resolve().then(() => (init_restart(), exports_restart));
132495
+ await restart2(registry2);
132496
+ }, true));
132359
132497
  var daemonCmd = program2.command("daemon").description("\u7BA1\u7406\u540E\u53F0 Bot \u670D\u52A1\uFF08\u5F00\u673A\u81EA\u542F\uFF09");
132360
132498
  daemonCmd.command("install").description("\u914D\u7F6E\u5F00\u673A\u81EA\u52A8\u542F\u52A8").action(() => installDaemon2());
132361
132499
  daemonCmd.command("uninstall").description("\u79FB\u9664\u5F00\u673A\u81EA\u52A8\u542F\u52A8").action(() => uninstallDaemon2());
@@ -132366,5 +132504,5 @@ program2.command("setup").description("\u4E00\u952E\u914D\u7F6E\u5411\u5BFC\uFF0
132366
132504
  program2.command("init-feishu").description("\u4EA4\u4E92\u5F0F\u914D\u7F6E\u98DE\u4E66\u96C6\u6210\uFF08App ID + App Secret + Owner\uFF09").action(() => initFeishu());
132367
132505
  program2.parseAsync(process.argv).catch(handleError);
132368
132506
 
132369
- //# debugId=2E4AE817032FD29C64756E2164756E21
132507
+ //# debugId=B09E898E9174471664756E2164756E21
132370
132508
  //# sourceMappingURL=index.js.map