bfi-cli 0.1.5 → 0.1.7

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 (2) hide show
  1. package/dist/cli.mjs +462 -462
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -1199,12 +1199,12 @@ async function tryGhClone(repo, tempDir, ref) {
1199
1199
  return true;
1200
1200
  }
1201
1201
  function buildGitHubAuthError(url, repo, message) {
1202
- if (repo && isGitHubSsoAuthError(message)) return `GitHub blocked HTTPS access to ${url} because the organization enforces SAML SSO.\n skills tried your existing git credentials and available fallbacks, but none succeeded.\n - Re-authorize your GitHub credentials/app for that org's SSO policy\n - Or rerun with SSH: npx skills add ${repo.sshUrl}\n - Verify access with: gh auth status -h github.com or ssh -T git@github.com`;
1203
- if (repo) return `Authentication failed for ${url}.\n - For private repos, ensure you have access\n - Retry with SSH: npx skills add ${repo.sshUrl}\n - Check access with: gh auth status -h github.com or ssh -T git@github.com`;
1204
- return `Authentication failed for ${url}.\n - For private repos, ensure you have access\n - For SSH: Check your keys with 'ssh -T git@github.com'\n - For HTTPS: Run 'gh auth login' or configure git credentials`;
1202
+ if (repo && isGitHubSsoAuthError(message)) return `GitHub 阻止了 ${url} 的 HTTPS 访问,因为组织强制使用 SAML SSO。\n skills 已尝试您现有的 git 凭据和可用回退方案,但均未成功。\n - 重新授权您的 GitHub 凭据/应用以符合该组织的 SSO 策略\n - 或使用 SSH 重新运行:npx skills add ${repo.sshUrl}\n - 验证访问权限:gh auth status -h github.com 或 ssh -T git@github.com`;
1203
+ if (repo) return `身份验证失败:${url}。\n - 私有仓库请确保您有访问权限\n - 使用 SSH 重试:npx skills add ${repo.sshUrl}\n - 检查访问权限:gh auth status -h github.com 或 ssh -T git@github.com`;
1204
+ return `身份验证失败:${url}。\n - 私有仓库请确保您有访问权限\n - SSH:使用 'ssh -T git@github.com' 检查您的密钥\n - HTTPS:运行 'gh auth login' 或配置 git 凭据`;
1205
1205
  }
1206
1206
  async function cloneRepo(url, ref) {
1207
- if (/^ext::/i.test(url)) throw new GitCloneError("Unsupported Git transport: ext", url);
1207
+ if (/^ext::/i.test(url)) throw new GitCloneError("不支持的 Git 传输协议:ext", url);
1208
1208
  const tempDir = await mkdtemp(join(tmpdir(), "skills-"));
1209
1209
  const cloneOptions = ref ? [
1210
1210
  "--depth",
@@ -1225,7 +1225,7 @@ async function cloneRepo(url, ref) {
1225
1225
  recursive: true,
1226
1226
  force: true
1227
1227
  }).catch(() => {});
1228
- throw new GitCloneError(`Clone timed out after ${Math.round(CLONE_TIMEOUT_MS / 1e3)}s. Common causes:\n - Large repository: raise the timeout with SKILLS_CLONE_TIMEOUT_MS=600000 (10m)\n - Slow network: retry, or clone manually and pass the local path to 'skills add'\n - Private repo without credentials: ensure auth is configured\n - For SSH: ssh-add -l (to check loaded keys)\n - For HTTPS: gh auth status (if using GitHub CLI)`, url, true, false);
1228
+ throw new GitCloneError(`克隆超时(${Math.round(CLONE_TIMEOUT_MS / 1e3)} 秒)。常见原因:\n - 仓库过大:使用 SKILLS_CLONE_TIMEOUT_MS=600000 (10 分钟) 提高超时时间\n - 网络较慢:重试,或手动克隆后将本地路径传给 'skills add'\n - 私有仓库未配置凭据:请确保身份验证已配置\n - SSH:ssh-add -l(检查已加载的密钥)\n - HTTPS:gh auth status(如果使用 GitHub CLI)`, url, true, false);
1229
1229
  }
1230
1230
  if (isAuthError && repo && isGitHubHttpsCloneUrl(url)) {
1231
1231
  try {
@@ -1243,7 +1243,7 @@ async function cloneRepo(url, ref) {
1243
1243
  force: true
1244
1244
  }).catch(() => {});
1245
1245
  if (isAuthError) throw new GitCloneError(buildGitHubAuthError(url, repo, errorMessage), url, false, true);
1246
- throw new GitCloneError(`Failed to clone ${url}: ${errorMessage}`, url, false, false);
1246
+ throw new GitCloneError(`克隆失败 ${url}:${errorMessage}`, url, false, false);
1247
1247
  }
1248
1248
  }
1249
1249
  async function cleanupTempDir(dir) {
@@ -2366,7 +2366,7 @@ const agents = {
2366
2366
  },
2367
2367
  universal: {
2368
2368
  name: "universal",
2369
- displayName: "Universal",
2369
+ displayName: "共享目录",
2370
2370
  skillsDir: ".agents/skills",
2371
2371
  globalSkillsDir: join(configHome, "agents/skills"),
2372
2372
  showInUniversalList: false,
@@ -2502,7 +2502,7 @@ async function installSkillForAgent(skill, agentType, options = {}) {
2502
2502
  success: false,
2503
2503
  path: "",
2504
2504
  mode: options.mode ?? "symlink",
2505
- error: `${agent.displayName} does not support global skill installation`
2505
+ error: `${agent.displayName} 不支持全局技能安装`
2506
2506
  };
2507
2507
  const skillName = sanitizeName(skill.name || basename(skill.path));
2508
2508
  const installMode = options.mode ?? "symlink";
@@ -2514,13 +2514,13 @@ async function installSkillForAgent(skill, agentType, options = {}) {
2514
2514
  success: false,
2515
2515
  path: agentDir,
2516
2516
  mode: installMode,
2517
- error: "Invalid skill name: potential path traversal detected"
2517
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2518
2518
  };
2519
2519
  if (!isPathSafe$1(agentBase, agentDir)) return {
2520
2520
  success: false,
2521
2521
  path: agentDir,
2522
2522
  mode: installMode,
2523
- error: "Invalid skill name: potential path traversal detected"
2523
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2524
2524
  };
2525
2525
  try {
2526
2526
  if (pathsOverlap(skill.path, agentDir)) return {
@@ -2584,7 +2584,7 @@ async function installSkillForAgent(skill, agentType, options = {}) {
2584
2584
  success: false,
2585
2585
  path: agentDir,
2586
2586
  mode: installMode,
2587
- error: error instanceof Error ? error.message : "Unknown error"
2587
+ error: error instanceof Error ? error.message : "未知错误"
2588
2588
  };
2589
2589
  }
2590
2590
  }
@@ -2687,7 +2687,7 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
2687
2687
  success: false,
2688
2688
  path: "",
2689
2689
  mode: installMode,
2690
- error: `${agent.displayName} does not support global skill installation`
2690
+ error: `${agent.displayName} 不支持全局技能安装`
2691
2691
  };
2692
2692
  const skillName = sanitizeName(skill.installName);
2693
2693
  const canonicalBase = agentType === "eve" && installMode === "symlink" ? getAgentBaseDir(agentType, isGlobal, cwd, eveSubagent) : getCanonicalSkillsDir(isGlobal, cwd);
@@ -2698,13 +2698,13 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
2698
2698
  success: false,
2699
2699
  path: agentDir,
2700
2700
  mode: installMode,
2701
- error: "Invalid skill name: potential path traversal detected"
2701
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2702
2702
  };
2703
2703
  if (!isPathSafe$1(agentBase, agentDir)) return {
2704
2704
  success: false,
2705
2705
  path: agentDir,
2706
2706
  mode: installMode,
2707
- error: "Invalid skill name: potential path traversal detected"
2707
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2708
2708
  };
2709
2709
  async function writeSkillFiles(targetDir) {
2710
2710
  for (const [filePath, content] of skill.files) {
@@ -2755,7 +2755,7 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
2755
2755
  success: false,
2756
2756
  path: agentDir,
2757
2757
  mode: installMode,
2758
- error: error instanceof Error ? error.message : "Unknown error"
2758
+ error: error instanceof Error ? error.message : "未知错误"
2759
2759
  };
2760
2760
  }
2761
2761
  }
@@ -2769,7 +2769,7 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
2769
2769
  success: false,
2770
2770
  path: "",
2771
2771
  mode: installMode,
2772
- error: `${agent.displayName} does not support global skill installation`
2772
+ error: `${agent.displayName} 不支持全局技能安装`
2773
2773
  };
2774
2774
  const skillName = sanitizeName(skill.installName);
2775
2775
  const agentBase = getAgentBaseDir(agentType, isGlobal, cwd, eveSubagent);
@@ -2779,7 +2779,7 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
2779
2779
  success: false,
2780
2780
  path: flatSkillPath,
2781
2781
  mode: installMode,
2782
- error: "Invalid skill name: potential path traversal detected"
2782
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2783
2783
  };
2784
2784
  try {
2785
2785
  await mkdir(agentBase, { recursive: true });
@@ -2798,7 +2798,7 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
2798
2798
  success: false,
2799
2799
  path: flatSkillPath,
2800
2800
  mode: installMode,
2801
- error: error instanceof Error ? error.message : "Unknown error"
2801
+ error: error instanceof Error ? error.message : "未知错误"
2802
2802
  };
2803
2803
  }
2804
2804
  }
@@ -2809,13 +2809,13 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
2809
2809
  success: false,
2810
2810
  path: agentDir,
2811
2811
  mode: installMode,
2812
- error: "Invalid skill name: potential path traversal detected"
2812
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2813
2813
  };
2814
2814
  if (!isPathSafe$1(agentBase, agentDir)) return {
2815
2815
  success: false,
2816
2816
  path: agentDir,
2817
2817
  mode: installMode,
2818
- error: "Invalid skill name: potential path traversal detected"
2818
+ error: "无效的技能名称:检测到潜在的路径遍历攻击"
2819
2819
  };
2820
2820
  async function writeSkillFiles(targetDir) {
2821
2821
  for (const file of skill.files) {
@@ -2875,7 +2875,7 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
2875
2875
  success: false,
2876
2876
  path: agentDir,
2877
2877
  mode: installMode,
2878
- error: error instanceof Error ? error.message : "Unknown error"
2878
+ error: error instanceof Error ? error.message : "未知错误"
2879
2879
  };
2880
2880
  }
2881
2881
  }
@@ -4056,7 +4056,7 @@ function multiselect(opts) {
4056
4056
  return multiselect$1({
4057
4057
  ...opts,
4058
4058
  options: opts.options,
4059
- message: `${opts.message} ${import_picocolors.default.dim("(space to toggle)")}`
4059
+ message: `${opts.message} ${import_picocolors.default.dim("(空格切换)")}`
4060
4060
  });
4061
4061
  }
4062
4062
  async function promptForAgents(message, choices) {
@@ -4090,7 +4090,7 @@ async function selectAgentsInteractive(options) {
4090
4090
  const visibleUniversalAgents = getVisibleUniversalAgents().filter(supportsGlobalFilter);
4091
4091
  const otherAgents = getNonUniversalAgents().filter((agent) => agent !== "eve" && supportsGlobalFilter(agent));
4092
4092
  const universalSection = {
4093
- title: "Universal (.agents/skills)",
4093
+ title: "共享目录 (.agents/skills)",
4094
4094
  items: visibleUniversalAgents.map((a) => ({
4095
4095
  value: a,
4096
4096
  label: agents[a].displayName
@@ -4107,7 +4107,7 @@ async function selectAgentsInteractive(options) {
4107
4107
  lastSelected = await getLastSelectedAgents();
4108
4108
  } catch {}
4109
4109
  const selected = await searchMultiselect({
4110
- message: "Which agents do you want to install to?",
4110
+ message: "请选择要安装到的 Agent:",
4111
4111
  items: otherChoices,
4112
4112
  initialSelected: lastSelected ? lastSelected.filter((a) => otherAgents.includes(a) && !universalAgents.includes(a)) : [],
4113
4113
  lockedSection: universalSection
@@ -4118,29 +4118,29 @@ async function selectAgentsInteractive(options) {
4118
4118
  return selected;
4119
4119
  }
4120
4120
  async function handleWellKnownSkills(source, url, options, spinner) {
4121
- spinner.start("Discovering skills from well-known endpoint...");
4121
+ spinner.start("正在从 well-known 端点发现技能...");
4122
4122
  const skills = await wellKnownProvider.fetchAllSkills(url);
4123
4123
  if (skills.length === 0) {
4124
- spinner.stop(import_picocolors.default.red("No skills found"));
4125
- outro(import_picocolors.default.red("No skills found at this URL. Make sure the server has a /.well-known/agent-skills/index.json or /.well-known/skills/index.json file."));
4124
+ spinner.stop(import_picocolors.default.red("未找到技能"));
4125
+ outro(import_picocolors.default.red("该 URL 未找到技能。请确保服务器提供 /.well-known/agent-skills/index.json 或 /.well-known/skills/index.json 文件。"));
4126
4126
  process.exit(1);
4127
4127
  }
4128
4128
  spinner.stop(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
4129
4129
  for (const skill of skills) {
4130
4130
  log.info(`Skill: ${import_picocolors.default.cyan(skill.installName)}`);
4131
4131
  log.message(import_picocolors.default.dim(skill.description));
4132
- if (skill.files.size > 1) log.message(import_picocolors.default.dim(` Files: ${Array.from(skill.files.keys()).join(", ")}`));
4132
+ if (skill.files.size > 1) log.message(import_picocolors.default.dim(` 文件: ${Array.from(skill.files.keys()).join(", ")}`));
4133
4133
  }
4134
4134
  if (options.list) {
4135
4135
  console.log();
4136
- log.step(import_picocolors.default.bold("Available Skills"));
4136
+ log.step(import_picocolors.default.bold("可用技能"));
4137
4137
  for (const skill of skills) {
4138
4138
  log.message(` ${import_picocolors.default.cyan(skill.installName)}`);
4139
4139
  log.message(` ${import_picocolors.default.dim(skill.description)}`);
4140
- if (skill.files.size > 1) log.message(` ${import_picocolors.default.dim(`Files: ${skill.files.size}`)}`);
4140
+ if (skill.files.size > 1) log.message(` ${import_picocolors.default.dim(`文件: ${skill.files.size}`)}`);
4141
4141
  }
4142
4142
  console.log();
4143
- outro("Run without --list to install");
4143
+ outro("不带 --list 参数运行即可安装");
4144
4144
  process.exit(0);
4145
4145
  }
4146
4146
  let selectedSkills;
@@ -4150,8 +4150,8 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4150
4150
  } else if (options.skill && options.skill.length > 0) {
4151
4151
  selectedSkills = skills.filter((s) => options.skill.some((name) => s.installName.toLowerCase() === name.toLowerCase() || s.name.toLowerCase() === name.toLowerCase()));
4152
4152
  if (selectedSkills.length === 0) {
4153
- log.error(`No matching skills found for: ${options.skill.join(", ")}`);
4154
- log.info("Available skills:");
4153
+ log.error(`未找到匹配技能:${options.skill.join(", ")}`);
4154
+ log.info("可用技能:");
4155
4155
  for (const s of skills) log.message(` - ${s.installName}`);
4156
4156
  process.exit(1);
4157
4157
  }
@@ -4164,7 +4164,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4164
4164
  log.info(`Installing all ${skills.length} skills`);
4165
4165
  } else {
4166
4166
  const selected = await multiselect({
4167
- message: "Select skills to install",
4167
+ message: "选择要安装的技能",
4168
4168
  options: skills.map((s) => ({
4169
4169
  value: s,
4170
4170
  label: s.installName,
@@ -4173,7 +4173,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4173
4173
  required: true
4174
4174
  });
4175
4175
  if (isCancel(selected)) {
4176
- cancel("Installation cancelled");
4176
+ cancel("安装已取消");
4177
4177
  process.exit(0);
4178
4178
  }
4179
4179
  selectedSkills = selected;
@@ -4186,27 +4186,27 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4186
4186
  } else if (options.agent && options.agent.length > 0) {
4187
4187
  const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
4188
4188
  if (invalidAgents.length > 0) {
4189
- log.error(`Invalid agents: ${invalidAgents.join(", ")}`);
4190
- log.info(`Valid agents: ${validAgents.join(", ")}`);
4189
+ log.error(`无效 Agent:${invalidAgents.join(", ")}`);
4190
+ log.info(`可用 Agent:${validAgents.join(", ")}`);
4191
4191
  process.exit(1);
4192
4192
  }
4193
4193
  targetAgents = options.agent;
4194
4194
  } else {
4195
- spinner.start("Loading agents...");
4195
+ spinner.start("正在加载 Agent...");
4196
4196
  const installedAgents = await detectInstalledAgents();
4197
4197
  const totalAgents = Object.keys(agents).length;
4198
4198
  spinner.stop(`${totalAgents} agents`);
4199
4199
  if (installedAgents.length === 0) if (options.yes) {
4200
4200
  targetAgents = validAgents;
4201
- log.info("Installing to all agents");
4201
+ log.info("正在安装到全部 Agent");
4202
4202
  } else {
4203
- log.info("Select agents to install skills to");
4204
- const selected = await promptForAgents("Which agents do you want to install to?", Object.entries(agents).map(([key, config]) => ({
4203
+ log.info("请选择要安装技能的 Agent");
4204
+ const selected = await promptForAgents("请选择要安装到的 Agent:", Object.entries(agents).map(([key, config]) => ({
4205
4205
  value: key,
4206
4206
  label: config.displayName
4207
4207
  })));
4208
4208
  if (isCancel(selected)) {
4209
- cancel("Installation cancelled");
4209
+ cancel("安装已取消");
4210
4210
  process.exit(0);
4211
4211
  }
4212
4212
  targetAgents = selected;
@@ -4220,7 +4220,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4220
4220
  } else {
4221
4221
  const selected = await selectAgentsInteractive({ global: options.global });
4222
4222
  if (isCancel(selected)) {
4223
- cancel("Installation cancelled");
4223
+ cancel("安装已取消");
4224
4224
  process.exit(0);
4225
4225
  }
4226
4226
  targetAgents = selected;
@@ -4230,19 +4230,19 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4230
4230
  const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
4231
4231
  if (options.global === void 0 && !options.yes && supportsGlobal) {
4232
4232
  const scope = await select({
4233
- message: "Installation scope",
4233
+ message: "安装范围",
4234
4234
  options: [{
4235
4235
  value: false,
4236
- label: "Project",
4237
- hint: "Install in current directory (committed with your project)"
4236
+ label: "项目",
4237
+ hint: "安装到当前目录(随项目一起提交)"
4238
4238
  }, {
4239
4239
  value: true,
4240
- label: "Global",
4241
- hint: "Install in home directory (available across all projects)"
4240
+ label: "全局",
4241
+ hint: "安装到主目录(跨所有项目可用)"
4242
4242
  }]
4243
4243
  });
4244
4244
  if (isCancel(scope)) {
4245
- cancel("Installation cancelled");
4245
+ cancel("安装已取消");
4246
4246
  process.exit(0);
4247
4247
  }
4248
4248
  installGlobally = scope;
@@ -4251,19 +4251,19 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4251
4251
  const uniqueDirs = new Set(targetAgents.map((a) => agents[a].skillsDir));
4252
4252
  if (!options.copy && !options.yes && uniqueDirs.size > 1) {
4253
4253
  const modeChoice = await select({
4254
- message: "Installation method",
4254
+ message: "安装方式",
4255
4255
  options: [{
4256
4256
  value: "symlink",
4257
- label: "Symlink (Recommended)",
4258
- hint: "Single source of truth, easy updates"
4257
+ label: "符号链接(推荐)",
4258
+ hint: "单一来源,易于更新"
4259
4259
  }, {
4260
4260
  value: "copy",
4261
- label: "Copy to all agents",
4262
- hint: "Independent copies for each agent"
4261
+ label: "复制到所有 Agent",
4262
+ hint: "每个 Agent 独立副本"
4263
4263
  }]
4264
4264
  });
4265
4265
  if (isCancel(modeChoice)) {
4266
- cancel("Installation cancelled");
4266
+ cancel("安装已取消");
4267
4267
  process.exit(0);
4268
4268
  }
4269
4269
  installMode = modeChoice;
@@ -4292,17 +4292,17 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4292
4292
  if (overwriteAgents.length > 0) summaryLines.push(` ${import_picocolors.default.yellow("overwrites:")} ${formatList$1(overwriteAgents)}`);
4293
4293
  }
4294
4294
  console.log();
4295
- note(summaryLines.join("\n"), "Installation Summary");
4295
+ note(summaryLines.join("\n"), "安装摘要");
4296
4296
  if (!options.yes) {
4297
- const confirmed = await confirm({ message: "Proceed with installation?" });
4297
+ const confirmed = await confirm({ message: "确认安装?" });
4298
4298
  if (isCancel(confirmed) || !confirmed) {
4299
- cancel("Installation cancelled");
4299
+ cancel("安装已取消");
4300
4300
  process.exit(0);
4301
4301
  }
4302
4302
  }
4303
4303
  const sourceIdentifier = wellKnownProvider.getSourceIdentifier(url);
4304
4304
  const wellKnownPrivacyPromise = isSourcePrivate(sourceIdentifier).catch(() => null);
4305
- spinner.start("Installing skills...");
4305
+ spinner.start("正在安装技能...");
4306
4306
  const results = [];
4307
4307
  for (const skill of selectedSkills) for (const agent of targetAgents) {
4308
4308
  const result = await installWellKnownSkillForAgent(skill, agent, {
@@ -4315,7 +4315,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4315
4315
  ...result
4316
4316
  });
4317
4317
  }
4318
- spinner.stop("Installation complete");
4318
+ spinner.stop("安装完成");
4319
4319
  console.log();
4320
4320
  const successful = results.filter((r) => r.success);
4321
4321
  const failed = results.filter((r) => !r.success);
@@ -4378,17 +4378,17 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4378
4378
  const title = import_picocolors.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
4379
4379
  note(resultLines.join("\n"), title);
4380
4380
  if (symlinkFailures.length > 0) {
4381
- log.warn(import_picocolors.default.yellow(`Symlinks failed for: ${formatList$1(copiedAgents)}`));
4382
- log.message(import_picocolors.default.dim(" Files were copied instead. On Windows, enable Developer Mode for symlink support."));
4381
+ log.warn(import_picocolors.default.yellow(`符号链接失败: ${formatList$1(copiedAgents)}`));
4382
+ log.message(import_picocolors.default.dim(" 已改为复制文件。在 Windows 上,请启用开发者模式以支持符号链接。"));
4383
4383
  }
4384
4384
  }
4385
4385
  if (failed.length > 0) {
4386
4386
  console.log();
4387
- log.error(import_picocolors.default.red(`Failed to install ${failed.length}`));
4387
+ log.error(import_picocolors.default.red(`安装失败 ${failed.length} 个`));
4388
4388
  for (const r of failed) log.message(` ${import_picocolors.default.red("✗")} ${r.skill} → ${r.agent}: ${import_picocolors.default.dim(r.error)}`);
4389
4389
  }
4390
4390
  console.log();
4391
- outro(import_picocolors.default.green("Done!") + import_picocolors.default.dim(" Review skills before use; they run with full agent permissions."));
4391
+ outro(import_picocolors.default.green("完成!") + import_picocolors.default.dim(" 使用前请审阅技能;技能以 Agent 的全部权限运行。"));
4392
4392
  await promptForFindSkills(options, targetAgents);
4393
4393
  }
4394
4394
  async function installFromSkillHub(parsed, options, spinner) {
@@ -4399,10 +4399,10 @@ async function installFromSkillHub(parsed, options, spinner) {
4399
4399
  let namespace;
4400
4400
  let slug;
4401
4401
  if (restParts.length === 0) {
4402
- spinner.start(`Searching SkillHub for "${rawRef}"...`);
4402
+ spinner.start(`正在 SkillHub 搜索 "${rawRef}"...`);
4403
4403
  const hits = ((await api.searchSkills(rawRef)).data || []).slice(0, 20);
4404
4404
  if (hits.length === 0) {
4405
- spinner.stop(import_picocolors.default.red("No results"));
4405
+ spinner.stop(import_picocolors.default.red("无结果"));
4406
4406
  outro(import_picocolors.default.red(`No skills found on SkillHub for "${rawRef}".`));
4407
4407
  process.exit(1);
4408
4408
  }
@@ -4411,10 +4411,10 @@ async function installFromSkillHub(parsed, options, spinner) {
4411
4411
  const hit = hits[0];
4412
4412
  namespace = hit.namespace;
4413
4413
  slug = hit.slug;
4414
- log.info(`Auto-selected: ${import_picocolors.default.cyan(`@${namespace}/${slug}`)} — ${hit.description || hit.name}`);
4414
+ log.info(`自动选择:${import_picocolors.default.cyan(`@${namespace}/${slug}`)} — ${hit.description || hit.name}`);
4415
4415
  } else {
4416
4416
  const idx = await select({
4417
- message: "Multiple skills matched — select one",
4417
+ message: "匹配到多个技能 — 请选择一个",
4418
4418
  options: hits.map((h, idx) => ({
4419
4419
  value: idx,
4420
4420
  label: `@${h.namespace}/${h.slug}`,
@@ -4422,7 +4422,7 @@ async function installFromSkillHub(parsed, options, spinner) {
4422
4422
  }))
4423
4423
  });
4424
4424
  if (isCancel(idx)) {
4425
- cancel("Installation cancelled");
4425
+ cancel("安装已取消");
4426
4426
  process.exit(0);
4427
4427
  }
4428
4428
  const chosen = hits[idx];
@@ -4435,13 +4435,13 @@ async function installFromSkillHub(parsed, options, spinner) {
4435
4435
  }
4436
4436
  const canonicalSlug = toCanonicalSlug(namespace, slug);
4437
4437
  const version = parsed.ref || "latest";
4438
- spinner.start(`Fetching skill metadata for @${namespace}/${slug}...`);
4438
+ spinner.start(`正在获取 @${namespace}/${slug} 的技能元数据...`);
4439
4439
  let metadata;
4440
4440
  try {
4441
4441
  metadata = await api.getSkill(canonicalSlug);
4442
4442
  } catch (err) {
4443
- spinner.stop(import_picocolors.default.red("Failed to fetch metadata"));
4444
- outro(import_picocolors.default.red(`Skill @${namespace}/${slug} not found on SkillHub: ${err.message}`));
4443
+ spinner.stop(import_picocolors.default.red("获取元数据失败"));
4444
+ outro(import_picocolors.default.red(`未在 SkillHub 上找到技能 @${namespace}/${slug}: ${err.message}`));
4445
4445
  process.exit(1);
4446
4446
  }
4447
4447
  const meta = metadata;
@@ -4449,39 +4449,39 @@ async function installFromSkillHub(parsed, options, spinner) {
4449
4449
  const tempDir = join(tmpdir(), `.bfi-skillhub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
4450
4450
  mkdirSync(tempDir, { recursive: true });
4451
4451
  const zipPath = join(tempDir, "skill.zip");
4452
- spinner.start("Downloading skill...");
4452
+ spinner.start("正在下载技能...");
4453
4453
  try {
4454
4454
  await api.downloadSkill(namespace, slug, version, zipPath);
4455
4455
  } catch (err) {
4456
- spinner.stop(import_picocolors.default.red("Download failed"));
4456
+ spinner.stop(import_picocolors.default.red("下载失败"));
4457
4457
  try {
4458
4458
  rmSync(tempDir, {
4459
4459
  recursive: true,
4460
4460
  force: true
4461
4461
  });
4462
4462
  } catch {}
4463
- outro(import_picocolors.default.red(`Failed to download @${namespace}/${slug}: ${err.message}`));
4463
+ outro(import_picocolors.default.red(`下载失败 @${namespace}/${slug}:${err.message}`));
4464
4464
  process.exit(1);
4465
4465
  }
4466
- spinner.stop("Download complete");
4467
- spinner.start("Extracting...");
4466
+ spinner.stop("下载完成");
4467
+ spinner.start("正在解压...");
4468
4468
  const extractDir = join(tempDir, "extracted");
4469
4469
  mkdirSync(extractDir, { recursive: true });
4470
4470
  try {
4471
4471
  await extractZip(zipPath, extractDir);
4472
4472
  } catch (err) {
4473
- spinner.stop(import_picocolors.default.red("Extraction failed"));
4473
+ spinner.stop(import_picocolors.default.red("解压失败"));
4474
4474
  try {
4475
4475
  rmSync(tempDir, {
4476
4476
  recursive: true,
4477
4477
  force: true
4478
4478
  });
4479
4479
  } catch {}
4480
- outro(import_picocolors.default.red(`Failed to extract skill archive: ${err.message}`));
4480
+ outro(import_picocolors.default.red(`解压技能压缩包失败:${err.message}`));
4481
4481
  process.exit(1);
4482
4482
  }
4483
- spinner.stop("Extraction complete");
4484
- spinner.start("Discovering skills...");
4483
+ spinner.stop("解压完成");
4484
+ spinner.start("正在发现技能...");
4485
4485
  const skills = await discoverSkills(extractDir, parsed.subpath, {
4486
4486
  includeInternal: !!(options.skill && options.skill.length > 0),
4487
4487
  fullDepth: options.fullDepth
@@ -4507,7 +4507,7 @@ async function runAdd(args, options = {}) {
4507
4507
  let installTipShown = false;
4508
4508
  const showInstallTip = () => {
4509
4509
  if (installTipShown) return;
4510
- log.message(import_picocolors.default.dim("Tip: use the --yes (-y) and --global (-g) flags to install without prompts."));
4510
+ log.message(import_picocolors.default.dim("提示:使用 --yes (-y) 和 --global (-g) 参数可跳过交互提示直接安装。"));
4511
4511
  installTipShown = true;
4512
4512
  };
4513
4513
  if (!source) {
@@ -4537,14 +4537,14 @@ async function runAdd(args, options = {}) {
4537
4537
  }
4538
4538
  console.log();
4539
4539
  if (!agentResult.isAgent) intro(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills ")));
4540
- if (agentResult.isAgent) log.info(import_picocolors.default.bgCyan(import_picocolors.default.black(import_picocolors.default.bold(` ${agentResult.agent.name} `))) + " Agent detected — installing non-interactively");
4540
+ if (agentResult.isAgent) log.info(import_picocolors.default.bgCyan(import_picocolors.default.black(import_picocolors.default.bold(` ${agentResult.agent.name} `))) + " 已检测到 Agent — 以非交互模式安装");
4541
4541
  else if (!process.stdin.isTTY) showInstallTip();
4542
4542
  let tempDir = null;
4543
4543
  try {
4544
4544
  const spinner$2 = spinner();
4545
- spinner$2.start("Parsing source...");
4545
+ spinner$2.start("正在解析源...");
4546
4546
  const parsed = parseSource(source);
4547
- spinner$2.stop(`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors.default.dim("@")}${import_picocolors.default.cyan(parsed.skillFilter)}` : ""}`);
4547
+ spinner$2.stop(`源:${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors.default.dim("@")}${import_picocolors.default.cyan(parsed.skillFilter)}` : ""}`);
4548
4548
  const ownerRepoRaw = getOwnerRepo(parsed);
4549
4549
  const repoPrivacyPromise = (() => {
4550
4550
  if (!ownerRepoRaw) return Promise.resolve(null);
@@ -4568,14 +4568,14 @@ async function runAdd(args, options = {}) {
4568
4568
  skills = result.skills;
4569
4569
  tempDir = result.tempDir;
4570
4570
  } else if (parsed.type === "local") {
4571
- spinner$2.start("Validating local path...");
4571
+ spinner$2.start("正在验证本地路径...");
4572
4572
  if (!existsSync(parsed.localPath)) {
4573
- spinner$2.stop(import_picocolors.default.red("Path not found"));
4574
- outro(import_picocolors.default.red(`Local path does not exist: ${parsed.localPath}`));
4573
+ spinner$2.stop(import_picocolors.default.red("路径未找到"));
4574
+ outro(import_picocolors.default.red(`本地路径不存在:${parsed.localPath}`));
4575
4575
  process.exit(1);
4576
4576
  }
4577
- spinner$2.stop("Local path validated");
4578
- spinner$2.start("Discovering skills...");
4577
+ spinner$2.stop("本地路径验证通过");
4578
+ spinner$2.start("正在发现技能...");
4579
4579
  skills = await discoverSkills(parsed.localPath, parsed.subpath, {
4580
4580
  includeInternal,
4581
4581
  fullDepth: options.fullDepth
@@ -4590,7 +4590,7 @@ async function runAdd(args, options = {}) {
4590
4590
  const owner = ownerRepo?.split("/")[0]?.toLowerCase();
4591
4591
  const isSelfHostedRepo = !!ownerRepo && Object.hasOwn(BLOB_ALLOWED_REPOS, ownerRepo.toLowerCase());
4592
4592
  if (ownerRepo && owner && (isSelfHostedRepo || BLOB_ALLOWED_OWNERS.includes(owner))) {
4593
- spinner$2.start("Fetching skills...");
4593
+ spinner$2.start("正在获取技能...");
4594
4594
  blobResult = await tryBlobInstall(ownerRepo, {
4595
4595
  subpath: parsed.subpath,
4596
4596
  skillFilter: parsed.skillFilter,
@@ -4604,35 +4604,35 @@ async function runAdd(args, options = {}) {
4604
4604
  skills = blobResult.skills;
4605
4605
  spinner$2.stop(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
4606
4606
  } else {
4607
- spinner$2.start("Cloning repository...");
4607
+ spinner$2.start("正在克隆仓库...");
4608
4608
  tempDir = await cloneRepo(parsed.url, parsed.ref);
4609
- spinner$2.stop("Repository cloned");
4610
- spinner$2.start("Discovering skills...");
4609
+ spinner$2.stop("仓库克隆完成");
4610
+ spinner$2.start("正在发现技能...");
4611
4611
  skills = await discoverSkills(tempDir, parsed.subpath, {
4612
4612
  includeInternal,
4613
4613
  fullDepth: options.fullDepth
4614
4614
  });
4615
4615
  }
4616
4616
  } else {
4617
- spinner$2.start("Cloning repository...");
4617
+ spinner$2.start("正在克隆仓库...");
4618
4618
  tempDir = await cloneRepo(parsed.url, parsed.ref);
4619
- spinner$2.stop("Repository cloned");
4620
- spinner$2.start("Discovering skills...");
4619
+ spinner$2.stop("仓库克隆完成");
4620
+ spinner$2.start("正在发现技能...");
4621
4621
  skills = await discoverSkills(tempDir, parsed.subpath, {
4622
4622
  includeInternal,
4623
4623
  fullDepth: options.fullDepth
4624
4624
  });
4625
4625
  }
4626
4626
  if (skills.length === 0) {
4627
- spinner$2.stop(import_picocolors.default.red("No skills found"));
4628
- outro(import_picocolors.default.red("No valid skills found. Skills require a SKILL.md with name and description."));
4627
+ spinner$2.stop(import_picocolors.default.red("未找到技能"));
4628
+ outro(import_picocolors.default.red("未找到有效技能。技能需要包含 name 和 description 的 SKILL.md 文件。"));
4629
4629
  await cleanup(tempDir);
4630
4630
  process.exit(1);
4631
4631
  }
4632
4632
  if (!blobResult) spinner$2.stop(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
4633
4633
  if (options.list) {
4634
4634
  console.log();
4635
- log.step(import_picocolors.default.bold("Available Skills"));
4635
+ log.step(import_picocolors.default.bold("可用技能"));
4636
4636
  const groupedSkills = {};
4637
4637
  const ungroupedSkills = [];
4638
4638
  for (const skill of skills) if (skill.pluginName) {
@@ -4658,7 +4658,7 @@ async function runAdd(args, options = {}) {
4658
4658
  }
4659
4659
  }
4660
4660
  console.log();
4661
- outro("Use --skill <name> to install specific skills");
4661
+ outro("使用 --skill <name> 安装指定技能");
4662
4662
  await cleanup(tempDir);
4663
4663
  process.exit(0);
4664
4664
  }
@@ -4669,8 +4669,8 @@ async function runAdd(args, options = {}) {
4669
4669
  } else if (options.skill && options.skill.length > 0) {
4670
4670
  selectedSkills = filterSkills(skills, options.skill);
4671
4671
  if (selectedSkills.length === 0) {
4672
- log.error(`No matching skills found for: ${options.skill.join(", ")}`);
4673
- log.info("Available skills:");
4672
+ log.error(`未找到匹配技能:${options.skill.join(", ")}`);
4673
+ log.info("可用技能:");
4674
4674
  for (const s of skills) log.message(` - ${getSkillDisplayName(s)}`);
4675
4675
  await cleanup(tempDir);
4676
4676
  process.exit(1);
@@ -4706,12 +4706,12 @@ async function runAdd(args, options = {}) {
4706
4706
  });
4707
4707
  }
4708
4708
  selected = await groupMultiselect({
4709
- message: `Select skills to install ${import_picocolors.default.dim("(space to toggle)")}`,
4709
+ message: `Select skills to install ${import_picocolors.default.dim("(空格切换)")}`,
4710
4710
  options: grouped,
4711
4711
  required: true
4712
4712
  });
4713
4713
  } else selected = await multiselect({
4714
- message: "Select skills to install",
4714
+ message: "选择要安装的技能",
4715
4715
  options: sortedSkills.map((s) => ({
4716
4716
  value: s,
4717
4717
  label: getSkillDisplayName(s),
@@ -4720,7 +4720,7 @@ async function runAdd(args, options = {}) {
4720
4720
  required: true
4721
4721
  });
4722
4722
  if (isCancel(selected)) {
4723
- cancel("Installation cancelled");
4723
+ cancel("安装已取消");
4724
4724
  await cleanup(tempDir);
4725
4725
  process.exit(0);
4726
4726
  }
@@ -4736,14 +4736,14 @@ async function runAdd(args, options = {}) {
4736
4736
  } else if (options.agent && options.agent.length > 0) {
4737
4737
  const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
4738
4738
  if (invalidAgents.length > 0) {
4739
- log.error(`Invalid agents: ${invalidAgents.join(", ")}`);
4740
- log.info(`Valid agents: ${validAgents.join(", ")}`);
4739
+ log.error(`无效 Agent:${invalidAgents.join(", ")}`);
4740
+ log.info(`可用 Agent:${validAgents.join(", ")}`);
4741
4741
  await cleanup(tempDir);
4742
4742
  process.exit(1);
4743
4743
  }
4744
4744
  targetAgents = options.agent;
4745
4745
  } else {
4746
- spinner$2.start("Loading agents...");
4746
+ spinner$2.start("正在加载 Agent...");
4747
4747
  const installedAgents = await detectInstalledAgents();
4748
4748
  const totalAgents = Object.keys(agents).length;
4749
4749
  spinner$2.stop(`${totalAgents} agents`);
@@ -4753,17 +4753,17 @@ async function runAdd(args, options = {}) {
4753
4753
  initialValue: true
4754
4754
  });
4755
4755
  if (isCancel(useEve)) {
4756
- cancel("Installation cancelled");
4756
+ cancel("安装已取消");
4757
4757
  await cleanup(tempDir);
4758
4758
  process.exit(0);
4759
4759
  }
4760
4760
  if (useEve) {
4761
4761
  targetAgents = ["eve"];
4762
- log.info(`Installing to: ${import_picocolors.default.cyan(EVE_AGENT_LABEL)}`);
4762
+ log.info(`安装到:${import_picocolors.default.cyan(EVE_AGENT_LABEL)}`);
4763
4763
  } else {
4764
4764
  const selected = await selectAgentsInteractive({ global: options.global });
4765
4765
  if (isCancel(selected)) {
4766
- cancel("Installation cancelled");
4766
+ cancel("安装已取消");
4767
4767
  await cleanup(tempDir);
4768
4768
  process.exit(0);
4769
4769
  }
@@ -4771,15 +4771,15 @@ async function runAdd(args, options = {}) {
4771
4771
  }
4772
4772
  } else if (installedAgents.length === 0) if (options.yes) {
4773
4773
  targetAgents = validAgents;
4774
- log.info("Installing to all agents");
4774
+ log.info("正在安装到全部 Agent");
4775
4775
  } else {
4776
- log.info("Select agents to install skills to");
4777
- const selected = await promptForAgents("Which agents do you want to install to?", Object.entries(agents).filter(([key]) => key !== "eve").map(([key, config]) => ({
4776
+ log.info("请选择要安装技能的 Agent");
4777
+ const selected = await promptForAgents("请选择要安装到的 Agent:", Object.entries(agents).filter(([key]) => key !== "eve").map(([key, config]) => ({
4778
4778
  value: key,
4779
4779
  label: config.displayName
4780
4780
  })));
4781
4781
  if (isCancel(selected)) {
4782
- cancel("Installation cancelled");
4782
+ cancel("安装已取消");
4783
4783
  await cleanup(tempDir);
4784
4784
  process.exit(0);
4785
4785
  }
@@ -4794,7 +4794,7 @@ async function runAdd(args, options = {}) {
4794
4794
  } else {
4795
4795
  const selected = await selectAgentsInteractive({ global: options.global });
4796
4796
  if (isCancel(selected)) {
4797
- cancel("Installation cancelled");
4797
+ cancel("安装已取消");
4798
4798
  await cleanup(tempDir);
4799
4799
  process.exit(0);
4800
4800
  }
@@ -4808,10 +4808,10 @@ async function runAdd(args, options = {}) {
4808
4808
  if (options.subagent && options.subagent.length > 0) eveSubagentTargets = options.subagent.map((s) => s === "root" || s === "." ? void 0 : s);
4809
4809
  else if (availableSubagents.length > 0 && !options.yes) {
4810
4810
  const selectedSubagents = await multiselect$1({
4811
- message: "Where should Eve skills be installed?",
4811
+ message: "Eve 技能安装位置?",
4812
4812
  options: [{
4813
4813
  value: "",
4814
- label: "Root agent",
4814
+ label: "根 Agent",
4815
4815
  hint: "agent/skills"
4816
4816
  }, ...availableSubagents.map((name) => ({
4817
4817
  value: name,
@@ -4822,7 +4822,7 @@ async function runAdd(args, options = {}) {
4822
4822
  required: true
4823
4823
  });
4824
4824
  if (isCancel(selectedSubagents)) {
4825
- cancel("Installation cancelled");
4825
+ cancel("安装已取消");
4826
4826
  await cleanup(tempDir);
4827
4827
  process.exit(0);
4828
4828
  }
@@ -4834,19 +4834,19 @@ async function runAdd(args, options = {}) {
4834
4834
  const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
4835
4835
  if (options.global === void 0 && !options.yes && supportsGlobal) {
4836
4836
  const scope = await select({
4837
- message: "Installation scope",
4837
+ message: "安装范围",
4838
4838
  options: [{
4839
4839
  value: false,
4840
4840
  label: "Project",
4841
- hint: "Install in current directory (committed with your project)"
4841
+ hint: "安装到当前目录(随项目一起提交)"
4842
4842
  }, {
4843
4843
  value: true,
4844
4844
  label: "Global",
4845
- hint: "Install in home directory (available across all projects)"
4845
+ hint: "安装到主目录(跨所有项目可用)"
4846
4846
  }]
4847
4847
  });
4848
4848
  if (isCancel(scope)) {
4849
- cancel("Installation cancelled");
4849
+ cancel("安装已取消");
4850
4850
  await cleanup(tempDir);
4851
4851
  process.exit(0);
4852
4852
  }
@@ -4857,19 +4857,19 @@ async function runAdd(args, options = {}) {
4857
4857
  const uniqueDirs = new Set(installTargets.map((t) => t.subagent ? `eve:subagent:${t.subagent}` : agents[t.agent].skillsDir));
4858
4858
  if (!options.copy && !options.yes && uniqueDirs.size > 1 && !allEve) {
4859
4859
  const modeChoice = await select({
4860
- message: "Installation method",
4860
+ message: "安装方式",
4861
4861
  options: [{
4862
4862
  value: "symlink",
4863
- label: "Symlink (Recommended)",
4864
- hint: "Single source of truth, easy updates"
4863
+ label: "符号链接(推荐)",
4864
+ hint: "单一来源,易于更新"
4865
4865
  }, {
4866
4866
  value: "copy",
4867
- label: "Copy to all agents",
4868
- hint: "Independent copies for each agent"
4867
+ label: "复制到所有 Agent",
4868
+ hint: "每个 Agent 独立副本"
4869
4869
  }]
4870
4870
  });
4871
4871
  if (isCancel(modeChoice)) {
4872
- cancel("Installation cancelled");
4872
+ cancel("安装已取消");
4873
4873
  await cleanup(tempDir);
4874
4874
  process.exit(0);
4875
4875
  }
@@ -4927,7 +4927,7 @@ async function runAdd(args, options = {}) {
4927
4927
  printSkillSummary(ungroupedSummary);
4928
4928
  }
4929
4929
  console.log();
4930
- note(summaryLines.join("\n"), "Installation Summary");
4930
+ note(summaryLines.join("\n"), "安装摘要");
4931
4931
  try {
4932
4932
  const auditData = await auditPromise;
4933
4933
  if (auditData && ownerRepoForAudit) {
@@ -4935,18 +4935,18 @@ async function runAdd(args, options = {}) {
4935
4935
  slug: getSkillDisplayName(s),
4936
4936
  displayName: getSkillDisplayName(s)
4937
4937
  })), ownerRepoForAudit);
4938
- if (securityLines.length > 0) note(securityLines.join("\n"), "Security Risk Assessments");
4938
+ if (securityLines.length > 0) note(securityLines.join("\n"), "安全风险评估");
4939
4939
  }
4940
4940
  } catch {}
4941
4941
  if (!options.yes) {
4942
- const confirmed = await confirm({ message: "Proceed with installation?" });
4942
+ const confirmed = await confirm({ message: "确认安装?" });
4943
4943
  if (isCancel(confirmed) || !confirmed) {
4944
- cancel("Installation cancelled");
4944
+ cancel("安装已取消");
4945
4945
  await cleanup(tempDir);
4946
4946
  process.exit(0);
4947
4947
  }
4948
4948
  }
4949
- spinner$2.start("Installing skills...");
4949
+ spinner$2.start("正在安装技能...");
4950
4950
  const results = [];
4951
4951
  for (const skill of selectedSkills) for (const target of installTargets) {
4952
4952
  const { agent, subagent } = target;
@@ -4983,7 +4983,7 @@ async function runAdd(args, options = {}) {
4983
4983
  ...result
4984
4984
  });
4985
4985
  }
4986
- spinner$2.stop("Installation complete");
4986
+ spinner$2.stop("安装完成");
4987
4987
  console.log();
4988
4988
  const successful = results.filter((r) => r.success);
4989
4989
  const failed = results.filter((r) => !r.success);
@@ -5073,7 +5073,7 @@ async function runAdd(args, options = {}) {
5073
5073
  const skillResults = bySkill.get(entry.skill) || [];
5074
5074
  const firstResult = skillResults[0];
5075
5075
  if (firstResult.mode === "copy") {
5076
- resultLines.push(`${import_picocolors.default.green("✓")} ${entry.skill} ${import_picocolors.default.dim("(copied)")}`);
5076
+ resultLines.push(`${import_picocolors.default.green("✓")} ${entry.skill} ${import_picocolors.default.dim("(已复制)")}`);
5077
5077
  for (const r of skillResults) {
5078
5078
  const shortPath = shortenPath$1(r.path, cwd);
5079
5079
  resultLines.push(` ${import_picocolors.default.dim("→")} ${shortPath}`);
@@ -5104,13 +5104,13 @@ async function runAdd(args, options = {}) {
5104
5104
  const title = import_picocolors.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
5105
5105
  note(resultLines.join("\n"), title);
5106
5106
  if (symlinkFailures.length > 0) {
5107
- log.warn(import_picocolors.default.yellow(`Symlinks failed for: ${formatList$1(copiedAgents)}`));
5108
- log.message(import_picocolors.default.dim(" Files were copied instead. On Windows, enable Developer Mode for symlink support."));
5107
+ log.warn(import_picocolors.default.yellow(`符号链接失败: ${formatList$1(copiedAgents)}`));
5108
+ log.message(import_picocolors.default.dim(" 已改为复制文件。在 Windows 上,请启用开发者模式以支持符号链接。"));
5109
5109
  }
5110
5110
  }
5111
5111
  if (failed.length > 0) {
5112
5112
  console.log();
5113
- log.error(import_picocolors.default.red(`Failed to install ${failed.length}`));
5113
+ log.error(import_picocolors.default.red(`安装失败 ${failed.length} 个`));
5114
5114
  for (const r of failed) log.message(` ${import_picocolors.default.red("✗")} ${r.skill} → ${r.agent}: ${import_picocolors.default.dim(r.error)}`);
5115
5115
  }
5116
5116
  console.log();
@@ -5118,11 +5118,11 @@ async function runAdd(args, options = {}) {
5118
5118
  await promptForFindSkills(options, targetAgents);
5119
5119
  } catch (error) {
5120
5120
  if (error instanceof GitCloneError) {
5121
- log.error(import_picocolors.default.red("Failed to clone repository"));
5121
+ log.error(import_picocolors.default.red("克隆仓库失败"));
5122
5122
  for (const line of error.message.split("\n")) log.message(import_picocolors.default.dim(line));
5123
5123
  } else log.error(error instanceof Error ? error.message : "Unknown error occurred");
5124
5124
  showInstallTip();
5125
- outro(import_picocolors.default.red("Installation failed"));
5125
+ outro(import_picocolors.default.red("安装失败"));
5126
5126
  process.exit(1);
5127
5127
  } finally {
5128
5128
  await cleanup(tempDir);
@@ -5143,7 +5143,7 @@ async function promptForFindSkills(options, targetAgents) {
5143
5143
  return;
5144
5144
  }
5145
5145
  console.log();
5146
- log.message(import_picocolors.default.dim("One-time prompt - you won't be asked again if you dismiss."));
5146
+ log.message(import_picocolors.default.dim("一次性提示 - 关闭后将不再询问。"));
5147
5147
  const install = await confirm({ message: `Install the ${import_picocolors.default.cyan("find-skills")} skill? It helps your agent discover and suggest skills.` });
5148
5148
  if (isCancel(install)) {
5149
5149
  await dismissPrompt("findSkillsPrompt");
@@ -5154,7 +5154,7 @@ async function promptForFindSkills(options, targetAgents) {
5154
5154
  const findSkillsAgents = targetAgents?.filter((a) => a !== "replit");
5155
5155
  if (!findSkillsAgents || findSkillsAgents.length === 0) return;
5156
5156
  console.log();
5157
- log.step("Installing find-skills skill...");
5157
+ log.step("正在安装 find-skills 技能...");
5158
5158
  try {
5159
5159
  await runAdd(["vercel-labs/skills"], {
5160
5160
  skill: ["find-skills"],
@@ -5163,12 +5163,12 @@ async function promptForFindSkills(options, targetAgents) {
5163
5163
  agent: findSkillsAgents
5164
5164
  });
5165
5165
  } catch {
5166
- log.warn("Failed to install find-skills. You can try again with:");
5166
+ log.warn("安装 find-skills 失败。你可以稍后重试:");
5167
5167
  log.message(import_picocolors.default.dim(" npx skills add vercel-labs/skills@find-skills -g -y --all"));
5168
5168
  }
5169
5169
  } else {
5170
5170
  await dismissPrompt("findSkillsPrompt");
5171
- log.message(import_picocolors.default.dim("You can install it later with: npx skills add vercel-labs/skills@find-skills"));
5171
+ log.message(import_picocolors.default.dim("你可以稍后通过以下命令安装:npx skills add vercel-labs/skills@find-skills"));
5172
5172
  }
5173
5173
  } catch {}
5174
5174
  }
@@ -5204,12 +5204,12 @@ function parseAddOptions(args) {
5204
5204
  i--;
5205
5205
  } else if (arg === "--metadata") {
5206
5206
  const metadata = args[++i];
5207
- if (metadata === void 0) errors.push("--metadata requires a JSON value");
5207
+ if (metadata === void 0) errors.push("--metadata 需要 JSON 值");
5208
5208
  else try {
5209
5209
  JSON.parse(metadata);
5210
5210
  options.metadata = metadata;
5211
5211
  } catch {
5212
- errors.push("--metadata must be valid JSON");
5212
+ errors.push("--metadata 必须是有效的 JSON");
5213
5213
  }
5214
5214
  } else if (arg === "--full-depth") options.fullDepth = true;
5215
5215
  else if (arg === "--copy") options.copy = true;
@@ -5241,7 +5241,7 @@ function formatInstalls$1(count) {
5241
5241
  if (!count || count <= 0) return "";
5242
5242
  if (count >= 1e6) return `${(count / 1e6).toFixed(1).replace(/\.0$/, "")}M installs`;
5243
5243
  if (count >= 1e3) return `${(count / 1e3).toFixed(1).replace(/\.0$/, "")}K installs`;
5244
- return `${count} install${count === 1 ? "" : "s"}`;
5244
+ return `${count} 次安装`;
5245
5245
  }
5246
5246
  const GITHUB_OWNER_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,38})$/i;
5247
5247
  function parseFindOptions(args) {
@@ -5324,11 +5324,11 @@ async function runSearchPrompt(initialQuery = "", owner) {
5324
5324
  process.stdout.write(CLEAR_DOWN);
5325
5325
  const lines = [];
5326
5326
  const cursor = `${BOLD$8}_${RESET$11}`;
5327
- lines.push(`${TEXT$9}Search skills:${RESET$11} ${query}${cursor}`);
5327
+ lines.push(`${TEXT$9}搜索技能:${RESET$11} ${query}${cursor}`);
5328
5328
  lines.push("");
5329
- if (!query || query.length < 2) lines.push(`${DIM$11}Start typing to search (min 2 chars)${RESET$11}`);
5330
- else if (results.length === 0 && loading) lines.push(`${DIM$11}Searching...${RESET$11}`);
5331
- else if (results.length === 0) lines.push(`${DIM$11}No skills found${RESET$11}`);
5329
+ if (!query || query.length < 2) lines.push(`${DIM$11}输入关键词搜索(最少 2 个字符)${RESET$11}`);
5330
+ else if (results.length === 0 && loading) lines.push(`${DIM$11}搜索中...${RESET$11}`);
5331
+ else if (results.length === 0) lines.push(`${DIM$11}未找到技能${RESET$11}`);
5332
5332
  else {
5333
5333
  const visible = results.slice(0, 8);
5334
5334
  for (let i = 0; i < visible.length; i++) {
@@ -5344,7 +5344,7 @@ async function runSearchPrompt(initialQuery = "", owner) {
5344
5344
  }
5345
5345
  }
5346
5346
  lines.push("");
5347
- lines.push(`${DIM$11}up/down navigate | enter select | esc cancel${RESET$11}`);
5347
+ lines.push(`${DIM$11}上下键导航 | 回车选择 | ESC 取消${RESET$11}`);
5348
5348
  for (const line of lines) process.stdout.write(line + "\n");
5349
5349
  lastRenderedLines = lines.length;
5350
5350
  }
@@ -5454,10 +5454,10 @@ ${DIM$11} 2) npx skills add <owner/repo@skill>${RESET$11}`;
5454
5454
  String(results.length);
5455
5455
  if (results.length === 0) {
5456
5456
  const ownerSuffix = owner ? ` from owner "${owner}"` : "";
5457
- console.log(`${DIM$11}No skills found for "${query}"${ownerSuffix}${RESET$11}`);
5457
+ console.log(`${DIM$11}未找到 "${query}" 的技能${ownerSuffix}${RESET$11}`);
5458
5458
  return;
5459
5459
  }
5460
- console.log(`${DIM$11}Install with${RESET$11} npx skills add <owner/repo@skill>`);
5460
+ console.log(`${DIM$11}安装:${RESET$11} npx skills add <owner/repo@skill>`);
5461
5461
  console.log();
5462
5462
  for (const skill of results.slice(0, 6)) {
5463
5463
  const pkg = skill.source || skill.slug;
@@ -5476,14 +5476,14 @@ ${DIM$11} 2) npx skills add <owner/repo@skill>${RESET$11}`;
5476
5476
  }
5477
5477
  const selected = await runSearchPrompt("", owner);
5478
5478
  if (!selected) {
5479
- console.log(`${DIM$11}Search cancelled${RESET$11}`);
5479
+ console.log(`${DIM$11}搜索已取消${RESET$11}`);
5480
5480
  console.log();
5481
5481
  return;
5482
5482
  }
5483
5483
  const pkg = selected.source || selected.slug;
5484
5484
  const skillName = selected.name;
5485
5485
  console.log();
5486
- console.log(`${TEXT$9}Installing ${BOLD$8}${skillName}${RESET$11} from ${DIM$11}${pkg}${RESET$11}...`);
5486
+ console.log(`${TEXT$9}正在从 ${DIM$11}${pkg}${RESET$11} 安装 ${BOLD$8}${skillName}${RESET$11}...`);
5487
5487
  console.log();
5488
5488
  const { source, options: addOptions } = parseAddOptions([
5489
5489
  pkg,
@@ -5493,8 +5493,8 @@ ${DIM$11} 2) npx skills add <owner/repo@skill>${RESET$11}`;
5493
5493
  await runAdd(source, addOptions);
5494
5494
  console.log();
5495
5495
  const info = getOwnerRepoFromString(pkg);
5496
- if (info && await isRepoPublic(info.owner, info.repo)) console.log(`${DIM$11}View the skill at${RESET$11} ${TEXT$9}https://skills.sh/${selected.slug}${RESET$11}`);
5497
- else console.log(`${DIM$11}Discover more skills at${RESET$11} ${TEXT$9}https://skills.sh${RESET$11}`);
5496
+ if (info && await isRepoPublic(info.owner, info.repo)) console.log(`${DIM$11}查看技能:${RESET$11} ${TEXT$9}https://skills.sh/${selected.slug}${RESET$11}`);
5497
+ else console.log(`${DIM$11}发现更多技能:${RESET$11} ${TEXT$9}https://skills.sh${RESET$11}`);
5498
5498
  console.log();
5499
5499
  }
5500
5500
  const RESET$10 = "\x1B[0m";
@@ -5557,15 +5557,15 @@ async function runList(args) {
5557
5557
  }
5558
5558
  const lockedSkills = await getAllLockedSkills();
5559
5559
  const cwd = process.cwd();
5560
- const scopeLabel = scope ? "Global" : "Project";
5560
+ const scopeLabel = scope ? "全局" : "项目";
5561
5561
  if (installedSkills.length === 0) {
5562
5562
  if (options.json) {
5563
5563
  console.log("[]");
5564
5564
  return;
5565
5565
  }
5566
- console.log(`${DIM$10}No ${scopeLabel.toLowerCase()} skills found.${RESET$10}`);
5567
- if (scope) console.log(`${DIM$10}Try listing project skills without -g${RESET$10}`);
5568
- else console.log(`${DIM$10}Try listing global skills with -g${RESET$10}`);
5566
+ console.log(`${DIM$10}未找到${scopeLabel}技能。${RESET$10}`);
5567
+ if (scope) console.log(`${DIM$10}尝试不带 -g 参数列出项目技能${RESET$10}`);
5568
+ else console.log(`${DIM$10}尝试带 -g 参数列出全局技能${RESET$10}`);
5569
5569
  return;
5570
5570
  }
5571
5571
  function printSkill(skill, indent = false, maxNameLength = 0, maxPathLength = 0) {
@@ -5577,7 +5577,7 @@ async function runList(args) {
5577
5577
  const paddedPath = shortPath.padEnd(maxPathLength);
5578
5578
  console.log(`${prefix}${CYAN$1}${paddedName}${RESET$10} ${DIM$10}${paddedPath}${RESET$10} ${DIM$10}Agents:${RESET$10} ${agentInfo}`);
5579
5579
  }
5580
- console.log(`${BOLD$7}${scopeLabel} Skills${RESET$10}`);
5580
+ console.log(`${BOLD$7}${scopeLabel}技能${RESET$10}`);
5581
5581
  console.log();
5582
5582
  const groupedSkills = {};
5583
5583
  const ungroupedSkills = [];
@@ -5609,7 +5609,7 @@ async function runList(args) {
5609
5609
  console.log();
5610
5610
  }
5611
5611
  if (ungroupedSkills.length > 0) {
5612
- console.log(`${BOLD$7}General${RESET$10}`);
5612
+ console.log(`${BOLD$7}通用${RESET$10}`);
5613
5613
  let maxNameLength = 0;
5614
5614
  let maxPathLength = 0;
5615
5615
  for (const skill of ungroupedSkills) {
@@ -5638,12 +5638,12 @@ async function removeCommand(skillNames, options) {
5638
5638
  const agentResult = await detectAgent();
5639
5639
  if (agentResult.isAgent) {
5640
5640
  options.yes = true;
5641
- log.info(import_picocolors.default.bgCyan(import_picocolors.default.black(import_picocolors.default.bold(` ${agentResult.agent.name} `))) + " Agent detected — removing non-interactively");
5641
+ log.info(import_picocolors.default.bgCyan(import_picocolors.default.black(import_picocolors.default.bold(` ${agentResult.agent.name} `))) + " 已检测到 Agent — 以非交互模式卸载");
5642
5642
  }
5643
5643
  const isGlobal = options.global ?? false;
5644
5644
  const cwd = process.cwd();
5645
5645
  const spinner$1 = spinner();
5646
- spinner$1.start("Scanning for installed skills...");
5646
+ spinner$1.start("正在扫描已安装的技能...");
5647
5647
  const skillNamesSet = /* @__PURE__ */ new Set();
5648
5648
  const scanDir = async (dir) => {
5649
5649
  try {
@@ -5662,17 +5662,17 @@ async function removeCommand(skillNames, options) {
5662
5662
  for (const subagent of getEveSubagents(cwd)) await scanDir(getEveSubagentSkillsDir(subagent, cwd));
5663
5663
  }
5664
5664
  const installedSkills = Array.from(skillNamesSet).sort();
5665
- spinner$1.stop(`Found ${installedSkills.length} unique installed skill(s)`);
5665
+ spinner$1.stop(`发现 ${installedSkills.length} 个已安装技能`);
5666
5666
  if (installedSkills.length === 0) {
5667
- outro(import_picocolors.default.yellow("No skills found to remove."));
5667
+ outro(import_picocolors.default.yellow("没有可卸载的技能。"));
5668
5668
  return;
5669
5669
  }
5670
5670
  if (options.agent && options.agent.length > 0) {
5671
5671
  const validAgents = Object.keys(agents);
5672
5672
  const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
5673
5673
  if (invalidAgents.length > 0) {
5674
- log.error(`Invalid agents: ${invalidAgents.join(", ")}`);
5675
- log.info(`Valid agents: ${validAgents.join(", ")}`);
5674
+ log.error(`无效 Agent:${invalidAgents.join(", ")}`);
5675
+ log.info(`可用 Agent:${validAgents.join(", ")}`);
5676
5676
  process.exit(1);
5677
5677
  }
5678
5678
  }
@@ -5681,7 +5681,7 @@ async function removeCommand(skillNames, options) {
5681
5681
  else if (skillNames.length > 0) {
5682
5682
  selectedSkills = installedSkills.filter((s) => skillNames.some((name) => name.toLowerCase() === s.toLowerCase()));
5683
5683
  if (selectedSkills.length === 0) {
5684
- log.error(`No matching skills found for: ${skillNames.join(", ")}`);
5684
+ log.error(`未找到匹配技能:${skillNames.join(", ")}`);
5685
5685
  return;
5686
5686
  }
5687
5687
  } else {
@@ -5695,7 +5695,7 @@ async function removeCommand(skillNames, options) {
5695
5695
  required: true
5696
5696
  });
5697
5697
  if (isCancel(selected)) {
5698
- cancel("Removal cancelled");
5698
+ cancel("卸载已取消");
5699
5699
  process.exit(0);
5700
5700
  }
5701
5701
  selectedSkills = selected;
@@ -5708,16 +5708,16 @@ async function removeCommand(skillNames, options) {
5708
5708
  }
5709
5709
  if (!options.yes) {
5710
5710
  console.log();
5711
- log.info("Skills to remove:");
5711
+ log.info("要卸载的技能:");
5712
5712
  for (const skill of selectedSkills) log.message(` ${import_picocolors.default.red("•")} ${skill}`);
5713
5713
  console.log();
5714
- const confirmed = await confirm({ message: `Are you sure you want to uninstall ${selectedSkills.length} skill(s)?` });
5714
+ const confirmed = await confirm({ message: `确认要卸载 ${selectedSkills.length} 个技能?` });
5715
5715
  if (isCancel(confirmed) || !confirmed) {
5716
- cancel("Removal cancelled");
5716
+ cancel("卸载已取消");
5717
5717
  process.exit(0);
5718
5718
  }
5719
5719
  }
5720
- spinner$1.start("Removing skills...");
5720
+ spinner$1.start("正在卸载技能...");
5721
5721
  const results = [];
5722
5722
  for (const skillName of selectedSkills) try {
5723
5723
  const canonicalPath = getCanonicalPath(skillName, {
@@ -5779,7 +5779,7 @@ async function removeCommand(skillNames, options) {
5779
5779
  error: err instanceof Error ? err.message : String(err)
5780
5780
  });
5781
5781
  }
5782
- spinner$1.stop("Removal process complete");
5782
+ spinner$1.stop("卸载完成");
5783
5783
  const successful = results.filter((r) => r.success);
5784
5784
  const failed = results.filter((r) => !r.success);
5785
5785
  if (successful.length > 0) {
@@ -5793,13 +5793,13 @@ async function removeCommand(skillNames, options) {
5793
5793
  }
5794
5794
  for (const [source, data] of bySource) data.skills.join(","), targetAgents.join(","), { ...isGlobal && { global: "1" } }, data.sourceType;
5795
5795
  }
5796
- if (successful.length > 0) log.success(import_picocolors.default.green(`Successfully removed ${successful.length} skill(s)`));
5796
+ if (successful.length > 0) log.success(import_picocolors.default.green(`已成功卸载 ${successful.length} 个技能`));
5797
5797
  if (failed.length > 0) {
5798
- log.error(import_picocolors.default.red(`Failed to remove ${failed.length} skill(s)`));
5798
+ log.error(import_picocolors.default.red(`卸载失败 ${failed.length} 个`));
5799
5799
  for (const r of failed) log.message(` ${import_picocolors.default.red("✗")} ${r.skill}: ${r.error}`);
5800
5800
  }
5801
5801
  console.log();
5802
- outro(import_picocolors.default.green("Done!"));
5802
+ outro(import_picocolors.default.green("完成!"));
5803
5803
  }
5804
5804
  function parseRemoveOptions(args) {
5805
5805
  const options = {};
@@ -5916,27 +5916,27 @@ async function resolveUpdateScope(options) {
5916
5916
  if (options.project) return "project";
5917
5917
  if (options.yes || !process.stdin.isTTY) return hasProjectSkills() ? "project" : "global";
5918
5918
  const scope = await select({
5919
- message: "Update scope",
5919
+ message: "更新范围",
5920
5920
  options: [
5921
5921
  {
5922
5922
  value: "project",
5923
- label: "Project",
5924
- hint: "Update skills in current directory"
5923
+ label: "项目",
5924
+ hint: "更新当前目录中的技能"
5925
5925
  },
5926
5926
  {
5927
5927
  value: "global",
5928
- label: "Global",
5929
- hint: "Update skills in home directory"
5928
+ label: "全局",
5929
+ hint: "更新主目录中的技能"
5930
5930
  },
5931
5931
  {
5932
5932
  value: "both",
5933
- label: "Both",
5934
- hint: "Update all skills"
5933
+ label: "全部",
5934
+ hint: "更新所有技能"
5935
5935
  }
5936
5936
  ]
5937
5937
  });
5938
5938
  if (isCancel(scope)) {
5939
- cancel("Cancelled");
5939
+ cancel("已取消");
5940
5940
  process.exit(0);
5941
5941
  }
5942
5942
  return scope;
@@ -5947,12 +5947,12 @@ function matchesSkillFilter(name, filter) {
5947
5947
  return filter.some((f) => f.toLowerCase() === lower);
5948
5948
  }
5949
5949
  function getSkipReason(entry) {
5950
- if (entry.sourceType === "local") return "Local path";
5951
- if (entry.sourceType === "git") return "Git URL";
5952
- if (entry.sourceType === "well-known") return "Well-known skill";
5953
- if (!entry.skillFolderHash) return "Private or deleted repo";
5954
- if (!entry.skillPath) return "No skill path recorded";
5955
- return "No version tracking";
5950
+ if (entry.sourceType === "local") return "本地路径";
5951
+ if (entry.sourceType === "git") return "Git 地址";
5952
+ if (entry.sourceType === "well-known") return "Well-known 技能";
5953
+ if (!entry.skillFolderHash) return "私有或已删除的仓库";
5954
+ if (!entry.skillPath) return "无路径记录";
5955
+ return "无版本跟踪";
5956
5956
  }
5957
5957
  function getInstallSource(skill) {
5958
5958
  let url = skill.sourceUrl;
@@ -5965,7 +5965,7 @@ function getInstallSource(skill) {
5965
5965
  function printSkippedSkills(skipped) {
5966
5966
  if (skipped.length === 0) return;
5967
5967
  console.log();
5968
- console.log(`${DIM$9}${skipped.length} skill(s) cannot be checked automatically:${RESET$9}`);
5968
+ console.log(`${DIM$9}${skipped.length} 个技能无法自动检查:${RESET$9}`);
5969
5969
  const grouped = /* @__PURE__ */ new Map();
5970
5970
  for (const skill of skipped) {
5971
5971
  const source = getInstallSource(skill);
@@ -5982,7 +5982,7 @@ function printSkippedSkills(skipped) {
5982
5982
  const names = skills.map((s) => sanitizeMetadata(s.name)).join(", ");
5983
5983
  console.log(` ${TEXT$8}•${RESET$9} ${names} ${DIM$9}(${reason})${RESET$9}`);
5984
5984
  }
5985
- console.log(` ${DIM$9}To update: ${TEXT$8}npx skills add ${source} -g -y${RESET$9}`);
5985
+ console.log(` ${DIM$9}更新方法:${TEXT$8}npx skills add ${source} -g -y${RESET$9}`);
5986
5986
  }
5987
5987
  }
5988
5988
  async function getProjectSkillsForUpdate(skillFilter) {
@@ -6007,13 +6007,13 @@ async function checkAndPromptForDeletions(source, allLockedForSource, lockSkills
6007
6007
  });
6008
6008
  if (deletedSkills.length > 0) {
6009
6009
  console.log();
6010
- console.log(`${DIM$9}Warning:${RESET$9} The following skills from ${DIM$9}${source}${RESET$9} appear to have been deleted upstream:`);
6010
+ console.log(`${DIM$9}警告:${RESET$9} 以下来自 ${DIM$9}${source}${RESET$9} 的技能似乎已在源仓库中删除:`);
6011
6011
  for (const s of deletedSkills) console.log(` ${DIM$9}•${RESET$9} ${s}`);
6012
- if (options.yes || !process.stdin.isTTY) console.log(`${DIM$9}Skipping deletion in non-interactive mode.${RESET$9}`);
6012
+ if (options.yes || !process.stdin.isTTY) console.log(`${DIM$9}非交互模式,跳过删除。${RESET$9}`);
6013
6013
  else {
6014
- const confirmed = await confirm({ message: `Would you like to remove the local copies of these deleted skills?` });
6014
+ const confirmed = await confirm({ message: `是否删除这些已删除技能的本地副本?` });
6015
6015
  if (confirmed && !isCancel(confirmed)) for (const s of deletedSkills) {
6016
- console.log(`${DIM$9}Removing${RESET$9} ${s}...`);
6016
+ console.log(`${DIM$9}正在卸载${RESET$9} ${s}...`);
6017
6017
  await removeCommand([s], {
6018
6018
  yes: true,
6019
6019
  global: isGlobal
@@ -6030,8 +6030,8 @@ async function updateGlobalSkills(options = {}) {
6030
6030
  let failCount = 0;
6031
6031
  if (skillNames.length === 0) {
6032
6032
  if (!options.skills) {
6033
- console.log(`${DIM$9}No global skills tracked in lock file.${RESET$9}`);
6034
- console.log(`${DIM$9}Install skills with${RESET$9} ${TEXT$8}npx skills add <package> -g${RESET$9}`);
6033
+ console.log(`${DIM$9}锁文件中没有跟踪的全局技能。${RESET$9}`);
6034
+ console.log(`${DIM$9}安装技能:${RESET$9} ${TEXT$8}npx skills add <package> -g${RESET$9}`);
6035
6035
  }
6036
6036
  return {
6037
6037
  successCount,
@@ -6120,7 +6120,7 @@ async function updateGlobalSkills(options = {}) {
6120
6120
  if (checkable.length > 0) process.stdout.write("\r\x1B[K");
6121
6121
  const checkedCount = checkable.length + skipped.length;
6122
6122
  if (checkable.length === 0 && skipped.length === 0) {
6123
- if (!options.skills) console.log(`${DIM$9}No global skills to check.${RESET$9}`);
6123
+ if (!options.skills) console.log(`${DIM$9}没有可检查的全局技能。${RESET$9}`);
6124
6124
  return {
6125
6125
  successCount,
6126
6126
  failCount,
@@ -6136,18 +6136,18 @@ async function updateGlobalSkills(options = {}) {
6136
6136
  };
6137
6137
  }
6138
6138
  if (updates.length === 0) {
6139
- console.log(`${TEXT$8}✓ All global skills are up to date${RESET$9}`);
6139
+ console.log(`${TEXT$8}✓ 所有全局技能已是最新${RESET$9}`);
6140
6140
  return {
6141
6141
  successCount,
6142
6142
  failCount,
6143
6143
  checkedCount
6144
6144
  };
6145
6145
  }
6146
- console.log(`${TEXT$8}Found ${updates.length} global update(s)${RESET$9}`);
6146
+ console.log(`${TEXT$8}发现 ${updates.length} 个可更新全局技能${RESET$9}`);
6147
6147
  console.log();
6148
6148
  for (const update of updates) {
6149
6149
  const safeName = sanitizeMetadata(update.name);
6150
- console.log(`${TEXT$8}Updating ${safeName}...${RESET$9}`);
6150
+ console.log(`${TEXT$8}正在更新 ${safeName}...${RESET$9}`);
6151
6151
  const installUrl = buildUpdateInstallSource(update.entry);
6152
6152
  if (!installUrl) {
6153
6153
  failCount++;
@@ -6176,10 +6176,10 @@ async function updateGlobalSkills(options = {}) {
6176
6176
  shell: false
6177
6177
  }).status === 0) {
6178
6178
  successCount++;
6179
- console.log(` ${TEXT$8}✓${RESET$9} Updated ${safeName}`);
6179
+ console.log(` ${TEXT$8}✓${RESET$9} 已更新 ${safeName}`);
6180
6180
  } else {
6181
6181
  failCount++;
6182
- console.log(` ${DIM$9}✗ Failed to update ${safeName}${RESET$9}`);
6182
+ console.log(` ${DIM$9}✗ 更新 ${safeName} 失败${RESET$9}`);
6183
6183
  }
6184
6184
  }
6185
6185
  printSkippedSkills(skipped);
@@ -6195,7 +6195,7 @@ async function updateProjectSkills(options = {}) {
6195
6195
  let failCount = 0;
6196
6196
  if (projectSkills.length === 0) {
6197
6197
  if (!options.skills) {
6198
- console.log(`${DIM$9}No project skills to update.${RESET$9}`);
6198
+ console.log(`${DIM$9}没有可更新的项目技能。${RESET$9}`);
6199
6199
  console.log(`${DIM$9}Install project skills with${RESET$9} ${TEXT$8}npx skills add <package>${RESET$9}`);
6200
6200
  }
6201
6201
  return {
@@ -6227,8 +6227,8 @@ async function updateProjectSkills(options = {}) {
6227
6227
  const targetParts = [];
6228
6228
  if (hasUniversal) targetParts.push("Universal");
6229
6229
  targetParts.push(...targetAgentNames);
6230
- if (targetParts.length > 0) console.log(`${TEXT$8}Updating for: ${targetParts.join(", ")}${RESET$9}`);
6231
- console.log(`${TEXT$8}Refreshing ${updatable.length} skill(s)...${RESET$9}`);
6230
+ if (targetParts.length > 0) console.log(`${TEXT$8}更新目标:${targetParts.join(", ")}${RESET$9}`);
6231
+ console.log(`${TEXT$8}正在刷新 ${updatable.length} 个技能...${RESET$9}`);
6232
6232
  console.log();
6233
6233
  const bySource = /* @__PURE__ */ new Map();
6234
6234
  for (const skill of updatable) {
@@ -6240,7 +6240,7 @@ async function updateProjectSkills(options = {}) {
6240
6240
  const localLock = await readLocalLock();
6241
6241
  const cliEntry = join(__dirname$1, "..", "bin", "cli.mjs");
6242
6242
  if (!existsSync(cliEntry)) {
6243
- console.log(`${DIM$9}✗ CLI entrypoint not found at ${cliEntry}${RESET$9}`);
6243
+ console.log(`${DIM$9}✗ CLI 入口未找到 ${cliEntry}${RESET$9}`);
6244
6244
  return {
6245
6245
  successCount,
6246
6246
  failCount: updatable.length,
@@ -6266,14 +6266,14 @@ async function updateProjectSkills(options = {}) {
6266
6266
  });
6267
6267
  deletedSkills = await checkAndPromptForDeletions(source, allLockedForSource, localLock.skills, false, options, discoveredPaths);
6268
6268
  } catch (error) {
6269
- console.log(`${DIM$9}✗ Failed to check for deleted skills from ${source}${RESET$9}`);
6269
+ console.log(`${DIM$9}✗ 检查 ${source} 已删除技能失败${RESET$9}`);
6270
6270
  } finally {
6271
6271
  if (tempDir) await cleanupTempDir(tempDir);
6272
6272
  }
6273
6273
  const remainingSkills = skillsForSource.filter((s) => !deletedSkills.includes(s.name));
6274
6274
  for (const skill of remainingSkills) {
6275
6275
  const safeName = sanitizeMetadata(skill.name);
6276
- console.log(`${TEXT$8}Updating ${safeName}...${RESET$9}`);
6276
+ console.log(`${TEXT$8}正在更新 ${safeName}...${RESET$9}`);
6277
6277
  const installUrl = buildLocalUpdateSource(skill.entry);
6278
6278
  if (!installUrl) {
6279
6279
  failCount++;
@@ -6299,10 +6299,10 @@ async function updateProjectSkills(options = {}) {
6299
6299
  shell: false
6300
6300
  }).status === 0) {
6301
6301
  successCount++;
6302
- console.log(` ${TEXT$8}✓${RESET$9} Updated ${safeName}`);
6302
+ console.log(` ${TEXT$8}✓${RESET$9} 已更新 ${safeName}`);
6303
6303
  } else {
6304
6304
  failCount++;
6305
- console.log(` ${DIM$9}✗ Failed to update ${safeName}${RESET$9}`);
6305
+ console.log(` ${DIM$9}✗ 更新 ${safeName} 失败${RESET$9}`);
6306
6306
  }
6307
6307
  }
6308
6308
  }
@@ -6320,21 +6320,21 @@ function printLegacyProjectSkills(legacy) {
6320
6320
  for (const skill of legacy) {
6321
6321
  const reinstall = buildLocalUpdateSource(skill.entry);
6322
6322
  console.log(` ${TEXT$8}•${RESET$9} ${sanitizeMetadata(skill.name)}`);
6323
- if (reinstall) console.log(` ${DIM$9}To refresh: ${TEXT$8}npx skills add ${reinstall} -y${RESET$9}`);
6323
+ if (reinstall) console.log(` ${DIM$9}刷新方法:${TEXT$8}npx skills add ${reinstall} -y${RESET$9}`);
6324
6324
  else console.log(` ${DIM$9}To refresh: reinstall using the original full Git URL; this lock entry only has an ambiguous shorthand.${RESET$9}`);
6325
6325
  }
6326
6326
  }
6327
6327
  async function runUpdate(args = []) {
6328
6328
  const options = parseUpdateOptions(args);
6329
6329
  const scope = await resolveUpdateScope(options);
6330
- if (options.skills) console.log(`${TEXT$8}Updating ${options.skills.join(", ")}...${RESET$9}`);
6331
- else console.log(`${TEXT$8}Checking for skill updates...${RESET$9}`);
6330
+ if (options.skills) console.log(`${TEXT$8}正在更新 ${options.skills.join(", ")}...${RESET$9}`);
6331
+ else console.log(`${TEXT$8}正在检查技能更新...${RESET$9}`);
6332
6332
  console.log();
6333
6333
  let totalSuccess = 0;
6334
6334
  let totalFail = 0;
6335
6335
  let totalFound = 0;
6336
6336
  if (scope === "global" || scope === "both") {
6337
- if (scope === "both" && !options.skills) console.log(`${BOLD$6}Global Skills${RESET$9}`);
6337
+ if (scope === "both" && !options.skills) console.log(`${BOLD$6}全局技能${RESET$9}`);
6338
6338
  const { successCount, failCount, checkedCount } = await updateGlobalSkills(options);
6339
6339
  totalSuccess += successCount;
6340
6340
  totalFail += failCount;
@@ -6342,17 +6342,17 @@ async function runUpdate(args = []) {
6342
6342
  if (scope === "both" && !options.skills) console.log();
6343
6343
  }
6344
6344
  if (scope === "project" || scope === "both") {
6345
- if (scope === "both" && !options.skills) console.log(`${BOLD$6}Project Skills${RESET$9}`);
6345
+ if (scope === "both" && !options.skills) console.log(`${BOLD$6}项目技能${RESET$9}`);
6346
6346
  const { successCount, failCount, foundCount } = await updateProjectSkills(options);
6347
6347
  totalSuccess += successCount;
6348
6348
  totalFail += failCount;
6349
6349
  totalFound += foundCount;
6350
6350
  }
6351
- if (options.skills && totalFound === 0) console.log(`${DIM$9}No installed skills found matching: ${options.skills.join(", ")}${RESET$9}`);
6351
+ if (options.skills && totalFound === 0) console.log(`${DIM$9}未找到匹配的已安装技能:${options.skills.join(", ")}${RESET$9}`);
6352
6352
  console.log();
6353
- if (totalSuccess > 0) console.log(`${TEXT$8}✓ Updated ${totalSuccess} skill(s)${RESET$9}`);
6353
+ if (totalSuccess > 0) console.log(`${TEXT$8}✓ 已更新 ${totalSuccess} 个技能${RESET$9}`);
6354
6354
  if (totalFail > 0) {
6355
- console.log(`${DIM$9}Failed to update ${totalFail} skill(s)${RESET$9}`);
6355
+ console.log(`${DIM$9}更新失败 ${totalFail} 个技能${RESET$9}`);
6356
6356
  process.exitCode = 1;
6357
6357
  }
6358
6358
  String(totalSuccess + totalFail);
@@ -6394,7 +6394,7 @@ function parseUseOptions(args) {
6394
6394
  const value = args[i + 1];
6395
6395
  if (!value || value.startsWith("-")) errors.push(`${arg} requires a skill name`);
6396
6396
  else if (options.skill) {
6397
- errors.push("Only one --skill value can be provided");
6397
+ errors.push("只能提供一个 --skill 值");
6398
6398
  i++;
6399
6399
  } else {
6400
6400
  options.skill = value;
@@ -6412,7 +6412,7 @@ function parseUseOptions(args) {
6412
6412
  }
6413
6413
  if (options.agent.length === startCount) errors.push(`${arg} requires an agent name`);
6414
6414
  i--;
6415
- } else if (arg.startsWith("-")) errors.push(`Unknown option: ${arg}`);
6415
+ } else if (arg.startsWith("-")) errors.push(`未知选项:${arg}`);
6416
6416
  else source.push(arg);
6417
6417
  }
6418
6418
  errors.push(...validateUseAgentOption(options.agent));
@@ -6454,15 +6454,15 @@ async function runUse(sourceArgs, options = {}, parseErrors = []) {
6454
6454
  return;
6455
6455
  }
6456
6456
  if (parseErrors.length > 0) fail(parseErrors.join("\n"));
6457
- if (sourceArgs.length === 0) fail(`Missing required argument: source\n\n${getUseHelp()}`);
6458
- if (sourceArgs.length > 1) fail(`Expected one source, received ${sourceArgs.length}: ${sourceArgs.join(", ")}`);
6457
+ if (sourceArgs.length === 0) fail(`缺少必要参数:source\n\n${getUseHelp()}`);
6458
+ if (sourceArgs.length > 1) fail(`期望一个源,收到 ${sourceArgs.length} 个:${sourceArgs.join(", ")}`);
6459
6459
  const useAgent = options.agent?.[0];
6460
6460
  if (useAgent && !USE_AGENT_CONFIGS[useAgent]) fail(formatUnsupportedAgentError(useAgent));
6461
6461
  const source = sourceArgs[0];
6462
6462
  const parsed = parseSource(source);
6463
6463
  if (getOwnerRepo(parsed)?.split("/")[0]?.toLowerCase() === "openclaw" && !options.dangerouslyAcceptOpenclawRisks) fail([
6464
6464
  "OpenClaw skills are unverified community submissions.",
6465
- "Skills run with full agent permissions and could be malicious.",
6465
+ "技能以 Agent 的全部权限运行,可能存在恶意行为。",
6466
6466
  `If you understand the risks, re-run with: skills use ${source} --dangerously-accept-openclaw-risks`
6467
6467
  ].join("\n"));
6468
6468
  const selector = resolveSelector(parsed.skillFilter, options.skill);
@@ -6550,7 +6550,7 @@ async function launchAgentInteractively(agent, prompt, spawnImpl = spawnAgent) {
6550
6550
  if (settled) return;
6551
6551
  settled = true;
6552
6552
  if (error.code === "ENOENT") {
6553
- reject(new UseCommandError(`Could not launch ${agents[agent].displayName}: command not found: ${config.command}`));
6553
+ reject(new UseCommandError(`无法启动 ${agents[agent].displayName}:未找到命令:${config.command}`));
6554
6554
  return;
6555
6555
  }
6556
6556
  reject(error);
@@ -6591,7 +6591,7 @@ function resolveSelector(sourceSelector, optionSelector) {
6591
6591
  return optionSelector ?? sourceSelector;
6592
6592
  }
6593
6593
  function selectSkill(skills, selector, source) {
6594
- if (skills.length === 0) throw new UseCommandError("No valid skills found. Skills require a SKILL.md with name and description.");
6594
+ if (skills.length === 0) throw new UseCommandError("未找到有效技能。技能需要包含 name 和 description 的 SKILL.md 文件。");
6595
6595
  if (!selector) {
6596
6596
  if (skills.length === 1) return skills[0];
6597
6597
  throw new UseCommandError(formatMultipleSkillsError(source, skills.map(getSkillDisplayName)));
@@ -6602,7 +6602,7 @@ function selectSkill(skills, selector, source) {
6602
6602
  return selected[0];
6603
6603
  }
6604
6604
  function selectWellKnownSkill(skills, selector, source) {
6605
- if (skills.length === 0) throw new UseCommandError("No skills found at this URL. Make sure the server has a /.well-known/agent-skills/index.json or /.well-known/skills/index.json file.");
6605
+ if (skills.length === 0) throw new UseCommandError("该 URL 未找到技能。请确保服务器提供 /.well-known/agent-skills/index.json 或 /.well-known/skills/index.json 文件。");
6606
6606
  let selected;
6607
6607
  if (!selector) {
6608
6608
  if (skills.length !== 1) throw new UseCommandError(formatMultipleSkillsError(source, skills.map((s) => s.installName)));
@@ -6623,7 +6623,7 @@ function selectWellKnownSkill(skills, selector, source) {
6623
6623
  }
6624
6624
  function formatMultipleSkillsError(source, names) {
6625
6625
  return [
6626
- "This source contains multiple skills. Specify exactly one skill:",
6626
+ "该源包含多个技能。请指定一个技能:",
6627
6627
  ...names.map((name) => ` - ${name}`),
6628
6628
  "",
6629
6629
  `Examples:\n skills use ${source}@${names[0] ?? "<skill>"}\n skills use ${source} --skill ${names[0] ?? "<skill>"}`
@@ -6632,7 +6632,7 @@ function formatMultipleSkillsError(source, names) {
6632
6632
  function formatNoMatchError(selector, names) {
6633
6633
  return [
6634
6634
  `No matching skill found for: ${selector}`,
6635
- "Available skills:",
6635
+ "可用技能:",
6636
6636
  ...names.map((name) => ` - ${name}`)
6637
6637
  ].join("\n");
6638
6638
  }
@@ -6647,7 +6647,7 @@ function validateUseAgentOption(agentValues) {
6647
6647
  return errors;
6648
6648
  }
6649
6649
  function formatUnsupportedAgentError(agent) {
6650
- return [`Running ${agents[agent].displayName} is not supported yet.`, `Supported agents for skills use --agent: ${SUPPORTED_USE_AGENTS.join(", ")}`].join("\n");
6650
+ return [`暂不支持运行 ${agents[agent].displayName}。`, `skills use --agent 支持的 Agent:${SUPPORTED_USE_AGENTS.join(", ")}`].join("\n");
6651
6651
  }
6652
6652
  async function writeSnapshotFiles(targetDir, files) {
6653
6653
  for (const file of files) await writeSafeFile(targetDir, file.path, file.contents);
@@ -6724,7 +6724,7 @@ async function runLogin(args, globalOpts) {
6724
6724
  const token = getOptionValue$3(args, "--token");
6725
6725
  const { registry } = resolveConfig(globalOpts);
6726
6726
  if (!token) {
6727
- console.error("Usage: bfi auth login --token <token>");
6727
+ console.error("用法:bfi auth login --token <token>");
6728
6728
  process.exit(1);
6729
6729
  }
6730
6730
  const api = new SkillHubAPI(registry, token);
@@ -6740,10 +6740,10 @@ async function runLogin(args, globalOpts) {
6740
6740
  handle: String(userInfo.handle || "")
6741
6741
  };
6742
6742
  saveGlobalConfig(config);
6743
- console.log(`✓ Logged in as ${userInfo.displayName || userInfo.name || "Unknown"}`);
6744
- console.log(` Registry: ${registry}`);
6743
+ console.log(`✓ 已登录为 ${userInfo.displayName || userInfo.name || "Unknown"}`);
6744
+ console.log(` 注册中心:${registry}`);
6745
6745
  } catch (error) {
6746
- console.error(`Login failed: ${error.message}`);
6746
+ console.error(`登录失败:${error.message}`);
6747
6747
  process.exit(1);
6748
6748
  }
6749
6749
  }
@@ -6753,21 +6753,21 @@ async function runLogout() {
6753
6753
  delete config.token;
6754
6754
  delete config.user;
6755
6755
  saveGlobalConfig(config);
6756
- console.log("✓ Logged out");
6757
- } else console.log("Not logged in.");
6756
+ console.log("✓ 已登出");
6757
+ } else console.log("未登录。");
6758
6758
  }
6759
6759
  async function runWhoami(globalOpts) {
6760
6760
  const { registry, token } = resolveConfig(globalOpts);
6761
6761
  if (!token) {
6762
- console.error("Not authenticated. Run: bfi auth login --token <token>");
6762
+ console.error("未认证。运行:bfi auth login --token <token>");
6763
6763
  process.exit(1);
6764
6764
  }
6765
6765
  const response = await new SkillHubAPI(registry, token).whoami();
6766
6766
  const user = response.user || response;
6767
- console.log(`\nCurrent User:`);
6768
- console.log(` Name: ${user.displayName || user.name || "N/A"}`);
6769
- console.log(` Handle: ${user.handle || "N/A"}`);
6770
- console.log(` ID: ${user.id || "N/A"}`);
6767
+ console.log(`\n当前用户:`);
6768
+ console.log(` 名称: ${user.displayName || user.name || "N/A"}`);
6769
+ console.log(` 句柄: ${user.handle || "N/A"}`);
6770
+ console.log(` ID: ${user.id || "N/A"}`);
6771
6771
  console.log();
6772
6772
  }
6773
6773
  function getOptionValue$3(args, flag) {
@@ -6784,12 +6784,12 @@ async function runSearch(args, globalOpts) {
6784
6784
  const query = parseSearchQuery(args);
6785
6785
  const namespace = args.includes("--namespace") ? getOptionValue$2(args, "--namespace") : void 0;
6786
6786
  if (!query) {
6787
- console.log("Usage: bfi search <query> [--namespace <ns>] [--marketplace]");
6787
+ console.log("用法:bfi search <query> [--namespace <ns>] [--marketplace]");
6788
6788
  console.log();
6789
- console.log("Options:");
6790
- console.log(" --namespace <ns> Filter by SkillHub namespace");
6791
- console.log(" --marketplace Search skills.sh marketplace only");
6792
- console.log(" --all Search both SkillHub and marketplace");
6789
+ console.log("选项:");
6790
+ console.log(" --namespace <ns> 按 SkillHub 命名空间筛选");
6791
+ console.log(" --marketplace 仅搜索 skills.sh 市场");
6792
+ console.log(" --all 同时搜索 SkillHub 和市场");
6793
6793
  return;
6794
6794
  }
6795
6795
  const useMarketplace = args.includes("--marketplace");
@@ -6799,9 +6799,9 @@ async function runSearch(args, globalOpts) {
6799
6799
  return;
6800
6800
  }
6801
6801
  if (searchAll) {
6802
- console.log(`${BOLD$5}=== SkillHub Registry ===${RESET$8}\n`);
6802
+ console.log(`${BOLD$5}=== SkillHub 注册表 ===${RESET$8}\n`);
6803
6803
  await searchSkillHub(query, namespace, globalOpts);
6804
- console.log(`\n${BOLD$5}=== skills.sh Marketplace ===${RESET$8}\n`);
6804
+ console.log(`\n${BOLD$5}=== skills.sh 市场 ===${RESET$8}\n`);
6805
6805
  await searchMarketplace(query);
6806
6806
  return;
6807
6807
  }
@@ -6831,10 +6831,10 @@ async function searchSkillHub(query, namespace, globalOpts) {
6831
6831
  });
6832
6832
  const skills = result.results || result.data || [];
6833
6833
  if (skills.length === 0) {
6834
- console.log(`${DIM$8}No skills found on SkillHub for "${query}"${RESET$8}`);
6834
+ console.log(`${DIM$8}SkillHub 上未找到 "${query}" 的技能${RESET$8}`);
6835
6835
  return;
6836
6836
  }
6837
- console.log(`Found ${skills.length} skill(s) on SkillHub:\n`);
6837
+ console.log(`SkillHub 上找到 ${skills.length} 个技能:\n`);
6838
6838
  for (const skill of skills) {
6839
6839
  const name = skill.displayName || skill.name || skill.slug;
6840
6840
  const desc = skill.summary || skill.description || "";
@@ -6846,7 +6846,7 @@ async function searchSkillHub(query, namespace, globalOpts) {
6846
6846
  console.log();
6847
6847
  }
6848
6848
  } catch (error) {
6849
- console.error(`${DIM$8}SkillHub search failed: ${error.message}${RESET$8}`);
6849
+ console.error(`${DIM$8}SkillHub 搜索失败:${error.message}${RESET$8}`);
6850
6850
  }
6851
6851
  }
6852
6852
  async function searchMarketplace(query) {
@@ -6858,15 +6858,15 @@ async function searchMarketplace(query) {
6858
6858
  const url = `${MARKETPLACE_API}/api/search?${params.toString()}`;
6859
6859
  const res = await fetch(url);
6860
6860
  if (!res.ok) {
6861
- console.log(`${DIM$8}No results from skills.sh marketplace${RESET$8}`);
6861
+ console.log(`${DIM$8}skills.sh 市场无结果${RESET$8}`);
6862
6862
  return;
6863
6863
  }
6864
6864
  const skills = (await res.json()).skills || [];
6865
6865
  if (skills.length === 0) {
6866
- console.log(`${DIM$8}No skills found on skills.sh for "${query}"${RESET$8}`);
6866
+ console.log(`${DIM$8}skills.sh 上未找到 "${query}" 的技能${RESET$8}`);
6867
6867
  return;
6868
6868
  }
6869
- console.log(`Found ${skills.length} skill(s) on skills.sh:\n`);
6869
+ console.log(`skills.sh 上找到 ${skills.length} 个技能:\n`);
6870
6870
  for (const skill of skills.slice(0, 12)) {
6871
6871
  const installs = formatInstalls(skill.installs);
6872
6872
  console.log(` ${BOLD$5}${skill.name}${RESET$8}`);
@@ -6876,14 +6876,14 @@ async function searchMarketplace(query) {
6876
6876
  console.log();
6877
6877
  }
6878
6878
  } catch {
6879
- console.log(`${DIM$8}skills.sh marketplace unavailable${RESET$8}`);
6879
+ console.log(`${DIM$8}skills.sh 市场不可用${RESET$8}`);
6880
6880
  }
6881
6881
  }
6882
6882
  function formatInstalls(count) {
6883
6883
  if (!count || count <= 0) return "";
6884
6884
  if (count >= 1e6) return `${(count / 1e6).toFixed(1).replace(/\.0$/, "")}M installs`;
6885
6885
  if (count >= 1e3) return `${(count / 1e3).toFixed(1).replace(/\.0$/, "")}K installs`;
6886
- return `${count} install${count === 1 ? "" : "s"}`;
6886
+ return `${count} 次安装`;
6887
6887
  }
6888
6888
  function truncate$2(text, maxLen) {
6889
6889
  if (text.length <= maxLen) return text;
@@ -6903,8 +6903,8 @@ const GREEN$4 = "\x1B[32m";
6903
6903
  async function runInfo(args, globalOpts) {
6904
6904
  const slug = args[0];
6905
6905
  if (!slug) {
6906
- console.log("Usage: bfi info <skill-slug>");
6907
- console.log("Example: bfi info global/my-skill");
6906
+ console.log("用法:bfi info <skill-slug>");
6907
+ console.log("示例:bfi info global/my-skill");
6908
6908
  process.exit(1);
6909
6909
  }
6910
6910
  const { registry, token } = resolveConfig(globalOpts);
@@ -6913,35 +6913,35 @@ async function runInfo(args, globalOpts) {
6913
6913
  const result = await api.getSkill(slug);
6914
6914
  const skill = result.data || result.skill || result;
6915
6915
  if (!skill || !skill.slug) {
6916
- console.log(`${DIM$7}Skill not found: ${slug}${RESET$7}`);
6916
+ console.log(`${DIM$7}未找到技能:${slug}${RESET$7}`);
6917
6917
  process.exit(1);
6918
6918
  }
6919
6919
  console.log();
6920
6920
  console.log(`${BOLD$4}${skill.displayName || skill.name || skill.slug}${RESET$7}`);
6921
6921
  console.log(`${DIM$7}${"─".repeat(48)}${RESET$7}`);
6922
- console.log(` ${BOLD$4}Slug:${RESET$7} ${TEXT$6}${skill.slug}${RESET$7}`);
6923
- if (skill.summary || skill.description) console.log(` ${BOLD$4}Description:${RESET$7} ${TEXT$6}${skill.summary || skill.description}${RESET$7}`);
6922
+ console.log(` ${BOLD$4}Slug:${RESET$7} ${TEXT$6}${skill.slug}${RESET$7}`);
6923
+ if (skill.summary || skill.description) console.log(` ${BOLD$4}描述:${RESET$7} ${TEXT$6}${skill.summary || skill.description}${RESET$7}`);
6924
6924
  const owner = skill.owner;
6925
6925
  if (owner) {
6926
- console.log(` ${BOLD$4}Owner:${RESET$7} ${TEXT$6}${owner.displayName || owner.handle}${RESET$7}`);
6927
- if (owner.handle) console.log(` ${BOLD$4}Handle:${RESET$7} ${TEXT$6}${owner.handle}${RESET$7}`);
6926
+ console.log(` ${BOLD$4}所有者:${RESET$7} ${TEXT$6}${owner.displayName || owner.handle}${RESET$7}`);
6927
+ if (owner.handle) console.log(` ${BOLD$4}句柄:${RESET$7} ${TEXT$6}${owner.handle}${RESET$7}`);
6928
6928
  }
6929
6929
  const latestVersion = skill.latestVersion;
6930
6930
  if (latestVersion) {
6931
- console.log(` ${BOLD$4}Version:${RESET$7} ${TEXT$6}${latestVersion.version || "N/A"}${RESET$7}`);
6932
- if (latestVersion.license) console.log(` ${BOLD$4}License:${RESET$7} ${TEXT$6}${latestVersion.license}${RESET$7}`);
6933
- if (latestVersion.changelog) console.log(` ${BOLD$4}Changelog:${RESET$7} ${DIM$7}${truncate$1(latestVersion.changelog, 80)}${RESET$7}`);
6931
+ console.log(` ${BOLD$4}版本:${RESET$7} ${TEXT$6}${latestVersion.version || "N/A"}${RESET$7}`);
6932
+ if (latestVersion.license) console.log(` ${BOLD$4}许可证:${RESET$7} ${TEXT$6}${latestVersion.license}${RESET$7}`);
6933
+ if (latestVersion.changelog) console.log(` ${BOLD$4}变更日志:${RESET$7} ${DIM$7}${truncate$1(latestVersion.changelog, 80)}${RESET$7}`);
6934
6934
  if (latestVersion.createdAt) {
6935
6935
  const date = new Date(latestVersion.createdAt).toISOString().split("T")[0];
6936
- console.log(` ${BOLD$4}Published:${RESET$7} ${TEXT$6}${date}${RESET$7}`);
6936
+ console.log(` ${BOLD$4}发布时间:${RESET$7} ${TEXT$6}${date}${RESET$7}`);
6937
6937
  }
6938
6938
  }
6939
6939
  const stats = skill.stats;
6940
6940
  if (stats) {
6941
6941
  console.log();
6942
- console.log(` ${BOLD$4}Stats:${RESET$7}`);
6943
- if (stats.downloads !== void 0) console.log(` Downloads: ${TEXT$6}${stats.downloads}${RESET$7}`);
6944
- if (stats.views !== void 0) console.log(` Views: ${TEXT$6}${stats.views}${RESET$7}`);
6942
+ console.log(` ${BOLD$4}统计:${RESET$7}`);
6943
+ if (stats.downloads !== void 0) console.log(` 下载量:${TEXT$6}${stats.downloads}${RESET$7}`);
6944
+ if (stats.views !== void 0) console.log(` 浏览量:${TEXT$6}${stats.views}${RESET$7}`);
6945
6945
  }
6946
6946
  const tags = skill.tags;
6947
6947
  if (Array.isArray(tags) && tags.length > 0) {
@@ -6949,33 +6949,33 @@ async function runInfo(args, globalOpts) {
6949
6949
  const tag = t;
6950
6950
  return tag.name || tag;
6951
6951
  }).join(", ");
6952
- console.log(` ${BOLD$4}Tags:${RESET$7} ${TEXT$6}${tagList}${RESET$7}`);
6952
+ console.log(` ${BOLD$4}标签:${RESET$7} ${TEXT$6}${tagList}${RESET$7}`);
6953
6953
  }
6954
6954
  const moderation = skill.moderation;
6955
6955
  if (moderation) {
6956
6956
  const verdict = moderation.verdict;
6957
6957
  if (verdict === "MALWARE_BLOCKED" || moderation.isMalwareBlocked) {
6958
6958
  console.log();
6959
- console.log(` ${RED$2}${BOLD$4}⚠ BLOCKED: Malware detected${RESET$7}`);
6959
+ console.log(` ${RED$2}${BOLD$4}⚠ 已封禁:检测到恶意软件${RESET$7}`);
6960
6960
  if (moderation.summary) console.log(` ${RED$2}${moderation.summary}${RESET$7}`);
6961
6961
  } else if (verdict === "SUSPICIOUS" || moderation.isSuspicious) {
6962
6962
  console.log();
6963
- console.log(` ${YELLOW$2}⚠ Suspicious skill${RESET$7}`);
6963
+ console.log(` ${YELLOW$2}⚠ 可疑技能${RESET$7}`);
6964
6964
  if (moderation.summary) console.log(` ${YELLOW$2}${moderation.summary}${RESET$7}`);
6965
- } else if (verdict === "SAFE") console.log(` ${BOLD$4}Safety:${RESET$7} ${GREEN$4}Verified safe${RESET$7}`);
6965
+ } else if (verdict === "SAFE") console.log(` ${BOLD$4}安全:${RESET$7} ${GREEN$4}已验证安全${RESET$7}`);
6966
6966
  }
6967
6967
  if (skill.createdAt) {
6968
6968
  const created = new Date(skill.createdAt).toISOString().split("T")[0];
6969
- console.log(` ${BOLD$4}Created:${RESET$7} ${TEXT$6}${created}${RESET$7}`);
6969
+ console.log(` ${BOLD$4}创建时间:${RESET$7} ${TEXT$6}${created}${RESET$7}`);
6970
6970
  }
6971
6971
  if (skill.updatedAt) {
6972
6972
  const updated = new Date(skill.updatedAt).toISOString().split("T")[0];
6973
- console.log(` ${BOLD$4}Updated:${RESET$7} ${TEXT$6}${updated}${RESET$7}`);
6973
+ console.log(` ${BOLD$4}更新时间:${RESET$7} ${TEXT$6}${updated}${RESET$7}`);
6974
6974
  }
6975
6975
  console.log();
6976
6976
  } catch (error) {
6977
- if (error.status === 404) console.error(`Skill not found: ${slug}`);
6978
- else console.error(`Failed to fetch skill info: ${error.message}`);
6977
+ if (error.status === 404) console.error(`未找到技能:${slug}`);
6978
+ else console.error(`获取技能信息失败:${error.message}`);
6979
6979
  process.exit(1);
6980
6980
  }
6981
6981
  }
@@ -6997,22 +6997,22 @@ async function runConfig(args, globalOpts) {
6997
6997
  }
6998
6998
  }
6999
6999
  function printConfigHelp() {
7000
- console.log("Config Commands:");
7001
- console.log(" bfi config get [key] Get configuration value");
7002
- console.log(" bfi config set <key> <value> Set configuration value");
7000
+ console.log("配置命令:");
7001
+ console.log(" bfi config get [key] 获取配置值");
7002
+ console.log(" bfi config set <key> <value> 设置配置值");
7003
7003
  console.log();
7004
- console.log("Available keys (global):");
7004
+ console.log("可用键(全局):");
7005
7005
  console.log(" registry API registry URL");
7006
7006
  console.log(" default-namespace Default namespace");
7007
7007
  console.log(" default-ide Default IDE");
7008
7008
  console.log();
7009
- console.log("Available keys (project):");
7009
+ console.log("可用键(项目):");
7010
7010
  console.log(" registry API registry URL");
7011
7011
  console.log(" namespace Project namespace");
7012
7012
  console.log(" ide Project IDE");
7013
7013
  console.log();
7014
- console.log("Flags:");
7015
- console.log(" --global Apply setting globally (default: project)");
7014
+ console.log("标志:");
7015
+ console.log(" --global 全局应用设置(默认:项目)");
7016
7016
  }
7017
7017
  async function handleGet(args, globalOpts) {
7018
7018
  const key = args[1];
@@ -7035,21 +7035,21 @@ async function handleGet(args, globalOpts) {
7035
7035
  const projectConfigKey = projectKeyMap[key] || key;
7036
7036
  const globalValue = globalConfig[globalConfigKey];
7037
7037
  const projectValue = projectConfig[projectConfigKey];
7038
- console.log(`\nConfiguration: ${key}`);
7038
+ console.log(`\n配置:${key}`);
7039
7039
  console.log("-".repeat(40));
7040
- if (projectValue !== void 0) console.log(`Project (.bfirc): ${projectValue}`);
7041
- else console.log(`Project (.bfirc): (not set)`);
7042
- if (globalValue !== void 0) console.log(`Global (~/.bfi/config.json): ${key === "token" ? "********" : globalValue}`);
7043
- else console.log(`Global (~/.bfi/config.json): (not set)`);
7040
+ if (projectValue !== void 0) console.log(`项目 (.bfirc):${projectValue}`);
7041
+ else console.log(`项目 (.bfirc):(未设置)`);
7042
+ if (globalValue !== void 0) console.log(`全局 (~/.bfi/config.json):${key === "token" ? "********" : globalValue}`);
7043
+ else console.log(`全局 (~/.bfi/config.json):(未设置)`);
7044
7044
  console.log();
7045
7045
  } else {
7046
- console.log("\nProject Configuration (.bfirc):");
7046
+ console.log("\n项目配置 (.bfirc):");
7047
7047
  console.log("-".repeat(40));
7048
- if (Object.keys(projectConfig).length === 0) console.log(" (no project config)");
7048
+ if (Object.keys(projectConfig).length === 0) console.log(" (无项目配置)");
7049
7049
  else for (const [k, v] of Object.entries(projectConfig)) console.log(` ${k}: ${v}`);
7050
- console.log("\nGlobal Configuration (~/.bfi/config.json):");
7050
+ console.log("\n全局配置 (~/.bfi/config.json):");
7051
7051
  console.log("-".repeat(40));
7052
- if (Object.keys(globalConfig).length === 0) console.log(" (no global config)");
7052
+ if (Object.keys(globalConfig).length === 0) console.log(" (无全局配置)");
7053
7053
  else for (const [k, v] of Object.entries(globalConfig)) console.log(` ${k}: ${k === "token" ? "********" : v}`);
7054
7054
  console.log();
7055
7055
  }
@@ -7058,9 +7058,9 @@ async function handleSet(args, _globalOpts) {
7058
7058
  const key = args[1];
7059
7059
  const value = args[2];
7060
7060
  if (!key || value === void 0) {
7061
- console.error("Usage: bfi config set <key> <value>");
7061
+ console.error("用法:bfi config set <key> <value>");
7062
7062
  console.log();
7063
- console.log("Use --global flag to set globally:");
7063
+ console.log("使用 --global 标志进行全局设置:");
7064
7064
  console.log(" bfi config set registry https://skillhub.example.com --global");
7065
7065
  console.log(" bfi config set namespace myteam --global");
7066
7066
  process.exit(1);
@@ -7073,13 +7073,13 @@ async function handleSet(args, _globalOpts) {
7073
7073
  "default-ide"
7074
7074
  ];
7075
7075
  if (!validKeys.includes(key)) {
7076
- console.error(`Invalid key: ${key}`);
7077
- console.log(`Valid keys: ${validKeys.join(", ")}`);
7076
+ console.error(`无效的键:${key}`);
7077
+ console.log(`有效键:${validKeys.join(", ")}`);
7078
7078
  process.exit(1);
7079
7079
  }
7080
7080
  const isGlobal = args.includes("--global");
7081
7081
  setConfigValue(key, value, isGlobal);
7082
- console.log(`${DIM$6}✓${RESET$6} Set ${key} = ${value} (${isGlobal ? "global" : "project"})`);
7082
+ console.log(`${DIM$6}✓${RESET$6} 已设置 ${key} = ${value}(${(isGlobal ? "global" : "project") === "global" ? "全局" : "项目"})`);
7083
7083
  }
7084
7084
  const RESET$5 = "\x1B[0m";
7085
7085
  const BOLD$3 = "\x1B[1m";
@@ -7100,12 +7100,12 @@ async function runDocs(args, globalOpts) {
7100
7100
  }
7101
7101
  }
7102
7102
  function printDocsHelp() {
7103
- console.log("Document Commands:");
7104
- console.log(" bfi docs upload <file> Upload a document for processing");
7105
- console.log(" bfi docs list List uploaded documents");
7106
- console.log(" bfi docs info <id> Show document processing status");
7103
+ console.log("文档命令:");
7104
+ console.log(" bfi docs upload <file> 上传文档进行解析");
7105
+ console.log(" bfi docs list 列出已上传文档");
7106
+ console.log(" bfi docs info <id> 查看文档处理状态");
7107
7107
  console.log();
7108
- console.log("Examples:");
7108
+ console.log("示例:");
7109
7109
  console.log(` ${DIM$5}$ ${RESET$5}bfi docs upload resume.pdf`);
7110
7110
  console.log(` ${DIM$5}$ ${RESET$5}bfi docs list`);
7111
7111
  console.log(` ${DIM$5}$ ${RESET$5}bfi docs info 42`);
@@ -7113,18 +7113,18 @@ function printDocsHelp() {
7113
7113
  async function handleUpload(args, globalOpts) {
7114
7114
  const filePath = args[0];
7115
7115
  if (!filePath) {
7116
- console.error("Usage: bfi docs upload <file>");
7117
- console.log("Upload a document file for processing.");
7116
+ console.error("用法:bfi docs upload <file>");
7117
+ console.log("上传文档文件进行解析。");
7118
7118
  process.exit(1);
7119
7119
  }
7120
7120
  const resolvedPath = path$1.resolve(filePath);
7121
7121
  if (!fs.existsSync(resolvedPath)) {
7122
- console.error(`File not found: ${resolvedPath}`);
7122
+ console.error(`文件未找到:${resolvedPath}`);
7123
7123
  process.exit(1);
7124
7124
  }
7125
7125
  const stats = fs.statSync(resolvedPath);
7126
7126
  if (!stats.isFile()) {
7127
- console.error(`Not a file: ${resolvedPath}`);
7127
+ console.error(`不是文件:${resolvedPath}`);
7128
7128
  process.exit(1);
7129
7129
  }
7130
7130
  const { registry, token } = resolveConfig(globalOpts);
@@ -7132,19 +7132,19 @@ async function handleUpload(args, globalOpts) {
7132
7132
  const fileName = path$1.basename(resolvedPath);
7133
7133
  const fileSize = stats.size;
7134
7134
  const fileSizeStr = fileSize < 1024 ? `${fileSize} B` : fileSize < 1024 * 1024 ? `${(fileSize / 1024).toFixed(1)} KB` : `${(fileSize / (1024 * 1024)).toFixed(1)} MB`;
7135
- console.log(`${DIM$5}Uploading ${fileName} (${fileSizeStr})...${RESET$5}`);
7135
+ console.log(`${DIM$5}正在上传 ${fileName} (${fileSizeStr})...${RESET$5}`);
7136
7136
  try {
7137
7137
  const fileBuffer = fs.readFileSync(resolvedPath);
7138
7138
  const result = await api.uploadDoc(fileBuffer, fileName);
7139
- console.log(`${TEXT$5}✓ Uploaded successfully${RESET$5}`);
7139
+ console.log(`${TEXT$5}✓ 上传成功${RESET$5}`);
7140
7140
  console.log();
7141
- if (result.id) console.log(` ${BOLD$3}ID:${RESET$5} ${TEXT$5}${result.id}${RESET$5}`);
7142
- if (result.status) console.log(` ${BOLD$3}Status:${RESET$5} ${TEXT$5}${result.status}${RESET$5}`);
7143
- if (result.fileName) console.log(` ${BOLD$3}File:${RESET$5} ${TEXT$5}${result.fileName}${RESET$5}`);
7141
+ if (result.id) console.log(` ${BOLD$3}ID:${RESET$5} ${TEXT$5}${result.id}${RESET$5}`);
7142
+ if (result.status) console.log(` ${BOLD$3}状态:${RESET$5} ${TEXT$5}${result.status}${RESET$5}`);
7143
+ if (result.fileName) console.log(` ${BOLD$3}文件:${RESET$5} ${TEXT$5}${result.fileName}${RESET$5}`);
7144
7144
  console.log();
7145
- if (result.id) console.log(`${DIM$5}Check status: bfi docs info ${result.id}${RESET$5}`);
7145
+ if (result.id) console.log(`${DIM$5}查看状态:bfi docs info ${result.id}${RESET$5}`);
7146
7146
  } catch (error) {
7147
- console.error(`Upload failed: ${error.message}`);
7147
+ console.error(`上传失败:${error.message}`);
7148
7148
  process.exit(1);
7149
7149
  }
7150
7150
  }
@@ -7157,11 +7157,11 @@ async function handleList$1(args, globalOpts) {
7157
7157
  const result = await api.listDocs(page, size);
7158
7158
  const docs = result.data || result.docs || result.content || [];
7159
7159
  if (!Array.isArray(docs) || docs.length === 0) {
7160
- console.log(`${DIM$5}No documents found.${RESET$5}`);
7160
+ console.log(`${DIM$5}未找到文档。${RESET$5}`);
7161
7161
  return;
7162
7162
  }
7163
7163
  console.log();
7164
- console.log(`${BOLD$3}Documents${RESET$5} (page ${page}, ${docs.length} results):`);
7164
+ console.log(`${BOLD$3}文档${RESET$5}(第 ${page} 页,共 ${docs.length} 条结果):`);
7165
7165
  console.log(`${DIM$5}${"─".repeat(64)}${RESET$5}`);
7166
7166
  for (const doc of docs) {
7167
7167
  const id = doc.id || "?";
@@ -7170,26 +7170,26 @@ async function handleList$1(args, globalOpts) {
7170
7170
  const createdAt = doc.createdAt || doc.created_at;
7171
7171
  const dateStr = createdAt ? new Date(createdAt).toISOString().split("T")[0] : "N/A";
7172
7172
  console.log(` ${BOLD$3}#${id}${RESET$5} ${TEXT$5}${fileName}${RESET$5}`);
7173
- console.log(` ${DIM$5}Status: ${status} | Date: ${dateStr}${RESET$5}`);
7173
+ console.log(` ${DIM$5}状态:${status} | 日期:${dateStr}${RESET$5}`);
7174
7174
  console.log();
7175
7175
  }
7176
7176
  const total = result.total || result.totalElements;
7177
- if (total && Number(total) > (page + 1) * size) console.log(`${DIM$5}Next page: bfi docs list ${page + 1}${RESET$5}`);
7177
+ if (total && Number(total) > (page + 1) * size) console.log(`${DIM$5}下一页:bfi docs list ${page + 1}${RESET$5}`);
7178
7178
  console.log();
7179
7179
  } catch (error) {
7180
- console.error(`Failed to list documents: ${error.message}`);
7180
+ console.error(`列出文档失败:${error.message}`);
7181
7181
  process.exit(1);
7182
7182
  }
7183
7183
  }
7184
7184
  async function handleInfo$1(args, globalOpts) {
7185
7185
  const docId = args[0];
7186
7186
  if (!docId) {
7187
- console.error("Usage: bfi docs info <id>");
7187
+ console.error("用法:bfi docs info <id>");
7188
7188
  process.exit(1);
7189
7189
  }
7190
7190
  const id = parseInt(docId, 10);
7191
7191
  if (isNaN(id)) {
7192
- console.error(`Invalid document ID: ${docId}`);
7192
+ console.error(`无效的文档 ID:${docId}`);
7193
7193
  process.exit(1);
7194
7194
  }
7195
7195
  const { registry, token } = resolveConfig(globalOpts);
@@ -7198,40 +7198,40 @@ async function handleInfo$1(args, globalOpts) {
7198
7198
  const result = await api.getDoc(id);
7199
7199
  const doc = result.data || result;
7200
7200
  if (!doc || !doc.id) {
7201
- console.log(`${DIM$5}Document not found: ${id}${RESET$5}`);
7201
+ console.log(`${DIM$5}未找到文档:${id}${RESET$5}`);
7202
7202
  process.exit(1);
7203
7203
  }
7204
7204
  console.log();
7205
- console.log(`${BOLD$3}Document #${doc.id}${RESET$5}`);
7205
+ console.log(`${BOLD$3}文档 #${doc.id}${RESET$5}`);
7206
7206
  console.log(`${DIM$5}${"─".repeat(48)}${RESET$5}`);
7207
- if (doc.fileName || doc.file_name) console.log(` ${BOLD$3}File:${RESET$5} ${TEXT$5}${doc.fileName || doc.file_name}${RESET$5}`);
7207
+ if (doc.fileName || doc.file_name) console.log(` ${BOLD$3}文件:${RESET$5} ${TEXT$5}${doc.fileName || doc.file_name}${RESET$5}`);
7208
7208
  if (doc.status) {
7209
7209
  const statusColor = doc.status === "completed" || doc.status === "COMPLETED" ? "\x1B[32m" : doc.status === "failed" || doc.status === "FAILED" ? "\x1B[31m" : TEXT$5;
7210
- console.log(` ${BOLD$3}Status:${RESET$5} ${statusColor}${doc.status}${RESET$5}`);
7210
+ console.log(` ${BOLD$3}状态:${RESET$5} ${statusColor}${doc.status}${RESET$5}`);
7211
7211
  }
7212
7212
  if (doc.createdAt || doc.created_at) {
7213
7213
  const date = new Date(doc.createdAt || doc.created_at).toISOString().replace("T", " ").slice(0, 19);
7214
- console.log(` ${BOLD$3}Created:${RESET$5} ${TEXT$5}${date}${RESET$5}`);
7214
+ console.log(` ${BOLD$3}创建时间:${RESET$5} ${TEXT$5}${date}${RESET$5}`);
7215
7215
  }
7216
7216
  if (doc.updatedAt || doc.updated_at) {
7217
7217
  const date = new Date(doc.updatedAt || doc.updated_at).toISOString().replace("T", " ").slice(0, 19);
7218
- console.log(` ${BOLD$3}Updated:${RESET$5} ${TEXT$5}${date}${RESET$5}`);
7218
+ console.log(` ${BOLD$3}更新时间:${RESET$5} ${TEXT$5}${date}${RESET$5}`);
7219
7219
  }
7220
7220
  if (doc.result) {
7221
7221
  console.log();
7222
- console.log(` ${BOLD$3}Result:${RESET$5}`);
7222
+ console.log(` ${BOLD$3}结果:${RESET$5}`);
7223
7223
  const resultStr = typeof doc.result === "string" ? doc.result : JSON.stringify(doc.result, null, 4);
7224
7224
  for (const line of resultStr.split("\n")) console.log(` ${DIM$5}${line}${RESET$5}`);
7225
7225
  }
7226
7226
  if (doc.error || doc.errorMessage) {
7227
7227
  console.log();
7228
- console.log(` \x1b[31m${BOLD$3}Error:${RESET$5}`);
7228
+ console.log(` \x1b[31m${BOLD$3}错误:${RESET$5}`);
7229
7229
  console.log(` \x1b[31m${doc.error || doc.errorMessage}${RESET$5}`);
7230
7230
  }
7231
7231
  console.log();
7232
7232
  } catch (error) {
7233
- if (error.status === 404) console.error(`Document not found: ${id}`);
7234
- else console.error(`Failed to fetch document info: ${error.message}`);
7233
+ if (error.status === 404) console.error(`未找到文档:${id}`);
7234
+ else console.error(`获取文档信息失败:${error.message}`);
7235
7235
  process.exit(1);
7236
7236
  }
7237
7237
  }
@@ -7272,53 +7272,53 @@ async function runPublish(args, globalOpts) {
7272
7272
  await publishFromGit(positionalArgs, api, namespace, visibility, yes, branch, directory, skillFilter);
7273
7273
  break;
7274
7274
  default:
7275
- console.error(`Unknown publish mode: ${mode}`);
7276
- console.log("Valid modes: dir, zip, git");
7277
- console.log("Usage: bfi publish [source] --from dir|zip|git [options]");
7275
+ console.error(`未知发布模式:${mode}`);
7276
+ console.log("可用模式:dir, zip, git");
7277
+ console.log("用法:bfi publish [source] --from dir|zip|git [options]");
7278
7278
  process.exit(1);
7279
7279
  }
7280
7280
  }
7281
7281
  async function publishFromDir(positionalArgs, api, namespace, visibility) {
7282
7282
  const dirPath = positionalArgs[0];
7283
7283
  if (!dirPath) {
7284
- console.error("Usage: bfi publish <directory> --from dir");
7285
- console.log("Publish a skill from a local directory containing SKILL.md.");
7284
+ console.error("用法:bfi publish <directory> --from dir");
7285
+ console.log("从包含 SKILL.md 的本地目录发布技能。");
7286
7286
  process.exit(1);
7287
7287
  }
7288
7288
  const resolvedDir = path$1.resolve(dirPath);
7289
7289
  if (!fs.existsSync(resolvedDir)) {
7290
- console.error(`Directory not found: ${resolvedDir}`);
7290
+ console.error(`目录未找到:${resolvedDir}`);
7291
7291
  process.exit(1);
7292
7292
  }
7293
7293
  if (!fs.statSync(resolvedDir).isDirectory()) {
7294
- console.error(`Not a directory: ${resolvedDir}`);
7294
+ console.error(`不是目录:${resolvedDir}`);
7295
7295
  process.exit(1);
7296
7296
  }
7297
7297
  const skillMdPath = path$1.join(resolvedDir, "SKILL.md");
7298
7298
  if (!fs.existsSync(skillMdPath)) {
7299
- console.error(`SKILL.md not found in ${resolvedDir}`);
7300
- console.log("A SKILL.md file with frontmatter (name, description) is required.");
7299
+ console.error(`在 ${resolvedDir} 中未找到 SKILL.md`);
7300
+ console.log("需要包含 frontmatter(name, description)的 SKILL.md 文件。");
7301
7301
  process.exit(1);
7302
7302
  }
7303
7303
  const { data: frontmatter } = parseFrontmatter(fs.readFileSync(skillMdPath, "utf-8"));
7304
7304
  const skillName = frontmatter.name || path$1.basename(resolvedDir);
7305
- console.log(`${DIM$4}Publishing skill from directory...${RESET$4}`);
7306
- console.log(` ${BOLD$2}Name:${RESET$4} ${TEXT$4}${skillName}${RESET$4}`);
7307
- console.log(` ${BOLD$2}Namespace:${RESET$4} ${TEXT$4}${namespace}${RESET$4}`);
7308
- console.log(` ${BOLD$2}Visibility:${RESET$4} ${TEXT$4}${visibility}${RESET$4}`);
7309
- console.log(` ${BOLD$2}Directory:${RESET$4} ${TEXT$4}${resolvedDir}${RESET$4}`);
7305
+ console.log(`${DIM$4}正在从目录发布技能...${RESET$4}`);
7306
+ console.log(` ${BOLD$2}名称:${RESET$4} ${TEXT$4}${skillName}${RESET$4}`);
7307
+ console.log(` ${BOLD$2}命名空间:${RESET$4} ${TEXT$4}${namespace}${RESET$4}`);
7308
+ console.log(` ${BOLD$2}可见性:${RESET$4} ${TEXT$4}${visibility}${RESET$4}`);
7309
+ console.log(` ${BOLD$2}目录:${RESET$4} ${TEXT$4}${resolvedDir}${RESET$4}`);
7310
7310
  console.log();
7311
- console.log(`${DIM$4}Creating zip...${RESET$4}`);
7311
+ console.log(`${DIM$4}正在创建 zip...${RESET$4}`);
7312
7312
  const zipBuffer = createZipFromDir(resolvedDir);
7313
- console.log(` ${GREEN$3}Zip created (${formatSize(zipBuffer.length)})${RESET$4}`);
7314
- console.log(`${DIM$4}Uploading to SkillHub...${RESET$4}`);
7313
+ console.log(` ${GREEN$3}Zip 已创建 (${formatSize(zipBuffer.length)})${RESET$4}`);
7314
+ console.log(`${DIM$4}正在上传到 SkillHub...${RESET$4}`);
7315
7315
  try {
7316
7316
  const res = await api.publishSkill(namespace, zipBuffer, visibility);
7317
- console.log(` ${GREEN$3}Published successfully!${RESET$4}`);
7318
- if (res.slug) console.log(` ${BOLD$2}Slug:${RESET$4} ${TEXT$4}${res.slug}${RESET$4}`);
7319
- if (res.url) console.log(` ${BOLD$2}URL:${RESET$4} ${TEXT$4}${res.url}${RESET$4}`);
7317
+ console.log(` ${GREEN$3}发布成功!${RESET$4}`);
7318
+ if (res.slug) console.log(` ${BOLD$2}Slug:${RESET$4} ${TEXT$4}${res.slug}${RESET$4}`);
7319
+ if (res.url) console.log(` ${BOLD$2}URL:${RESET$4} ${TEXT$4}${res.url}${RESET$4}`);
7320
7320
  } catch (error) {
7321
- console.error(` ${RED$1}Publish failed: ${error.message}${RESET$4}`);
7321
+ console.error(` ${RED$1}发布失败:${error.message}${RESET$4}`);
7322
7322
  process.exit(1);
7323
7323
  }
7324
7324
  console.log();
@@ -7326,43 +7326,43 @@ async function publishFromDir(positionalArgs, api, namespace, visibility) {
7326
7326
  async function publishFromZip(positionalArgs, api, namespace, visibility) {
7327
7327
  const zipPath = positionalArgs[0];
7328
7328
  if (!zipPath) {
7329
- console.error("Usage: bfi publish <file.zip> --from zip");
7330
- console.log("Publish a skill from a zip file containing SKILL.md.");
7329
+ console.error("用法:bfi publish <file.zip> --from zip");
7330
+ console.log("从包含 SKILL.md 的 zip 文件发布技能。");
7331
7331
  process.exit(1);
7332
7332
  }
7333
7333
  const resolvedZip = path$1.resolve(zipPath);
7334
7334
  if (!fs.existsSync(resolvedZip)) {
7335
- console.error(`File not found: ${resolvedZip}`);
7335
+ console.error(`文件未找到:${resolvedZip}`);
7336
7336
  process.exit(1);
7337
7337
  }
7338
- console.log(`${DIM$4}Extracting zip...${RESET$4}`);
7338
+ console.log(`${DIM$4}正在解压 zip...${RESET$4}`);
7339
7339
  const tmpDir = path$1.join(os$1.tmpdir(), `.bfi-publish-${Date.now()}`);
7340
7340
  fs.mkdirSync(tmpDir, { recursive: true });
7341
7341
  try {
7342
7342
  await extractZip(resolvedZip, tmpDir);
7343
7343
  const skillMdPath = findSkillMd(tmpDir);
7344
7344
  if (!skillMdPath) {
7345
- console.error(` ${RED$1}SKILL.md not found in zip file${RESET$4}`);
7345
+ console.error(` ${RED$1}zip 文件中未找到 SKILL.md${RESET$4}`);
7346
7346
  process.exit(1);
7347
7347
  }
7348
7348
  const skillDir = path$1.dirname(skillMdPath);
7349
- console.log(` ${GREEN$3}Found SKILL.md in ${path$1.relative(tmpDir, skillDir) || "."}${RESET$4}`);
7349
+ console.log(` ${GREEN$3}在 ${path$1.relative(tmpDir, skillDir) || "."} 中找到 SKILL.md${RESET$4}`);
7350
7350
  const { data: frontmatter } = parseFrontmatter(fs.readFileSync(skillMdPath, "utf-8"));
7351
7351
  const skillName = frontmatter.name || path$1.basename(skillDir);
7352
- console.log(` ${BOLD$2}Name:${RESET$4} ${TEXT$4}${skillName}${RESET$4}`);
7353
- console.log(` ${BOLD$2}Namespace:${RESET$4} ${TEXT$4}${namespace}${RESET$4}`);
7354
- console.log(` ${BOLD$2}Visibility:${RESET$4} ${TEXT$4}${visibility}${RESET$4}`);
7352
+ console.log(` ${BOLD$2}名称:${RESET$4} ${TEXT$4}${skillName}${RESET$4}`);
7353
+ console.log(` ${BOLD$2}命名空间:${RESET$4} ${TEXT$4}${namespace}${RESET$4}`);
7354
+ console.log(` ${BOLD$2}可见性:${RESET$4} ${TEXT$4}${visibility}${RESET$4}`);
7355
7355
  console.log();
7356
- console.log(`${DIM$4}Re-zipping skill...${RESET$4}`);
7356
+ console.log(`${DIM$4}正在重新打包...${RESET$4}`);
7357
7357
  const zipBuffer = createZipFromDir(skillDir);
7358
- console.log(` ${GREEN$3}Zip created (${formatSize(zipBuffer.length)})${RESET$4}`);
7359
- console.log(`${DIM$4}Uploading to SkillHub...${RESET$4}`);
7358
+ console.log(` ${GREEN$3}Zip 已创建 (${formatSize(zipBuffer.length)})${RESET$4}`);
7359
+ console.log(`${DIM$4}正在上传到 SkillHub...${RESET$4}`);
7360
7360
  const res = await api.publishSkill(namespace, zipBuffer, visibility);
7361
- console.log(` ${GREEN$3}Published successfully!${RESET$4}`);
7362
- if (res.slug) console.log(` ${BOLD$2}Slug:${RESET$4} ${TEXT$4}${res.slug}${RESET$4}`);
7363
- if (res.url) console.log(` ${BOLD$2}URL:${RESET$4} ${TEXT$4}${res.url}${RESET$4}`);
7361
+ console.log(` ${GREEN$3}发布成功!${RESET$4}`);
7362
+ if (res.slug) console.log(` ${BOLD$2}Slug:${RESET$4} ${TEXT$4}${res.slug}${RESET$4}`);
7363
+ if (res.url) console.log(` ${BOLD$2}URL:${RESET$4} ${TEXT$4}${res.url}${RESET$4}`);
7364
7364
  } catch (error) {
7365
- if (error.message && !error.message.includes("Publish failed")) console.error(` ${RED$1}Error: ${error.message}${RESET$4}`);
7365
+ if (error.message && !error.message.includes("Publish failed")) console.error(` ${RED$1}错误:${error.message}${RESET$4}`);
7366
7366
  process.exit(1);
7367
7367
  } finally {
7368
7368
  try {
@@ -7377,10 +7377,10 @@ async function publishFromZip(positionalArgs, api, namespace, visibility) {
7377
7377
  async function publishFromGit(positionalArgs, api, namespace, visibility, yes, branch, directory, skillFilter) {
7378
7378
  const repoArg = positionalArgs[0];
7379
7379
  if (!repoArg) {
7380
- console.error("Usage: bfi publish <repo-url> --from git [options]");
7381
- console.log("Publish skills from a Git repository using server-side discovery.");
7380
+ console.error("用法:bfi publish <repo-url> --from git [options]");
7381
+ console.log("使用服务端发现从 Git 仓库发布技能。");
7382
7382
  console.log();
7383
- console.log("Examples:");
7383
+ console.log("示例:");
7384
7384
  console.log(` ${DIM$4}$ ${RESET$4}bfi publish https://github.com/user/repo --from git`);
7385
7385
  console.log(` ${DIM$4}$ ${RESET$4}bfi publish user/repo --from git --branch main`);
7386
7386
  process.exit(1);
@@ -7393,40 +7393,40 @@ async function publishFromGit(positionalArgs, api, namespace, visibility, yes, b
7393
7393
  }
7394
7394
  const effectiveBranch = branch || "main";
7395
7395
  const effectiveDir = directory || null;
7396
- console.log(`${DIM$4}Discovering skills from Git repository...${RESET$4}`);
7397
- console.log(` ${BOLD$2}Repository:${RESET$4} ${TEXT$4}${repoUrl}${RESET$4}`);
7398
- console.log(` ${BOLD$2}Branch:${RESET$4} ${TEXT$4}${effectiveBranch}${RESET$4}`);
7399
- if (effectiveDir) console.log(` ${BOLD$2}Directory:${RESET$4} ${TEXT$4}${effectiveDir}${RESET$4}`);
7396
+ console.log(`${DIM$4}正在从 Git 仓库发现技能...${RESET$4}`);
7397
+ console.log(` ${BOLD$2}仓库:${RESET$4} ${TEXT$4}${repoUrl}${RESET$4}`);
7398
+ console.log(` ${BOLD$2}分支:${RESET$4} ${TEXT$4}${effectiveBranch}${RESET$4}`);
7399
+ if (effectiveDir) console.log(` ${BOLD$2}目录:${RESET$4} ${TEXT$4}${effectiveDir}${RESET$4}`);
7400
7400
  console.log();
7401
7401
  let parseResult;
7402
7402
  try {
7403
7403
  parseResult = await api.gitParse(repoUrl, effectiveBranch, effectiveDir);
7404
7404
  } catch (error) {
7405
- console.error(` ${RED$1}Git parse failed: ${error.message}${RESET$4}`);
7405
+ console.error(` ${RED$1}Git 解析失败:${error.message}${RESET$4}`);
7406
7406
  process.exit(1);
7407
7407
  }
7408
7408
  const sessionId = parseResult.sessionId;
7409
7409
  const discoveredSkills = parseResult.skills || [];
7410
7410
  const precheck = parseResult.precheck;
7411
7411
  if (!sessionId || discoveredSkills.length === 0) {
7412
- console.log(`${YELLOW$1}No skills discovered in the repository.${RESET$4}`);
7412
+ console.log(`${YELLOW$1}仓库中未发现技能。${RESET$4}`);
7413
7413
  if (precheck && (precheck.errors || precheck.warnings)) {
7414
7414
  console.log();
7415
- console.log(`${BOLD$2}Precheck results:${RESET$4}`);
7415
+ console.log(`${BOLD$2}预检结果:${RESET$4}`);
7416
7416
  const errors = precheck.errors;
7417
7417
  const warnings = precheck.warnings;
7418
7418
  if (errors && errors.length > 0) {
7419
- console.log(` ${RED$1}Errors:${RESET$4}`);
7419
+ console.log(` ${RED$1}错误:${RESET$4}`);
7420
7420
  for (const e of errors) console.log(` ${RED$1}- ${e}${RESET$4}`);
7421
7421
  }
7422
7422
  if (warnings && warnings.length > 0) {
7423
- console.log(` ${YELLOW$1}Warnings:${RESET$4}`);
7423
+ console.log(` ${YELLOW$1}警告:${RESET$4}`);
7424
7424
  for (const w of warnings) console.log(` ${YELLOW$1}- ${w}${RESET$4}`);
7425
7425
  }
7426
7426
  }
7427
7427
  process.exit(1);
7428
7428
  }
7429
- console.log(`${BOLD$2}Discovered ${discoveredSkills.length} skill(s):${RESET$4}`);
7429
+ console.log(`${BOLD$2}发现 ${discoveredSkills.length} 个技能:${RESET$4}`);
7430
7430
  console.log();
7431
7431
  let selectedSkills = discoveredSkills;
7432
7432
  if (skillFilter) {
@@ -7437,7 +7437,7 @@ async function publishFromGit(positionalArgs, api, namespace, visibility, yes, b
7437
7437
  return filters.some((f) => slug.includes(f) || name.includes(f));
7438
7438
  });
7439
7439
  if (selectedSkills.length === 0) {
7440
- console.log(`${YELLOW$1}No skills match filter: ${skillFilter}${RESET$4}`);
7440
+ console.log(`${YELLOW$1}没有技能匹配筛选条件:${skillFilter}${RESET$4}`);
7441
7441
  console.log("Available skills:");
7442
7442
  for (const s of discoveredSkills) console.log(` - ${s.slug || s.name}`);
7443
7443
  process.exit(1);
@@ -7460,8 +7460,8 @@ async function publishFromGit(positionalArgs, api, namespace, visibility, yes, b
7460
7460
  if (skillPrecheck) {
7461
7461
  const errors = skillPrecheck.errors;
7462
7462
  const warnings = skillPrecheck.warnings;
7463
- if (errors && errors.length > 0) for (const e of errors) console.log(` ${RED$1}Error: ${e}${RESET$4}`);
7464
- if (warnings && warnings.length > 0) for (const w of warnings) console.log(` ${YELLOW$1}Warning: ${w}${RESET$4}`);
7463
+ if (errors && errors.length > 0) for (const e of errors) console.log(` ${RED$1}错误:${e}${RESET$4}`);
7464
+ if (warnings && warnings.length > 0) for (const w of warnings) console.log(` ${YELLOW$1}警告:${w}${RESET$4}`);
7465
7465
  }
7466
7466
  console.log();
7467
7467
  }
@@ -7474,21 +7474,21 @@ async function publishFromGit(positionalArgs, api, namespace, visibility, yes, b
7474
7474
  const selectedSlugs = skillFilter ? selectedSkills.map((s) => String(s.slug)) : null;
7475
7475
  if (!yes) {
7476
7476
  const count = selectedSlugs ? selectedSlugs.length : discoveredSkills.length;
7477
- console.log(`${DIM$4}Publishing ${count} skill(s) to @${namespace} (${visibility})${RESET$4}`);
7478
- console.log(`${DIM$4}Press Ctrl+C to cancel, or Enter to continue...${RESET$4}`);
7479
- await confirmPrompt("Proceed with publish?");
7477
+ console.log(`${DIM$4}正在将 ${count} 个技能发布到 @${namespace} (${visibility})${RESET$4}`);
7478
+ console.log(`${DIM$4}按 Ctrl+C 取消,或按 Enter 继续...${RESET$4}`);
7479
+ await confirmPrompt("确认发布?");
7480
7480
  }
7481
- console.log(`${DIM$4}Publishing to SkillHub...${RESET$4}`);
7481
+ console.log(`${DIM$4}正在发布到 SkillHub...${RESET$4}`);
7482
7482
  try {
7483
7483
  const res = await api.gitPublish(sessionId, namespace, visibility, selectedSlugs, confirmWarnings);
7484
- console.log(` ${GREEN$3}Published successfully!${RESET$4}`);
7484
+ console.log(` ${GREEN$3}发布成功!${RESET$4}`);
7485
7485
  const publishedSkills = res.skills || res.published;
7486
7486
  if (Array.isArray(publishedSkills)) for (const s of publishedSkills) {
7487
7487
  const ps = s;
7488
7488
  console.log(` ${GREEN$3}✓ ${ps.slug || ps.name}${RESET$4}`);
7489
7489
  }
7490
7490
  } catch (error) {
7491
- console.error(` ${RED$1}Publish failed: ${error.message}${RESET$4}`);
7491
+ console.error(` ${RED$1}发布失败:${error.message}${RESET$4}`);
7492
7492
  process.exit(1);
7493
7493
  }
7494
7494
  console.log();
@@ -7584,21 +7584,21 @@ async function runPackage(args, globalOpts) {
7584
7584
  }
7585
7585
  function printPackageHelp() {
7586
7586
  console.log();
7587
- console.log(`${BOLD$1}Package Commands:${RESET$3}`);
7588
- console.log(` ${DIM$3}bfi package list${RESET$3} List packages`);
7589
- console.log(` ${DIM$3}bfi package info <ref>${RESET$3} Show package details`);
7590
- console.log(` ${DIM$3}bfi package create <slug>${RESET$3} Create new package`);
7591
- console.log(` ${DIM$3}bfi package add <pkg> <skills>${RESET$3} Add skills to package`);
7592
- console.log(` ${DIM$3}bfi package remove <pkg> <skills>${RESET$3} Remove skills from package`);
7587
+ console.log(`${BOLD$1}包命令:${RESET$3}`);
7588
+ console.log(` ${DIM$3}bfi package list${RESET$3} 列出包`);
7589
+ console.log(` ${DIM$3}bfi package info <ref>${RESET$3} 查看包详情`);
7590
+ console.log(` ${DIM$3}bfi package create <slug>${RESET$3} 创建新包`);
7591
+ console.log(` ${DIM$3}bfi package add <pkg> <skills>${RESET$3} 添加技能到包`);
7592
+ console.log(` ${DIM$3}bfi package remove <pkg> <skills>${RESET$3} 从包移除技能`);
7593
7593
  console.log();
7594
- console.log(`${BOLD$1}Options:${RESET$3}`);
7595
- console.log(` --namespace <ns> Target namespace`);
7596
- console.log(` --name <name> Display name (for create)`);
7597
- console.log(` --description <text> Description (for create)`);
7598
- console.log(` --visibility <v> private or public (for create)`);
7599
- console.log(` --json Output as JSON`);
7594
+ console.log(`${BOLD$1}选项:${RESET$3}`);
7595
+ console.log(` --namespace <ns> 目标命名空间`);
7596
+ console.log(` --name <name> 显示名称(create 时)`);
7597
+ console.log(` --description <text> 描述(create 时)`);
7598
+ console.log(` --visibility <v> 私有或公开(create 时)`);
7599
+ console.log(` --json 以 JSON 输出`);
7600
7600
  console.log();
7601
- console.log(`${BOLD$1}Examples:${RESET$3}`);
7601
+ console.log(`${BOLD$1}示例:${RESET$3}`);
7602
7602
  console.log(` ${DIM$3}$ ${RESET$3}bfi package list --namespace myteam`);
7603
7603
  console.log(` ${DIM$3}$ ${RESET$3}bfi package info @myteam/my-package`);
7604
7604
  console.log(` ${DIM$3}$ ${RESET$3}bfi package create my-utils --namespace myteam`);
@@ -7621,7 +7621,7 @@ async function handleList(args, api, globalOpts) {
7621
7621
  return;
7622
7622
  }
7623
7623
  console.log();
7624
- console.log(`${BOLD$1}Packages in @${namespace}${RESET$3} (${packages.length}):`);
7624
+ console.log(`${BOLD$1}@${namespace} 中的包${RESET$3}(${packages.length} 个):`);
7625
7625
  console.log();
7626
7626
  packages.forEach((pkg, index) => {
7627
7627
  const visibility = pkg.visibility || "private";
@@ -7634,7 +7634,7 @@ async function handleList(args, api, globalOpts) {
7634
7634
  console.log();
7635
7635
  });
7636
7636
  } catch (error) {
7637
- console.error(`Failed to list packages: ${error.message}`);
7637
+ console.error(`列出包失败:${error.message}`);
7638
7638
  process.exit(1);
7639
7639
  }
7640
7640
  }
@@ -7660,26 +7660,26 @@ async function handleInfo(args, api, globalOpts) {
7660
7660
  console.log();
7661
7661
  console.log(`${BOLD$1}${pkg.name || slug}${RESET$3}`);
7662
7662
  console.log(`${DIM$3}${"=".repeat(48)}${RESET$3}`);
7663
- console.log(` ${BOLD$1}Slug:${RESET$3} ${TEXT$3}${toCanonicalSlug(namespace, slug)}${RESET$3}`);
7664
- console.log(` ${BOLD$1}Namespace:${RESET$3} ${TEXT$3}@${namespace}${RESET$3}`);
7665
- console.log(` ${BOLD$1}Visibility:${RESET$3} ${TEXT$3}${pkg.visibility || "private"}${RESET$3}`);
7666
- console.log(` ${BOLD$1}Description:${RESET$3} ${TEXT$3}${pkg.description || "N/A"}${RESET$3}`);
7663
+ console.log(` ${BOLD$1}Slug:${RESET$3} ${TEXT$3}${toCanonicalSlug(namespace, slug)}${RESET$3}`);
7664
+ console.log(` ${BOLD$1}命名空间:${RESET$3} ${TEXT$3}@${namespace}${RESET$3}`);
7665
+ console.log(` ${BOLD$1}可见性:${RESET$3} ${TEXT$3}${pkg.visibility || "private"}${RESET$3}`);
7666
+ console.log(` ${BOLD$1}描述:${RESET$3} ${TEXT$3}${pkg.description || "N/A"}${RESET$3}`);
7667
7667
  const skills = pkg.skills;
7668
7668
  if (skills && skills.length > 0) {
7669
7669
  console.log();
7670
- console.log(` ${BOLD$1}Skills (${skills.length}):${RESET$3}`);
7670
+ console.log(` ${BOLD$1}技能(${skills.length} 个):${RESET$3}`);
7671
7671
  for (const skill of skills) console.log(` ${DIM$3}- ${skill.slug}${skill.name ? ` (${skill.name})` : ""}${RESET$3}`);
7672
7672
  }
7673
7673
  console.log();
7674
7674
  } catch (error) {
7675
- console.error(`Failed to get package info: ${error.message}`);
7675
+ console.error(`获取包信息失败:${error.message}`);
7676
7676
  process.exit(1);
7677
7677
  }
7678
7678
  }
7679
7679
  async function handleCreate(args, api, globalOpts) {
7680
7680
  const slug = args[0];
7681
7681
  if (!slug) {
7682
- console.error("Usage: bfi package create <slug> [options]");
7682
+ console.error("用法:bfi package create <slug> [options]");
7683
7683
  process.exit(1);
7684
7684
  }
7685
7685
  const namespace = getOptionValue(args, "--namespace") || globalOpts.namespace || "global";
@@ -7693,14 +7693,14 @@ async function handleCreate(args, api, globalOpts) {
7693
7693
  description: description || "",
7694
7694
  visibility
7695
7695
  });
7696
- console.log(`${GREEN$2}✓ Created package ${toSkillRefString(namespace, slug)}${RESET$3}`);
7696
+ console.log(`${GREEN$2}✓ 已创建包 ${toSkillRefString(namespace, slug)}${RESET$3}`);
7697
7697
  const createdPkg = result.package;
7698
7698
  if (createdPkg) {
7699
- console.log(` ${BOLD$1}Name:${RESET$3} ${TEXT$3}${createdPkg.name || slug}${RESET$3}`);
7699
+ console.log(` ${BOLD$1}名称:${RESET$3} ${TEXT$3}${createdPkg.name || slug}${RESET$3}`);
7700
7700
  console.log(` ${BOLD$1}Visibility:${RESET$3} ${TEXT$3}${createdPkg.visibility || visibility}${RESET$3}`);
7701
7701
  }
7702
7702
  } catch (error) {
7703
- console.error(`Failed to create package: ${error.message}`);
7703
+ console.error(`创建包失败:${error.message}`);
7704
7704
  process.exit(1);
7705
7705
  }
7706
7706
  }
@@ -7708,7 +7708,7 @@ async function handleAdd(args, api, globalOpts) {
7708
7708
  const pkgRef = args[0];
7709
7709
  const skillRefs = args.slice(1);
7710
7710
  if (!pkgRef || skillRefs.length === 0) {
7711
- console.error("Usage: bfi package add <package-ref> <skill-ref...>");
7711
+ console.error("用法:bfi package add <package-ref> <skill-ref...>");
7712
7712
  process.exit(1);
7713
7713
  }
7714
7714
  const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
@@ -7721,10 +7721,10 @@ async function handleAdd(args, api, globalOpts) {
7721
7721
  });
7722
7722
  try {
7723
7723
  await api.addSkillsToPackage(namespace, slug, skills);
7724
- console.log(`${GREEN$2}✓ Added ${skills.length} skill(s) to ${toSkillRefString(namespace, slug)}${RESET$3}`);
7724
+ console.log(`${GREEN$2}✓ 已添加 ${skills.length} 个技能到 ${toSkillRefString(namespace, slug)}${RESET$3}`);
7725
7725
  for (const s of skills) console.log(` ${DIM$3}- ${toSkillRefString(s.namespace, s.slug)}${RESET$3}`);
7726
7726
  } catch (error) {
7727
- console.error(`Failed to add skills: ${error.message}`);
7727
+ console.error(`添加技能失败:${error.message}`);
7728
7728
  process.exit(1);
7729
7729
  }
7730
7730
  }
@@ -7732,7 +7732,7 @@ async function handleRemove(args, api, globalOpts) {
7732
7732
  const pkgRef = args[0];
7733
7733
  const skillRefs = args.slice(1);
7734
7734
  if (!pkgRef || skillRefs.length === 0) {
7735
- console.error("Usage: bfi package remove <package-ref> <skill-ref...>");
7735
+ console.error("用法:bfi package remove <package-ref> <skill-ref...>");
7736
7736
  process.exit(1);
7737
7737
  }
7738
7738
  const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
@@ -7745,10 +7745,10 @@ async function handleRemove(args, api, globalOpts) {
7745
7745
  });
7746
7746
  try {
7747
7747
  await api.removeSkillsFromPackage(namespace, slug, skills);
7748
- console.log(`${GREEN$2}✓ Removed ${skills.length} skill(s) from ${toSkillRefString(namespace, slug)}${RESET$3}`);
7748
+ console.log(`${GREEN$2}✓ 已从 ${toSkillRefString(namespace, slug)} 移除 ${skills.length} 个技能${RESET$3}`);
7749
7749
  for (const s of skills) console.log(` ${DIM$3}- ${toSkillRefString(s.namespace, s.slug)}${RESET$3}`);
7750
7750
  } catch (error) {
7751
- console.error(`Failed to remove skills: ${error.message}`);
7751
+ console.error(`移除技能失败:${error.message}`);
7752
7752
  process.exit(1);
7753
7753
  }
7754
7754
  }
@@ -7764,11 +7764,11 @@ const RED = "\x1B[31m";
7764
7764
  async function runLog(args, globalOpts) {
7765
7765
  const skillRef = args[0];
7766
7766
  if (!skillRef) {
7767
- console.log("Usage: bfi log <skill-ref> [summary]");
7767
+ console.log("用法:bfi log <skill-ref> [summary]");
7768
7768
  console.log();
7769
- console.log("Log skill usage to SkillHub for tracking and analytics.");
7769
+ console.log("记录技能使用到 SkillHub 用于追踪和分析。");
7770
7770
  console.log();
7771
- console.log("Examples:");
7771
+ console.log("示例:");
7772
7772
  console.log(` ${DIM$2}$ ${RESET$2}bfi log @myteam/my-skill`);
7773
7773
  console.log(` ${DIM$2}$ ${RESET$2}bfi log my-skill "Used for code review"`);
7774
7774
  process.exit(1);
@@ -7778,10 +7778,10 @@ async function runLog(args, globalOpts) {
7778
7778
  const api = new SkillHubAPI(registry, token);
7779
7779
  try {
7780
7780
  const result = await api.logSkillUsage(skillRef, summary);
7781
- console.log(`${GREEN$1}✓ Logged usage for ${TEXT$2}${skillRef}${RESET$2}`);
7781
+ console.log(`${GREEN$1}✓ 已记录使用 ${TEXT$2}${skillRef}${RESET$2}`);
7782
7782
  if (result.message) console.log(` ${DIM$2}${result.message}${RESET$2}`);
7783
7783
  } catch (error) {
7784
- console.error(`${RED}Failed to log skill usage: ${error.message}${RESET$2}`);
7784
+ console.error(`${RED}记录技能使用失败:${error.message}${RESET$2}`);
7785
7785
  process.exit(1);
7786
7786
  }
7787
7787
  }
@@ -7796,14 +7796,14 @@ async function runInstall(args, globalOpts) {
7796
7796
  const skillEntries = Object.entries(lock.skills);
7797
7797
  const packageEntries = Object.entries(lock.packages);
7798
7798
  if (skillEntries.length === 0 && packageEntries.length === 0) {
7799
- console.log(`${DIM$1}No skills or packages found in lockfile (.bfi/lock.json).${RESET$1}`);
7800
- console.log(`${DIM$1}Run 'bfi skills add <source>' to install skills first.${RESET$1}`);
7799
+ console.log(`${DIM$1}锁文件 (.bfi/lock.json) 中未找到技能或包。${RESET$1}`);
7800
+ console.log(`${DIM$1}请先运行 'bfi skills add <source>' 安装技能。${RESET$1}`);
7801
7801
  return;
7802
7802
  }
7803
7803
  console.log();
7804
- console.log(`${DIM$1}Restoring from lockfile...${RESET$1}`);
7805
- console.log(` Skills: ${skillEntries.length}`);
7806
- console.log(` Packages: ${packageEntries.length}`);
7804
+ console.log(`${DIM$1}正在从锁文件恢复...${RESET$1}`);
7805
+ console.log(` 技能:${skillEntries.length}`);
7806
+ console.log(` 包:${packageEntries.length}`);
7807
7807
  console.log();
7808
7808
  let installedCount = 0;
7809
7809
  let failedCount = 0;
@@ -7818,35 +7818,35 @@ async function runInstall(args, globalOpts) {
7818
7818
  if (sourceType === "skillhub" || namespace !== "global") installSource = `@${namespace}/${slug}`;
7819
7819
  else if (source) installSource = source;
7820
7820
  else {
7821
- console.log(` ${YELLOW}Skipping ${skillName}: unknown source type${RESET$1}`);
7821
+ console.log(` ${YELLOW}跳过 ${skillName}:未知源类型${RESET$1}`);
7822
7822
  continue;
7823
7823
  }
7824
- console.log(` ${TEXT$1}Installing ${skillName} from ${installSource}...${RESET$1}`);
7824
+ console.log(` ${TEXT$1}正在从 ${installSource} 安装 ${skillName}...${RESET$1}`);
7825
7825
  try {
7826
7826
  await runAdd([installSource], { yes });
7827
7827
  installedCount++;
7828
7828
  console.log(` ${GREEN}✓ ${skillName}${RESET$1}`);
7829
7829
  } catch (error) {
7830
7830
  failedCount++;
7831
- console.error(` ${YELLOW}Failed: ${error.message}${RESET$1}`);
7831
+ console.error(` ${YELLOW}失败:${error.message}${RESET$1}`);
7832
7832
  }
7833
7833
  }
7834
7834
  for (const [pkgRef, entry] of packageEntries) {
7835
7835
  const pkgEntry = entry;
7836
7836
  const installSource = `@${String(pkgEntry.namespace || "global")}/${String(pkgEntry.slug || pkgRef)}`;
7837
- console.log(` ${TEXT$1}Installing package ${pkgRef} from ${installSource}...${RESET$1}`);
7837
+ console.log(` ${TEXT$1}正在从 ${installSource} 安装包 ${pkgRef}...${RESET$1}`);
7838
7838
  try {
7839
7839
  await runAdd([installSource], { yes });
7840
7840
  installedCount++;
7841
7841
  console.log(` ${GREEN}✓ ${pkgRef}${RESET$1}`);
7842
7842
  } catch (error) {
7843
7843
  failedCount++;
7844
- console.error(` ${YELLOW}Failed: ${error.message}${RESET$1}`);
7844
+ console.error(` ${YELLOW}失败:${error.message}${RESET$1}`);
7845
7845
  }
7846
7846
  }
7847
7847
  console.log();
7848
- if (installedCount > 0) console.log(`${GREEN}✓ Restored ${installedCount} item(s)${RESET$1}`);
7849
- if (failedCount > 0) console.log(`${YELLOW}⚠ ${failedCount} item(s) failed to restore${RESET$1}`);
7848
+ if (installedCount > 0) console.log(`${GREEN}✓ 已恢复 ${installedCount} 项${RESET$1}`);
7849
+ if (failedCount > 0) console.log(`${YELLOW}⚠ ${failedCount} 项恢复失败${RESET$1}`);
7850
7850
  console.log();
7851
7851
  }
7852
7852
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -7897,8 +7897,8 @@ function showBanner() {
7897
7897
  console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills search ${DIM}[query]${RESET}`);
7898
7898
  console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills update${RESET}`);
7899
7899
  console.log();
7900
- console.log(`Discover more skills at ${TEXT}https://skills.sh/${RESET}`);
7901
- console.log(`and at ${TEXT}https://skillhub.skillhub.woa.com/${RESET}`);
7900
+ console.log(`发现更多技能:${TEXT}https://skills.sh/${RESET}`);
7901
+ console.log(`以及 ${TEXT}https://skillhub.skillhub.woa.com/${RESET}`);
7902
7902
  console.log();
7903
7903
  }
7904
7904
  function showHelp() {
@@ -7978,21 +7978,21 @@ function showRemoveHelp() {
7978
7978
  console.log(`
7979
7979
  ${BOLD}Usage:${RESET} bfi skills remove [skills...] [options]
7980
7980
 
7981
- ${BOLD}Description:${RESET}
7981
+ ${BOLD}说明:${RESET}
7982
7982
  Remove installed skills from agents. If no skill names are provided,
7983
7983
  an interactive selection menu will be shown.
7984
7984
 
7985
- ${BOLD}Arguments:${RESET}
7985
+ ${BOLD}参数:${RESET}
7986
7986
  skills Optional skill names to remove (space-separated)
7987
7987
 
7988
- ${BOLD}Options:${RESET}
7988
+ ${BOLD}选项:${RESET}
7989
7989
  -g, --global Remove from global scope (~/) instead of project scope
7990
7990
  -a, --agent Remove from specific agents (use '*' for all agents)
7991
7991
  -s, --skill Specify skills to remove (use '*' for all skills)
7992
7992
  -y, --yes Skip confirmation prompts
7993
7993
  --all Shorthand for --skill '*' --agent '*' -y
7994
7994
 
7995
- ${BOLD}Examples:${RESET}
7995
+ ${BOLD}示例:${RESET}
7996
7996
  ${DIM}$${RESET} bfi skills remove ${DIM}# interactive selection${RESET}
7997
7997
  ${DIM}$${RESET} bfi skills remove my-skill ${DIM}# remove specific skill${RESET}
7998
7998
  ${DIM}$${RESET} bfi skills remove skill1 skill2 -y ${DIM}# remove multiple skills${RESET}
@@ -8013,7 +8013,7 @@ function runInit(args) {
8013
8013
  const skillFile = join(skillDir, "SKILL.md");
8014
8014
  const displayPath = hasName ? `${skillName}/SKILL.md` : "SKILL.md";
8015
8015
  if (existsSync(skillFile)) {
8016
- console.log(`${TEXT}Skill already exists at ${DIM}${displayPath}${RESET}`);
8016
+ console.log(`${TEXT}技能已存在:${DIM}${displayPath}${RESET}`);
8017
8017
  return;
8018
8018
  }
8019
8019
  if (hasName) mkdirSync(skillDir, { recursive: true });
@@ -8036,16 +8036,16 @@ Describe when this skill should be used.
8036
8036
  2. Second step
8037
8037
  3. Additional steps as needed
8038
8038
  `);
8039
- console.log(`${TEXT}Initialized skill: ${DIM}${skillName}${RESET}`);
8039
+ console.log(`${TEXT}已初始化技能:${DIM}${skillName}${RESET}`);
8040
8040
  console.log();
8041
- console.log(`${DIM}Created:${RESET}`);
8041
+ console.log(`${DIM}已创建:${RESET}`);
8042
8042
  console.log(` ${displayPath}`);
8043
8043
  console.log();
8044
- console.log(`${DIM}Next steps:${RESET}`);
8044
+ console.log(`${DIM}下一步:${RESET}`);
8045
8045
  console.log(` 1. Edit ${TEXT}${displayPath}${RESET} to define your skill instructions`);
8046
8046
  console.log(` 2. Update the ${TEXT}name${RESET} and ${TEXT}description${RESET} in the frontmatter`);
8047
8047
  console.log();
8048
- console.log(`${DIM}Publishing:${RESET}`);
8048
+ console.log(`${DIM}发布方式:${RESET}`);
8049
8049
  console.log(` ${DIM}GitHub:${RESET} Push to a repo, then ${TEXT}npx bfi skills add <owner>/<repo>${RESET}`);
8050
8050
  console.log(` ${DIM}URL:${RESET} Host the file, then ${TEXT}npx bfi skills add https://example.com/${displayPath}${RESET}`);
8051
8051
  console.log();
@@ -8174,10 +8174,10 @@ async function dispatchSkillSubcommand(args, globalOpts) {
8174
8174
  console.log(`${BOLD}Docs:${RESET}`);
8175
8175
  console.log(` docs <cmd> Document management`);
8176
8176
  console.log();
8177
- console.log(`Run ${BOLD}bfi --help${RESET} for more details.`);
8177
+ console.log(`运行 ${BOLD}bfi --help${RESET} 查看更多详情。`);
8178
8178
  } else {
8179
- console.log(`Unknown skills command: ${sub}`);
8180
- console.log(`Run ${BOLD}bfi skills --help${RESET} for usage.`);
8179
+ console.log(`未知技能命令:${sub}`);
8180
+ console.log(`运行 ${BOLD}bfi skills --help${RESET} 查看用法。`);
8181
8181
  }
8182
8182
  }
8183
8183
  }
@@ -8308,8 +8308,8 @@ async function main() {
8308
8308
  console.log(VERSION);
8309
8309
  break;
8310
8310
  default:
8311
- console.log(`Unknown command: ${command}`);
8312
- console.log(`Run ${BOLD}bfi --help${RESET} for usage.`);
8311
+ console.log(`未知命令:${command}`);
8312
+ console.log(`运行 ${BOLD}bfi --help${RESET} 查看用法。`);
8313
8313
  }
8314
8314
  }
8315
8315
  main().finally(() => process.exit(process.exitCode ?? 0));