ali-skills 0.0.31 → 0.0.33

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.
@@ -440,8 +440,22 @@ function getGitUserConfig() {
440
440
  return null;
441
441
  }
442
442
  }
443
+ function getBucUser() {
444
+ try {
445
+ const authFile = join(homedir(), ".ali-skills", "auth.json");
446
+ if (!existsSync(authFile)) return null;
447
+ const auth = JSON.parse(readFileSync(authFile, "utf-8"));
448
+ if (!auth.account) return null;
449
+ return {
450
+ username: auth.name || auth.account,
451
+ email: auth.email || `${auth.account}@alibaba-inc.com`
452
+ };
453
+ } catch {
454
+ return null;
455
+ }
456
+ }
443
457
  function getCurrentUser() {
444
- return getGitUserConfig();
458
+ return getBucUser() ?? getGitUserConfig();
445
459
  }
446
460
  var GitCloneError = class extends Error {
447
461
  url;
@@ -1888,6 +1902,14 @@ async function fetchAuditData(source, skillSlugs, sourceType, timeoutMs = 3e3) {
1888
1902
  return null;
1889
1903
  }
1890
1904
  }
1905
+ let cachedUserParam;
1906
+ function getUserParam() {
1907
+ if (cachedUserParam === void 0) {
1908
+ const user = getCurrentUser();
1909
+ cachedUserParam = user ? JSON.stringify(user) : null;
1910
+ }
1911
+ return cachedUserParam;
1912
+ }
1891
1913
  function track(data) {
1892
1914
  if (!isEnabled()) return;
1893
1915
  try {
@@ -1895,6 +1917,8 @@ function track(data) {
1895
1917
  pendingCount++;
1896
1918
  if (cliVersion) params.set("v", cliVersion);
1897
1919
  if (isCI()) params.set("ci", "1");
1920
+ const userParam = getUserParam();
1921
+ if (userParam) params.set("user", userParam);
1898
1922
  for (const [key, value] of Object.entries(data)) if (value !== void 0 && value !== null) params.set(key, String(value));
1899
1923
  const requestUrl = `${TELEMETRY_URL}?${params.toString()}`;
1900
1924
  if (process.env.DEBUG) console.log("[Telemetry] request:", requestUrl);
@@ -2340,7 +2364,7 @@ function logSkillParseFailures(failures) {
2340
2364
  if (f.hint) M.message(import_picocolors.default.yellow(` 提示: ${f.hint}`));
2341
2365
  }
2342
2366
  }
2343
- var version$1 = "2.0.32";
2367
+ var version$1 = "2.0.34";
2344
2368
  const isCancelled$1 = (value) => typeof value === "symbol";
2345
2369
  function redactSensitiveText(text) {
2346
2370
  return text.replace(/(https?:\/\/)([^/\s:@]+)(?::([^@/\s]*))?@/gi, "$1").replace(/([?&](?:private_token|access_token|token|api_key|access_key|secret|password)=)[^&\s]+/gi, "$1***");
@@ -2368,7 +2392,7 @@ function socketLabel(audit) {
2368
2392
  const count = audit.alerts ?? 0;
2369
2393
  return count > 0 ? import_picocolors.default.red(`${count} alert${count !== 1 ? "s" : ""}`) : import_picocolors.default.green("0 alerts");
2370
2394
  }
2371
- function padEnd(str, width) {
2395
+ function padEnd$1(str, width) {
2372
2396
  const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
2373
2397
  const pad = Math.max(0, width - visible.length);
2374
2398
  return str + " ".repeat(pad);
@@ -2381,7 +2405,7 @@ function buildSecurityLines(auditData, skills, source) {
2381
2405
  })) return [];
2382
2406
  const nameWidth = Math.min(Math.max(...skills.map((s) => s.displayName.length)), 36);
2383
2407
  const lines = [];
2384
- const header = padEnd("", nameWidth + 2) + padEnd(import_picocolors.default.dim("Gen"), 18) + padEnd(import_picocolors.default.dim("Socket"), 18) + import_picocolors.default.dim("Snyk");
2408
+ const header = padEnd$1("", nameWidth + 2) + padEnd$1(import_picocolors.default.dim("Gen"), 18) + padEnd$1(import_picocolors.default.dim("Socket"), 18) + import_picocolors.default.dim("Snyk");
2385
2409
  lines.push(header);
2386
2410
  for (const skill of skills) {
2387
2411
  const data = auditData[skill.slug];
@@ -2389,7 +2413,7 @@ function buildSecurityLines(auditData, skills, source) {
2389
2413
  const ath = data?.ath ? riskLabel(data.ath.risk) : import_picocolors.default.dim("--");
2390
2414
  const socket = data?.socket ? socketLabel(data.socket) : import_picocolors.default.dim("--");
2391
2415
  const snyk = data?.snyk ? riskLabel(data.snyk.risk) : import_picocolors.default.dim("--");
2392
- lines.push(padEnd(import_picocolors.default.cyan(name), nameWidth + 2) + padEnd(ath, 18) + padEnd(socket, 18) + snyk);
2416
+ lines.push(padEnd$1(import_picocolors.default.cyan(name), nameWidth + 2) + padEnd$1(ath, 18) + padEnd$1(socket, 18) + snyk);
2393
2417
  }
2394
2418
  lines.push("");
2395
2419
  lines.push(`${import_picocolors.default.dim("Details:")} ${import_picocolors.default.dim(`https://skills.sh/${source}`)}`);
@@ -2741,20 +2765,16 @@ async function handleWellKnownSkills(source, url, options, spinner) {
2741
2765
  skillFiles[skill.installName] = skill.sourceUrl;
2742
2766
  if (skill.description) skillDescriptions[skill.installName] = skill.description;
2743
2767
  }
2744
- if (await isSourcePrivate(sourceIdentifier) !== true) {
2745
- const currentUser = getCurrentUser();
2746
- track({
2747
- event: "install",
2748
- source: sourceIdentifier,
2749
- skills: selectedSkills.map((s) => s.installName).join(","),
2750
- agents: targetAgents.join(","),
2751
- ...installGlobally && { global: "1" },
2752
- skillFiles: JSON.stringify(skillFiles),
2753
- sourceType: "well-known",
2754
- descriptions: JSON.stringify(skillDescriptions),
2755
- ...currentUser && { user: JSON.stringify(currentUser) }
2756
- });
2757
- }
2768
+ if (await isSourcePrivate(sourceIdentifier) !== true) track({
2769
+ event: "install",
2770
+ source: sourceIdentifier,
2771
+ skills: selectedSkills.map((s) => s.installName).join(","),
2772
+ agents: targetAgents.join(","),
2773
+ ...installGlobally && { global: "1" },
2774
+ skillFiles: JSON.stringify(skillFiles),
2775
+ sourceType: "well-known",
2776
+ descriptions: JSON.stringify(skillDescriptions)
2777
+ });
2758
2778
  if (successful.length > 0 && installGlobally) {
2759
2779
  const successfulSkillNames = new Set(successful.map((r) => r.skill));
2760
2780
  for (const skill of selectedSkills) if (successfulSkillNames.has(skill.installName)) try {
@@ -3315,25 +3335,7 @@ async function runAdd(args, options = {}) {
3315
3335
  if (normalizedSource && trackableSkillNames.length > 0) {
3316
3336
  const ownerRepo = parseOwnerRepo(normalizedSource);
3317
3337
  if (ownerRepo) {
3318
- if (await isRepoPrivate(ownerRepo.owner, ownerRepo.repo) === false) {
3319
- const currentUser = getCurrentUser();
3320
- track({
3321
- event: "install",
3322
- source: normalizedSource,
3323
- skills: trackableSkillNames.join(","),
3324
- agents: targetAgents.join(","),
3325
- ...installGlobally && { global: "1" },
3326
- skillFiles: JSON.stringify(skillFiles),
3327
- sourceType: effectiveSourceType,
3328
- skillMdLastCommitAuthors: JSON.stringify(skillMdLastCommitAuthors),
3329
- skillMdConfigAuthors: JSON.stringify(skillMdAuthors),
3330
- descriptions: JSON.stringify(skillDescriptions),
3331
- ...currentUser && { user: JSON.stringify(currentUser) }
3332
- });
3333
- }
3334
- } else {
3335
- const currentUser = getCurrentUser();
3336
- track({
3338
+ if (await isRepoPrivate(ownerRepo.owner, ownerRepo.repo) === false) track({
3337
3339
  event: "install",
3338
3340
  source: normalizedSource,
3339
3341
  skills: trackableSkillNames.join(","),
@@ -3343,10 +3345,20 @@ async function runAdd(args, options = {}) {
3343
3345
  sourceType: effectiveSourceType,
3344
3346
  skillMdLastCommitAuthors: JSON.stringify(skillMdLastCommitAuthors),
3345
3347
  skillMdConfigAuthors: JSON.stringify(skillMdAuthors),
3346
- descriptions: JSON.stringify(skillDescriptions),
3347
- ...currentUser && { user: JSON.stringify(currentUser) }
3348
+ descriptions: JSON.stringify(skillDescriptions)
3348
3349
  });
3349
- }
3350
+ } else track({
3351
+ event: "install",
3352
+ source: normalizedSource,
3353
+ skills: trackableSkillNames.join(","),
3354
+ agents: targetAgents.join(","),
3355
+ ...installGlobally && { global: "1" },
3356
+ skillFiles: JSON.stringify(skillFiles),
3357
+ sourceType: effectiveSourceType,
3358
+ skillMdLastCommitAuthors: JSON.stringify(skillMdLastCommitAuthors),
3359
+ skillMdConfigAuthors: JSON.stringify(skillMdAuthors),
3360
+ descriptions: JSON.stringify(skillDescriptions)
3361
+ });
3350
3362
  }
3351
3363
  if (successful.length > 0 && installGlobally && normalizedSource) {
3352
3364
  const successfulSkillNames = new Set(successful.map((r) => r.skill));
@@ -3564,9 +3576,9 @@ function parseAddOptions(args) {
3564
3576
  options
3565
3577
  };
3566
3578
  }
3567
- const RESET$5 = "\x1B[0m";
3568
- const BOLD$2 = "\x1B[1m";
3569
- const DIM$5 = "\x1B[38;5;102m";
3579
+ const RESET$6 = "\x1B[0m";
3580
+ const BOLD$3 = "\x1B[1m";
3581
+ const DIM$6 = "\x1B[38;5;102m";
3570
3582
  const TEXT$5 = "\x1B[38;5;145m";
3571
3583
  const CYAN$1 = "\x1B[36m";
3572
3584
  const YELLOW$5 = "\x1B[33m";
@@ -3622,29 +3634,29 @@ async function runSearchPrompt(initialQuery = "") {
3622
3634
  if (lastRenderedLines > 0) process.stdout.write(MOVE_UP(lastRenderedLines) + MOVE_TO_COL(1));
3623
3635
  process.stdout.write(CLEAR_DOWN);
3624
3636
  const lines = [];
3625
- const cursor = `${BOLD$2}_${RESET$5}`;
3626
- lines.push(`${TEXT$5}Search skills:${RESET$5} ${query}${cursor}`);
3637
+ const cursor = `${BOLD$3}_${RESET$6}`;
3638
+ lines.push(`${TEXT$5}Search skills:${RESET$6} ${query}${cursor}`);
3627
3639
  lines.push("");
3628
- if (!query || query.length < 2) lines.push(`${DIM$5}Start typing to search (min 2 chars)${RESET$5}`);
3629
- else if (results.length === 0 && loading) lines.push(`${DIM$5}Searching...${RESET$5}`);
3630
- else if (results.length === 0) lines.push(`${DIM$5}No skills found${RESET$5}`);
3640
+ if (!query || query.length < 2) lines.push(`${DIM$6}Start typing to search (min 2 chars)${RESET$6}`);
3641
+ else if (results.length === 0 && loading) lines.push(`${DIM$6}Searching...${RESET$6}`);
3642
+ else if (results.length === 0) lines.push(`${DIM$6}No skills found${RESET$6}`);
3631
3643
  else {
3632
3644
  const visible = results.slice(0, 8);
3633
3645
  for (let i = 0; i < visible.length; i++) {
3634
3646
  const skill = visible[i];
3635
3647
  const isSelected = i === selectedIndex;
3636
- const arrow = isSelected ? `${BOLD$2}>${RESET$5}` : " ";
3637
- const name = isSelected ? `${BOLD$2}${skill.name}${RESET$5}` : `${TEXT$5}${skill.name}${RESET$5}`;
3638
- const source = skill.source ? ` ${DIM$5}${skill.source}${RESET$5}` : "";
3648
+ const arrow = isSelected ? `${BOLD$3}>${RESET$6}` : " ";
3649
+ const name = isSelected ? `${BOLD$3}${skill.name}${RESET$6}` : `${TEXT$5}${skill.name}${RESET$6}`;
3650
+ const source = skill.source ? ` ${DIM$6}${skill.source}${RESET$6}` : "";
3639
3651
  const installs = formatInstalls(skill.installs);
3640
- const installsBadge = installs ? ` ${CYAN$1}${installs}${RESET$5}` : "";
3641
- const githubBadge = skill.sourceType === "github" ? ` ${YELLOW$5}GitHub${RESET$5}` : "";
3642
- const loadingIndicator = loading && i === 0 ? ` ${DIM$5}...${RESET$5}` : "";
3652
+ const installsBadge = installs ? ` ${CYAN$1}${installs}${RESET$6}` : "";
3653
+ const githubBadge = skill.sourceType === "github" ? ` ${YELLOW$5}GitHub${RESET$6}` : "";
3654
+ const loadingIndicator = loading && i === 0 ? ` ${DIM$6}...${RESET$6}` : "";
3643
3655
  lines.push(` ${arrow} ${name}${source}${githubBadge}${installsBadge}${loadingIndicator}`);
3644
3656
  }
3645
3657
  }
3646
3658
  lines.push("");
3647
- lines.push(`${DIM$5}up/down navigate | enter select | esc cancel${RESET$5}`);
3659
+ lines.push(`${DIM$6}up/down navigate | enter select | esc cancel${RESET$6}`);
3648
3660
  for (const line of lines) process.stdout.write(line + "\n");
3649
3661
  lastRenderedLines = lines.length;
3650
3662
  }
@@ -3728,9 +3740,9 @@ async function runSearchPrompt(initialQuery = "") {
3728
3740
  async function runFind(args) {
3729
3741
  const query = args.join(" ");
3730
3742
  const isNonInteractive = !process.stdin.isTTY;
3731
- const agentTip = `${DIM$5}Tip: if running in a coding agent, follow these steps:${RESET$5}
3732
- ${DIM$5} 1) npx @ali/cli-skills find [query]${RESET$5}
3733
- ${DIM$5} 2) npx @ali/cli-skills add <owner/repo@skill>${RESET$5}`;
3743
+ const agentTip = `${DIM$6}Tip: if running in a coding agent, follow these steps:${RESET$6}
3744
+ ${DIM$6} 1) npx @ali/cli-skills find [query]${RESET$6}
3745
+ ${DIM$6} 2) npx @ali/cli-skills add <owner/repo@skill>${RESET$6}`;
3734
3746
  if (query) {
3735
3747
  const results = await searchSkillsAPI(query);
3736
3748
  track({
@@ -3739,18 +3751,18 @@ ${DIM$5} 2) npx @ali/cli-skills add <owner/repo@skill>${RESET$5}`;
3739
3751
  resultCount: String(results.length)
3740
3752
  });
3741
3753
  if (results.length === 0) {
3742
- console.log(`${DIM$5}No skills found for "${query}"${RESET$5}`);
3754
+ console.log(`${DIM$6}No skills found for "${query}"${RESET$6}`);
3743
3755
  return;
3744
3756
  }
3745
- console.log(`${DIM$5}Install with${RESET$5} npx ali-skills add <owner/repo>`);
3757
+ console.log(`${DIM$6}Install with${RESET$6} npx ali-skills add <owner/repo>`);
3746
3758
  console.log();
3747
3759
  for (const skill of results.slice(0, 6)) {
3748
3760
  const pkg = skill.source || skill.slug;
3749
3761
  const installs = formatInstalls(skill.installs);
3750
- const githubBadge = skill.sourceType === "github" ? ` ${YELLOW$5}GitHub${RESET$5}` : "";
3751
- console.log(`${TEXT$5}${pkg}@${skill.name}${RESET$5}${githubBadge}${installs ? ` ${CYAN$1}${installs}${RESET$5}` : ""}`);
3762
+ const githubBadge = skill.sourceType === "github" ? ` ${YELLOW$5}GitHub${RESET$6}` : "";
3763
+ console.log(`${TEXT$5}${pkg}@${skill.name}${RESET$6}${githubBadge}${installs ? ` ${CYAN$1}${installs}${RESET$6}` : ""}`);
3752
3764
  const skillUrl = buildSkillUrl(skill);
3753
- console.log(`${DIM$5}└ ${skillUrl}${RESET$5}`);
3765
+ console.log(`${DIM$6}└ ${skillUrl}${RESET$6}`);
3754
3766
  console.log();
3755
3767
  }
3756
3768
  return;
@@ -3767,14 +3779,14 @@ ${DIM$5} 2) npx @ali/cli-skills add <owner/repo@skill>${RESET$5}`;
3767
3779
  interactive: "1"
3768
3780
  });
3769
3781
  if (!selected) {
3770
- console.log(`${DIM$5}Search cancelled${RESET$5}`);
3782
+ console.log(`${DIM$6}Search cancelled${RESET$6}`);
3771
3783
  console.log();
3772
3784
  return;
3773
3785
  }
3774
3786
  const pkg = selected.source || selected.slug;
3775
3787
  const skillName = selected.name;
3776
3788
  console.log();
3777
- console.log(`${TEXT$5}Installing ${BOLD$2}${skillName}${RESET$5} from ${DIM$5}${pkg}${RESET$5}...`);
3789
+ console.log(`${TEXT$5}Installing ${BOLD$3}${skillName}${RESET$6} from ${DIM$6}${pkg}${RESET$6}...`);
3778
3790
  console.log();
3779
3791
  const { source, options } = parseAddOptions([
3780
3792
  pkg,
@@ -3784,7 +3796,7 @@ ${DIM$5} 2) npx @ali/cli-skills add <owner/repo@skill>${RESET$5}`;
3784
3796
  await runAdd(source, options);
3785
3797
  console.log();
3786
3798
  const skillUrl = buildSkillUrl(selected);
3787
- console.log(`${DIM$5}View the skill at${RESET$5} ${TEXT$5}${skillUrl}${RESET$5}`);
3799
+ console.log(`${DIM$6}View the skill at${RESET$6} ${TEXT$5}${skillUrl}${RESET$6}`);
3788
3800
  console.log();
3789
3801
  }
3790
3802
  const isCancelled = (value) => typeof value === "symbol";
@@ -4123,9 +4135,9 @@ async function runInstallFromLock(args) {
4123
4135
  }
4124
4136
  }
4125
4137
  }
4126
- const RESET$4 = "\x1B[0m";
4127
- const BOLD$1 = "\x1B[1m";
4128
- const DIM$4 = "\x1B[38;5;102m";
4138
+ const RESET$5 = "\x1B[0m";
4139
+ const BOLD$2 = "\x1B[1m";
4140
+ const DIM$5 = "\x1B[38;5;102m";
4129
4141
  const TEXT$4 = "\x1B[38;5;145m";
4130
4142
  const CYAN = "\x1B[36m";
4131
4143
  const YELLOW$4 = "\x1B[33m";
@@ -4167,8 +4179,8 @@ async function runList(args) {
4167
4179
  const validAgents = Object.keys(agents);
4168
4180
  const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
4169
4181
  if (invalidAgents.length > 0) {
4170
- console.log(`${YELLOW$4}Invalid agents: ${invalidAgents.join(", ")}${RESET$4}`);
4171
- console.log(`${DIM$4}Valid agents: ${validAgents.join(", ")}${RESET$4}`);
4182
+ console.log(`${YELLOW$4}Invalid agents: ${invalidAgents.join(", ")}${RESET$5}`);
4183
+ console.log(`${DIM$5}Valid agents: ${validAgents.join(", ")}${RESET$5}`);
4172
4184
  process.exit(1);
4173
4185
  }
4174
4186
  agentFilter = options.agent;
@@ -4188,7 +4200,7 @@ async function runList(args) {
4188
4200
  return;
4189
4201
  }
4190
4202
  if (!scope && !options.scopeSpecified) {
4191
- console.log(`${DIM$4}提示: 当前为项目级列表。如需查看全局技能,请执行: ${TEXT$4}npx ali-skills list -g${RESET$4}`);
4203
+ console.log(`${DIM$5}提示: 当前为项目级列表。如需查看全局技能,请执行: ${TEXT$4}npx ali-skills list -g${RESET$5}`);
4192
4204
  console.log();
4193
4205
  }
4194
4206
  const lockedSkills = await getAllLockedSkills();
@@ -4199,19 +4211,19 @@ async function runList(args) {
4199
4211
  console.log("[]");
4200
4212
  return;
4201
4213
  }
4202
- console.log(`${DIM$4}No ${scopeLabel.toLowerCase()} skills found.${RESET$4}`);
4203
- if (scope) console.log(`${DIM$4}Try listing project skills without -g${RESET$4}`);
4214
+ console.log(`${DIM$5}No ${scopeLabel.toLowerCase()} skills found.${RESET$5}`);
4215
+ if (scope) console.log(`${DIM$5}Try listing project skills without -g${RESET$5}`);
4204
4216
  return;
4205
4217
  }
4206
4218
  function printSkill(skill, indent = false) {
4207
4219
  const prefix = indent ? " " : "";
4208
4220
  const shortPath = shortenPath(skill.canonicalPath, cwd);
4209
4221
  const agentNames = skill.agents.map((a) => agents[a].displayName);
4210
- const agentInfo = skill.agents.length > 0 ? formatList(agentNames) : `${YELLOW$4}not linked${RESET$4}`;
4211
- console.log(`${prefix}${CYAN}${skill.name}${RESET$4} ${DIM$4}${shortPath}${RESET$4}`);
4212
- console.log(`${prefix} ${DIM$4}Agents:${RESET$4} ${agentInfo}`);
4222
+ const agentInfo = skill.agents.length > 0 ? formatList(agentNames) : `${YELLOW$4}not linked${RESET$5}`;
4223
+ console.log(`${prefix}${CYAN}${skill.name}${RESET$5} ${DIM$5}${shortPath}${RESET$5}`);
4224
+ console.log(`${prefix} ${DIM$5}Agents:${RESET$5} ${agentInfo}`);
4213
4225
  }
4214
- console.log(`${BOLD$1}${scopeLabel} Skills${RESET$4}`);
4226
+ console.log(`${BOLD$2}${scopeLabel} Skills${RESET$5}`);
4215
4227
  console.log();
4216
4228
  const groupedSkills = {};
4217
4229
  const ungroupedSkills = [];
@@ -4227,13 +4239,13 @@ async function runList(args) {
4227
4239
  const sortedGroups = Object.keys(groupedSkills).sort();
4228
4240
  for (const group of sortedGroups) {
4229
4241
  const title = group.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
4230
- console.log(`${BOLD$1}${title}${RESET$4}`);
4242
+ console.log(`${BOLD$2}${title}${RESET$5}`);
4231
4243
  const skills = groupedSkills[group];
4232
4244
  if (skills) for (const skill of skills) printSkill(skill, true);
4233
4245
  console.log();
4234
4246
  }
4235
4247
  if (ungroupedSkills.length > 0) {
4236
- console.log(`${BOLD$1}General${RESET$4}`);
4248
+ console.log(`${BOLD$2}General${RESET$5}`);
4237
4249
  for (const skill of ungroupedSkills) printSkill(skill, true);
4238
4250
  console.log();
4239
4251
  }
@@ -4952,12 +4964,12 @@ function listPlatforms() {
4952
4964
  config
4953
4965
  }));
4954
4966
  }
4955
- const DIM$3 = "\x1B[38;5;102m";
4967
+ const DIM$4 = "\x1B[38;5;102m";
4956
4968
  const TEXT$3 = "\x1B[38;5;145m";
4957
- const RESET$3 = "\x1B[0m";
4969
+ const RESET$4 = "\x1B[0m";
4958
4970
  const GREEN$2 = "\x1B[32m";
4959
4971
  const YELLOW$3 = "\x1B[33m";
4960
- const RED$3 = "\x1B[31m";
4972
+ const RED$4 = "\x1B[31m";
4961
4973
  const STATUS_PLATFORM_KEYS = [
4962
4974
  "code",
4963
4975
  "yuque",
@@ -4971,9 +4983,9 @@ function isGatewayDebugEnabled() {
4971
4983
  }
4972
4984
  function gatewayDebugLog(message) {
4973
4985
  if (!isGatewayDebugEnabled()) return;
4974
- console.log(`${DIM$3}[gateway-debug]${RESET$3} ${message}`);
4986
+ console.log(`${DIM$4}[gateway-debug]${RESET$4} ${message}`);
4975
4987
  }
4976
- function displayWidth(str) {
4988
+ function displayWidth$1(str) {
4977
4989
  let width = 0;
4978
4990
  for (const char of str) width += char.charCodeAt(0) > 127 ? 2 : 1;
4979
4991
  return width;
@@ -4993,6 +5005,7 @@ function startLocalServer() {
4993
5005
  const empId = url.searchParams.get("emp_id") || "";
4994
5006
  const account = url.searchParams.get("account") || "";
4995
5007
  const name = url.searchParams.get("name") || "";
5008
+ const email = url.searchParams.get("email") || "";
4996
5009
  const privateToken = url.searchParams.get("private_token") || "";
4997
5010
  const ssoRefreshToken = url.searchParams.get("sso_refresh_token") || "";
4998
5011
  const expiresAt = url.searchParams.get("expires_at") || "0";
@@ -5149,6 +5162,7 @@ function startLocalServer() {
5149
5162
  empId,
5150
5163
  account,
5151
5164
  name,
5165
+ email,
5152
5166
  privateToken,
5153
5167
  ssoRefreshToken,
5154
5168
  expiresAt: parseInt(expiresAt, 10)
@@ -5183,11 +5197,11 @@ async function revokeGatewaySessionIfPossible(auth) {
5183
5197
  method: "POST",
5184
5198
  headers: { "X-Private-Token": auth.privateToken }
5185
5199
  });
5186
- if (revokeRes.ok) console.log(`${GREEN$2}✓ 已撤销当前网关会话${RESET$3}`);
5187
- else if (revokeRes.status === 404) console.log(`${DIM$3}服务端暂不支持撤销网关会话,继续本机登出${RESET$3}`);
5188
- else console.log(`${YELLOW$3}⚠️ 撤销网关会话失败,继续本机登出${RESET$3}`);
5200
+ if (revokeRes.ok) console.log(`${GREEN$2}✓ 已撤销当前网关会话${RESET$4}`);
5201
+ else if (revokeRes.status === 404) console.log(`${DIM$4}服务端暂不支持撤销网关会话,继续本机登出${RESET$4}`);
5202
+ else console.log(`${YELLOW$3}⚠️ 撤销网关会话失败,继续本机登出${RESET$4}`);
5189
5203
  } catch {
5190
- console.log(`${YELLOW$3}⚠️ 撤销网关会话失败,继续本机登出${RESET$3}`);
5204
+ console.log(`${YELLOW$3}⚠️ 撤销网关会话失败,继续本机登出${RESET$4}`);
5191
5205
  }
5192
5206
  }
5193
5207
  async function login(options) {
@@ -5200,28 +5214,29 @@ async function login(options) {
5200
5214
  } else {
5201
5215
  const existingAuth = readAuth();
5202
5216
  if (existingAuth && !isAuthExpired(existingAuth)) {
5203
- console.log(`${YELLOW$3}! 您已经登录为: ${existingAuth.name} (${existingAuth.account})${RESET$3}`);
5217
+ console.log(`${YELLOW$3}! 您已经登录为: ${existingAuth.name} (${existingAuth.account})${RESET$4}`);
5204
5218
  console.log();
5205
- console.log(`${DIM$3}如需重新登录,请执行: npx ali-skills login --reauth${RESET$3}`);
5219
+ console.log(`${DIM$4}如需重新登录,请执行: npx ali-skills login --reauth${RESET$4}`);
5206
5220
  return;
5207
5221
  }
5208
5222
  }
5209
- console.log(`${TEXT$3}正在启动本地服务...${RESET$3}`);
5223
+ console.log(`${TEXT$3}正在启动本地服务...${RESET$4}`);
5210
5224
  const { port, waitForCallback, close } = await startLocalServer();
5211
5225
  const callbackUrl = `http://localhost:${port}/callback`;
5212
5226
  const gatewayUrl = getGatewayUrl();
5213
5227
  const loginUrl = `${gatewayUrl}/api/gateway/login?callback_url=${encodeURIComponent(callbackUrl)}&type=cli`;
5214
- console.log(`${TEXT$3}正在打开浏览器进行 BUC 授权...${RESET$3}`);
5215
- console.log(`${DIM$3}如果浏览器没有自动打开,请手动访问:${RESET$3}`);
5216
- console.log(`${DIM$3}${loginUrl}${RESET$3}`);
5228
+ console.log(`${TEXT$3}正在打开浏览器进行 BUC 授权...${RESET$4}`);
5229
+ console.log(`${DIM$4}如果浏览器没有自动打开,请手动访问:${RESET$4}`);
5230
+ console.log(`${DIM$4}${loginUrl}${RESET$4}`);
5217
5231
  openBrowser$2(loginUrl);
5218
- console.log(`${TEXT$3}等待授权完成...${RESET$3}`);
5232
+ console.log(`${TEXT$3}等待授权完成...${RESET$4}`);
5219
5233
  try {
5220
- const { empId, account, name, privateToken, ssoRefreshToken, expiresAt } = await waitForCallback();
5234
+ const { empId, account, name, email, privateToken, ssoRefreshToken, expiresAt } = await waitForCallback();
5221
5235
  saveAuth({
5222
5236
  empId,
5223
5237
  account,
5224
5238
  name,
5239
+ email,
5225
5240
  gatewayUrl,
5226
5241
  privateToken,
5227
5242
  ssoRefreshToken,
@@ -5229,13 +5244,13 @@ async function login(options) {
5229
5244
  expiresAt: expiresAt * 1e3
5230
5245
  });
5231
5246
  console.log();
5232
- console.log(`${GREEN$2}✓ 登录成功!${RESET$3}`);
5233
- console.log(`${TEXT$3}欢迎: ${name} (${account})${RESET$3}`);
5234
- console.log(`${DIM$3}Token 有效期至: ${(/* @__PURE__ */ new Date(expiresAt * 1e3)).toLocaleDateString()}${RESET$3}`);
5247
+ console.log(`${GREEN$2}✓ 登录成功!${RESET$4}`);
5248
+ console.log(`${TEXT$3}欢迎: ${name} (${account})${RESET$4}`);
5249
+ console.log(`${DIM$4}Token 有效期至: ${(/* @__PURE__ */ new Date(expiresAt * 1e3)).toLocaleDateString()}${RESET$4}`);
5235
5250
  if (!ssoRefreshToken) {
5236
5251
  console.log();
5237
- console.log(`${YELLOW$3}⚠ SSO_REFRESH_TOKEN 获取异常:本次授权回调未携带该凭证,网关代理等依赖 SSO Cookie 的能力可能不可用${RESET$3}`);
5238
- console.log(`${DIM$3}可尝试:在网页端(https://ali-skills.alibaba-inc.com)退出平台登录后重新执行 login 命令。同时请将此问题反馈给本工具开发者处理,感谢!${RESET$3}`);
5252
+ console.log(`${YELLOW$3}⚠ SSO_REFRESH_TOKEN 获取异常:本次授权回调未携带该凭证,网关代理等依赖 SSO Cookie 的能力可能不可用${RESET$4}`);
5253
+ console.log(`${DIM$4}可尝试:在网页端(https://ali-skills.alibaba-inc.com)退出平台登录后重新执行 login 命令。同时请将此问题反馈给本工具开发者处理,感谢!${RESET$4}`);
5239
5254
  }
5240
5255
  } catch (error) {
5241
5256
  close();
@@ -5246,18 +5261,18 @@ async function logout(platformInput, yuqueGroup, clearAll) {
5246
5261
  if (platformInput) {
5247
5262
  const platform = resolvePlatformByInput(platformInput);
5248
5263
  if (!platform) {
5249
- console.error(`${RED$3}不支持的平台: ${platformInput}${RESET$3}`);
5250
- console.log(`${DIM$3}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$3}`);
5264
+ console.error(`${RED$4}不支持的平台: ${platformInput}${RESET$4}`);
5265
+ console.log(`${DIM$4}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$4}`);
5251
5266
  process.exit(1);
5252
5267
  }
5253
5268
  if (platform.key === "yuque") {
5254
5269
  if (clearAll) {
5255
5270
  if (!hasYuqueCredentials(readConfig().platforms?.yuque)) {
5256
- console.log(`${DIM$3}${platform.config.name} 未配置 Token${RESET$3}`);
5271
+ console.log(`${DIM$4}${platform.config.name} 未配置 Token${RESET$4}`);
5257
5272
  return;
5258
5273
  }
5259
5274
  removePlatformToken(platform.key);
5260
- console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的全部 Token 配置${RESET$3}`);
5275
+ console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的全部 Token 配置${RESET$4}`);
5261
5276
  return;
5262
5277
  }
5263
5278
  if (!yuqueGroup) {
@@ -5266,10 +5281,10 @@ async function logout(platformInput, yuqueGroup, clearAll) {
5266
5281
  if (groups.length === 0) {
5267
5282
  if (yuque?.privateToken?.trim()) {
5268
5283
  removePlatformToken(platform.key);
5269
- console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的 Token 配置${RESET$3}`);
5284
+ console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的 Token 配置${RESET$4}`);
5270
5285
  return;
5271
5286
  }
5272
- console.log(`${DIM$3}${platform.config.name} 未配置 Token${RESET$3}`);
5287
+ console.log(`${DIM$4}${platform.config.name} 未配置 Token${RESET$4}`);
5273
5288
  return;
5274
5289
  }
5275
5290
  const selected = await fe({
@@ -5281,61 +5296,61 @@ async function logout(platformInput, yuqueGroup, clearAll) {
5281
5296
  required: false
5282
5297
  });
5283
5298
  if (pD(selected)) {
5284
- console.log(`${DIM$3}已取消${RESET$3}`);
5299
+ console.log(`${DIM$4}已取消${RESET$4}`);
5285
5300
  return;
5286
5301
  }
5287
5302
  if (selected.length === 0) {
5288
- console.log(`${DIM$3}未选择任何团队,已取消${RESET$3}`);
5303
+ console.log(`${DIM$4}未选择任何团队,已取消${RESET$4}`);
5289
5304
  return;
5290
5305
  }
5291
5306
  for (const group of selected) removeYuqueGroup(group);
5292
- console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 团队 Token: ${selected.join(", ")}${RESET$3}`);
5307
+ console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 团队 Token: ${selected.join(", ")}${RESET$4}`);
5293
5308
  const remaining = Object.keys(readConfig().platforms?.yuque?.groups ?? {});
5294
- if (remaining.length > 0) console.log(`${DIM$3}剩余团队: ${remaining.join(", ")}${RESET$3}`);
5295
- console.log(`${DIM$3}如需清除全部,请执行: npx ali-skills logout yuque --all${RESET$3}`);
5309
+ if (remaining.length > 0) console.log(`${DIM$4}剩余团队: ${remaining.join(", ")}${RESET$4}`);
5310
+ console.log(`${DIM$4}如需清除全部,请执行: npx ali-skills logout yuque --all${RESET$4}`);
5296
5311
  return;
5297
5312
  }
5298
5313
  if (!hasYuqueCredentials(readConfig().platforms?.yuque)) {
5299
- console.log(`${DIM$3}${platform.config.name} 未配置 Token${RESET$3}`);
5314
+ console.log(`${DIM$4}${platform.config.name} 未配置 Token${RESET$4}`);
5300
5315
  return;
5301
5316
  }
5302
5317
  const g = yuqueGroup.trim();
5303
5318
  if (!(readConfig().platforms?.yuque)?.groups?.[g]?.privateToken?.trim()) {
5304
- console.log(`${DIM$3}${platform.config.name} 团队 ${g} 未配置 Group Access Token${RESET$3}`);
5319
+ console.log(`${DIM$4}${platform.config.name} 团队 ${g} 未配置 Group Access Token${RESET$4}`);
5305
5320
  return;
5306
5321
  }
5307
5322
  removeYuqueGroup(g);
5308
- console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 团队 ${g} 的 Token${RESET$3}`);
5323
+ console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 团队 ${g} 的 Token${RESET$4}`);
5309
5324
  return;
5310
5325
  }
5311
5326
  if (platform.key === "o2") {
5312
5327
  const gatewayAuth = readAuth();
5313
5328
  const bucLoggedIn = Boolean(gatewayAuth) && !isAuthExpired(gatewayAuth);
5314
- console.log(`${TEXT$3}${platform.config.name} 使用内置服务调用身份,无独立平台 Token${RESET$3}`);
5315
- console.log(` BUC 登录态: ${bucLoggedIn ? `${GREEN$2}已登录${RESET$3}` : `${YELLOW$3}未登录${RESET$3}`}`);
5316
- console.log(`${DIM$3}如需退出 BUC 登录态,请执行: npx ali-skills logout${RESET$3}`);
5329
+ console.log(`${TEXT$3}${platform.config.name} 使用内置服务调用身份,无独立平台 Token${RESET$4}`);
5330
+ console.log(` BUC 登录态: ${bucLoggedIn ? `${GREEN$2}已登录${RESET$4}` : `${YELLOW$3}未登录${RESET$4}`}`);
5331
+ console.log(`${DIM$4}如需退出 BUC 登录态,请执行: npx ali-skills logout${RESET$4}`);
5317
5332
  return;
5318
5333
  }
5319
5334
  const token = readConfig().platforms?.[platform.key]?.privateToken;
5320
5335
  if (!token || !token.trim()) {
5321
- console.log(`${DIM$3}${platform.config.name} 未配置 Private Token${RESET$3}`);
5336
+ console.log(`${DIM$4}${platform.config.name} 未配置 Private Token${RESET$4}`);
5322
5337
  return;
5323
5338
  }
5324
5339
  removePlatformToken(platform.key);
5325
- console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的 Private Token 配置${RESET$3}`);
5340
+ console.log(`${GREEN$2}✓ 已清除 ${platform.config.name} 的 Private Token 配置${RESET$4}`);
5326
5341
  return;
5327
5342
  }
5328
5343
  const auth = readAuth();
5329
5344
  if (!auth) {
5330
- console.log(`${DIM$3}您尚未登录${RESET$3}`);
5345
+ console.log(`${DIM$4}您尚未登录${RESET$4}`);
5331
5346
  return;
5332
5347
  }
5333
5348
  try {
5334
5349
  await revokeGatewaySessionIfPossible(auth);
5335
5350
  removeAuth();
5336
- console.log(`${GREEN$2}✓ 已登出${RESET$3}`);
5351
+ console.log(`${GREEN$2}✓ 已登出${RESET$4}`);
5337
5352
  } catch (error) {
5338
- console.error(`${RED$3}登出失败: ${error.message}${RESET$3}`);
5353
+ console.error(`${RED$4}登出失败: ${error.message}${RESET$4}`);
5339
5354
  process.exit(1);
5340
5355
  }
5341
5356
  }
@@ -5365,52 +5380,52 @@ function resolvePlatformByInput(platformInput) {
5365
5380
  function printSinglePlatformStatus(platformInput, isLoggedIn) {
5366
5381
  const platform = resolvePlatformByInput(platformInput);
5367
5382
  if (!platform) {
5368
- console.error(`${RED$3}不支持的平台: ${platformInput}${RESET$3}`);
5369
- console.log(`${DIM$3}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$3}`);
5383
+ console.error(`${RED$4}不支持的平台: ${platformInput}${RESET$4}`);
5384
+ console.log(`${DIM$4}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$4}`);
5370
5385
  process.exit(1);
5371
5386
  }
5372
5387
  const config = readConfig();
5373
5388
  const yuque = platform.key === "yuque" ? config.platforms?.yuque : void 0;
5374
5389
  const isBuiltinServiceIdentity = platform.key === "o2";
5375
5390
  const hasPrivateToken = platform.key === "yuque" ? hasYuqueCredentials(yuque) : isBuiltinServiceIdentity || Boolean(config.platforms?.[platform.key]?.privateToken?.trim());
5376
- console.log(`${TEXT$3}平台状态: ${platform.config.name}${RESET$3}`);
5391
+ console.log(`${TEXT$3}平台状态: ${platform.config.name}${RESET$4}`);
5377
5392
  if (platform.key === "yuque") {
5378
5393
  const groupCount = yuque?.groups ? Object.keys(yuque.groups).length : 0;
5379
- const line = groupCount > 0 ? ` Group Access Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$3}` : `${YELLOW$3}未配置${RESET$3}`} ${DIM$3}(${groupCount} 团队)${RESET$3}` : ` Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$3}` : `${YELLOW$3}未配置${RESET$3}`}`;
5394
+ const line = groupCount > 0 ? ` Group Access Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$4}` : `${YELLOW$3}未配置${RESET$4}`} ${DIM$4}(${groupCount} 团队)${RESET$4}` : ` Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$4}` : `${YELLOW$3}未配置${RESET$4}`}`;
5380
5395
  console.log(line);
5381
- if (yuque?.defaultGroup) console.log(`${DIM$3} 默认团队: ${yuque.defaultGroup}${RESET$3}`);
5382
- } else if (isBuiltinServiceIdentity) console.log(` Token: ${GREEN$2}无需配置(走内置服务调用身份)${RESET$3}`);
5383
- else console.log(` Private Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$3}` : `${YELLOW$3}未配置${RESET$3}`}`);
5384
- if (!hasPrivateToken && !isBuiltinServiceIdentity) console.log(`${DIM$3} 配置命令: npx ali-skills login ${platform.key}${RESET$3}`);
5385
- if (platform.config.authType !== "private_token") console.log(` BUC 登录: ${isLoggedIn ? `${GREEN$2}已登录${RESET$3}` : `${YELLOW$3}未登录${RESET$3}`}`);
5396
+ if (yuque?.defaultGroup) console.log(`${DIM$4} 默认团队: ${yuque.defaultGroup}${RESET$4}`);
5397
+ } else if (isBuiltinServiceIdentity) console.log(` Token: ${GREEN$2}无需配置(走内置服务调用身份)${RESET$4}`);
5398
+ else console.log(` Private Token: ${hasPrivateToken ? `${GREEN$2}已配置${RESET$4}` : `${YELLOW$3}未配置${RESET$4}`}`);
5399
+ if (!hasPrivateToken && !isBuiltinServiceIdentity) console.log(`${DIM$4} 配置命令: npx ali-skills login ${platform.key}${RESET$4}`);
5400
+ if (platform.config.authType !== "private_token") console.log(` BUC 登录: ${isLoggedIn ? `${GREEN$2}已登录${RESET$4}` : `${YELLOW$3}未登录${RESET$4}`}`);
5386
5401
  }
5387
5402
  function printYuqueGroupStatus(group) {
5388
5403
  const yuque = readConfig().platforms?.yuque;
5389
5404
  const token = yuque?.groups?.[group]?.privateToken?.trim() ?? "";
5390
5405
  const hasToken = Boolean(token);
5391
5406
  const isDefault = yuque?.defaultGroup === group;
5392
- console.log(`${TEXT$3}语雀团队状态: ${group}${RESET$3}`);
5393
- console.log(` Group Access Token: ${hasToken ? `${GREEN$2}已配置${RESET$3}` : `${YELLOW$3}未配置${RESET$3}`}`);
5394
- if (isDefault) console.log(` 默认团队: ${GREEN$2}是${RESET$3}`);
5395
- else if (yuque?.defaultGroup) console.log(`${DIM$3} 当前默认团队: ${yuque.defaultGroup}${RESET$3}`);
5396
- if (!hasToken) console.log(`${DIM$3} 配置命令: npx ali-skills login yuque ${group}${RESET$3}`);
5407
+ console.log(`${TEXT$3}语雀团队状态: ${group}${RESET$4}`);
5408
+ console.log(` Group Access Token: ${hasToken ? `${GREEN$2}已配置${RESET$4}` : `${YELLOW$3}未配置${RESET$4}`}`);
5409
+ if (isDefault) console.log(` 默认团队: ${GREEN$2}是${RESET$4}`);
5410
+ else if (yuque?.defaultGroup) console.log(`${DIM$4} 当前默认团队: ${yuque.defaultGroup}${RESET$4}`);
5411
+ if (!hasToken) console.log(`${DIM$4} 配置命令: npx ali-skills login yuque ${group}${RESET$4}`);
5397
5412
  }
5398
5413
  function printAllPlatformStatuses(isLoggedIn) {
5399
5414
  const config = readConfig();
5400
5415
  const platforms = listPlatforms().filter(({ key }) => STATUS_PLATFORM_KEYS.includes(key));
5401
- const maxKeyWidth = Math.max(...platforms.map(({ key }) => displayWidth(key)));
5402
- const maxNameWidth = Math.max(...platforms.map(({ config: p }) => displayWidth(p.name)));
5416
+ const maxKeyWidth = Math.max(...platforms.map(({ key }) => displayWidth$1(key)));
5417
+ const maxNameWidth = Math.max(...platforms.map(({ config: p }) => displayWidth$1(p.name)));
5403
5418
  console.log();
5404
- console.log(`${TEXT$3}平台凭证状态:${RESET$3}`);
5419
+ console.log(`${TEXT$3}平台凭证状态:${RESET$4}`);
5405
5420
  for (const { key, config: platform } of platforms) {
5406
5421
  const yuque = key === "yuque" ? config.platforms?.yuque : void 0;
5407
5422
  const isBuiltinServiceIdentity = key === "o2";
5408
5423
  const hasPrivateToken = key === "yuque" ? hasYuqueCredentials(yuque) : isBuiltinServiceIdentity || Boolean(config.platforms?.[key]?.privateToken?.trim());
5409
5424
  const groupCount = key === "yuque" && yuque?.groups ? Object.keys(yuque.groups).length : 0;
5410
- let statusText = isBuiltinServiceIdentity ? `${GREEN$2}Token 无需配置(走内置服务调用身份)${RESET$3}` : hasPrivateToken ? key === "yuque" && groupCount > 0 ? `${GREEN$2}Group Token 已配置${RESET$3} ${DIM$3}(${groupCount} 团队)${RESET$3}` : `${GREEN$2}Private Token 已配置${RESET$3}` : key === "yuque" ? `${YELLOW$3}Token 未配置${RESET$3}` : `${YELLOW$3}Private Token 未配置${RESET$3}`;
5411
- if (platform.authType !== "private_token") statusText += isLoggedIn ? ` ${DIM$3}(BUC 已登录)${RESET$3}` : ` ${DIM$3}(BUC 未登录)${RESET$3}`;
5412
- const keyPadding = " ".repeat(maxKeyWidth - displayWidth(key) + 2);
5413
- const namePadding = " ".repeat(maxNameWidth - displayWidth(platform.name) + 2);
5425
+ let statusText = isBuiltinServiceIdentity ? `${GREEN$2}Token 无需配置(走内置服务调用身份)${RESET$4}` : hasPrivateToken ? key === "yuque" && groupCount > 0 ? `${GREEN$2}Group Token 已配置${RESET$4} ${DIM$4}(${groupCount} 团队)${RESET$4}` : `${GREEN$2}Private Token 已配置${RESET$4}` : key === "yuque" ? `${YELLOW$3}Token 未配置${RESET$4}` : `${YELLOW$3}Private Token 未配置${RESET$4}`;
5426
+ if (platform.authType !== "private_token") statusText += isLoggedIn ? ` ${DIM$4}(BUC 已登录)${RESET$4}` : ` ${DIM$4}(BUC 未登录)${RESET$4}`;
5427
+ const keyPadding = " ".repeat(maxKeyWidth - displayWidth$1(key) + 2);
5428
+ const namePadding = " ".repeat(maxNameWidth - displayWidth$1(platform.name) + 2);
5414
5429
  console.log(` ${key}${keyPadding}${platform.name}${namePadding}${statusText}`);
5415
5430
  }
5416
5431
  }
@@ -5419,11 +5434,11 @@ async function status(args = {}) {
5419
5434
  const auth = readAuth();
5420
5435
  if (showPrivateToken && !targetPlatform) {
5421
5436
  if (showAll) {
5422
- console.error(`${RED$3}--show/-s 与 --all 同用时需指定平台,例如: npx ali-skills status yuque -s --all${RESET$3}`);
5437
+ console.error(`${RED$4}--show/-s 与 --all 同用时需指定平台,例如: npx ali-skills status yuque -s --all${RESET$4}`);
5423
5438
  process.exit(1);
5424
5439
  }
5425
5440
  if (!auth) {
5426
- console.error(`${RED$3}未登录网关,请执行: npx ali-skills login${RESET$3}`);
5441
+ console.error(`${RED$4}未登录网关,请执行: npx ali-skills login${RESET$4}`);
5427
5442
  process.exit(1);
5428
5443
  }
5429
5444
  printJson(auth, prettyJson);
@@ -5432,21 +5447,21 @@ async function status(args = {}) {
5432
5447
  if (targetPlatform && showPrivateToken) {
5433
5448
  const platform = resolvePlatformByInput(targetPlatform);
5434
5449
  if (!platform) {
5435
- console.error(`${RED$3}不支持的平台: ${targetPlatform}${RESET$3}`);
5436
- console.log(`${DIM$3}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$3}`);
5450
+ console.error(`${RED$4}不支持的平台: ${targetPlatform}${RESET$4}`);
5451
+ console.log(`${DIM$4}可用平台: ${STATUS_PLATFORM_KEYS.join(", ")}${RESET$4}`);
5437
5452
  process.exit(1);
5438
5453
  }
5439
5454
  if (platform.key === "yuque") {
5440
5455
  const yuque = readConfig().platforms?.yuque;
5441
5456
  if (!yuque) {
5442
- console.error(`${RED$3}未配置语雀 Token,请执行: npx ali-skills login yuque${RESET$3}`);
5457
+ console.error(`${RED$4}未配置语雀 Token,请执行: npx ali-skills login yuque${RESET$4}`);
5443
5458
  process.exit(1);
5444
5459
  }
5445
5460
  if (yuqueGroup) {
5446
5461
  const token = yuque.groups?.[yuqueGroup]?.privateToken?.trim();
5447
5462
  if (!token) {
5448
- console.error(`${RED$3}语雀团队 ${yuqueGroup} 未配置 Group Access Token${RESET$3}`);
5449
- console.log(`${DIM$3}可先执行: npx ali-skills login yuque ${yuqueGroup}${RESET$3}`);
5463
+ console.error(`${RED$4}语雀团队 ${yuqueGroup} 未配置 Group Access Token${RESET$4}`);
5464
+ console.log(`${DIM$4}可先执行: npx ali-skills login yuque ${yuqueGroup}${RESET$4}`);
5450
5465
  process.exit(1);
5451
5466
  }
5452
5467
  printJson({
@@ -5460,7 +5475,7 @@ async function status(args = {}) {
5460
5475
  }
5461
5476
  const token = readConfig().platforms?.[platform.key]?.privateToken?.trim() ?? "";
5462
5477
  if (!token) {
5463
- console.error(`${RED$3}未配置 Private Token,请执行: npx ali-skills login ${platform.key}${RESET$3}`);
5478
+ console.error(`${RED$4}未配置 Private Token,请执行: npx ali-skills login ${platform.key}${RESET$4}`);
5464
5479
  process.exit(1);
5465
5480
  }
5466
5481
  printJson({ privateToken: token }, prettyJson);
@@ -5475,8 +5490,8 @@ async function status(args = {}) {
5475
5490
  return;
5476
5491
  }
5477
5492
  if (!auth) {
5478
- console.log(`${DIM$3}您尚未登录${RESET$3}`);
5479
- console.log(`${TEXT$3}请执行: npx ali-skills login${RESET$3}`);
5493
+ console.log(`${DIM$4}您尚未登录${RESET$4}`);
5494
+ console.log(`${TEXT$3}请执行: npx ali-skills login${RESET$4}`);
5480
5495
  if (showAll) {
5481
5496
  console.log();
5482
5497
  printAllPlatformStatuses(false);
@@ -5486,15 +5501,15 @@ async function status(args = {}) {
5486
5501
  const expired = isAuthExpired(auth);
5487
5502
  const remaining = auth.expiresAt - Date.now();
5488
5503
  const remainingDays = Math.max(0, Math.floor(remaining / (1440 * 60 * 1e3)));
5489
- console.log(`${TEXT$3}登录状态:${RESET$3}`);
5504
+ console.log(`${TEXT$3}登录状态:${RESET$4}`);
5490
5505
  console.log(` 用户: ${auth.name} (${auth.account})`);
5491
5506
  console.log(` 工号: ${auth.empId}`);
5492
5507
  console.log(` 网关: ${getGatewayUrl()}`);
5493
- console.log(` SSO_REFRESH_TOKEN: ${auth.ssoRefreshToken ? `${GREEN$2}已缓存${RESET$3}` : `${YELLOW$3}未缓存${RESET$3}`}${auth.ssoRefreshTokenUpdatedAt ? `${DIM$3}(更新于 ${new Date(auth.ssoRefreshTokenUpdatedAt).toLocaleString()})${RESET$3}` : ""}`);
5508
+ console.log(` SSO_REFRESH_TOKEN: ${auth.ssoRefreshToken ? `${GREEN$2}已缓存${RESET$4}` : `${YELLOW$3}未缓存${RESET$4}`}${auth.ssoRefreshTokenUpdatedAt ? `${DIM$4}(更新于 ${new Date(auth.ssoRefreshTokenUpdatedAt).toLocaleString()})${RESET$4}` : ""}`);
5494
5509
  if (expired) {
5495
- console.log(` Token: ${YELLOW$3}已过期${RESET$3}`);
5496
- console.log(`${TEXT$3}请重新登录: npx ali-skills login --reauth${RESET$3}`);
5497
- } else console.log(` Token: ${GREEN$2}有效${RESET$3} (还剩 ${remainingDays} 天)`);
5510
+ console.log(` Token: ${YELLOW$3}已过期${RESET$4}`);
5511
+ console.log(`${TEXT$3}请重新登录: npx ali-skills login --reauth${RESET$4}`);
5512
+ } else console.log(` Token: ${GREEN$2}有效${RESET$4} (还剩 ${remainingDays} 天)`);
5498
5513
  if (showAll) {
5499
5514
  console.log();
5500
5515
  printAllPlatformStatuses(true);
@@ -5518,19 +5533,19 @@ async function ensureSsoRefreshToken() {
5518
5533
  ssoRefreshToken: data.ssoRefreshToken,
5519
5534
  ssoRefreshTokenUpdatedAt: Date.now()
5520
5535
  });
5521
- console.log(`${DIM$3}已从服务端获取 SSO_REFRESH_TOKEN${RESET$3}`);
5536
+ console.log(`${DIM$4}已从服务端获取 SSO_REFRESH_TOKEN${RESET$4}`);
5522
5537
  return data.ssoRefreshToken;
5523
5538
  }
5524
5539
  if (response.status === 404) {
5525
- console.log(`${YELLOW$3}⚠️ SSO_REFRESH_TOKEN 不可用${RESET$3}`);
5526
- console.log(`${DIM$3}提示: 请通过浏览器登录以获取 SSO_REFRESH_TOKEN${RESET$3}`);
5540
+ console.log(`${YELLOW$3}⚠️ SSO_REFRESH_TOKEN 不可用${RESET$4}`);
5541
+ console.log(`${DIM$4}提示: 请通过浏览器登录以获取 SSO_REFRESH_TOKEN${RESET$4}`);
5527
5542
  return null;
5528
5543
  }
5529
5544
  const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
5530
- console.error(`${RED$3}获取 SSO_REFRESH_TOKEN 失败: ${errorData.error}${RESET$3}`);
5545
+ console.error(`${RED$4}获取 SSO_REFRESH_TOKEN 失败: ${errorData.error}${RESET$4}`);
5531
5546
  return null;
5532
5547
  } catch (error) {
5533
- console.error(`${RED$3}获取 SSO_REFRESH_TOKEN 失败: ${error.message}${RESET$3}`);
5548
+ console.error(`${RED$4}获取 SSO_REFRESH_TOKEN 失败: ${error.message}${RESET$4}`);
5534
5549
  return null;
5535
5550
  }
5536
5551
  }
@@ -5554,16 +5569,16 @@ async function ensureSsoTicket() {
5554
5569
  const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
5555
5570
  gatewayDebugLog(`sso-ticket failed: code=${errorData.code ?? "n/a"}, error=${errorData.error ?? "Unknown error"}`);
5556
5571
  if (response.status === 401 && errorData.code === "INVALID_TOKEN") {
5557
- console.error(`${RED$3}ali-skills CLI 会话凭证(Gateway private token)已失效,无法获取 BUC SSO_TICKET${RESET$3}`);
5558
- console.log(`${TEXT$3}请重新登录: npx ali-skills login --reauth${RESET$3}`);
5572
+ console.error(`${RED$4}ali-skills CLI 会话凭证(Gateway private token)已失效,无法获取 BUC SSO_TICKET${RESET$4}`);
5573
+ console.log(`${TEXT$3}请重新登录: npx ali-skills login --reauth${RESET$4}`);
5559
5574
  return null;
5560
5575
  }
5561
- console.error(`${RED$3}获取 BUC SSO_TICKET 失败: ${errorData.error || errorData.code || "Unknown error"}${RESET$3}`);
5562
- console.log(`${TEXT$3}如果问题持续,请重新登录: npx ali-skills login --reauth${RESET$3}`);
5576
+ console.error(`${RED$4}获取 BUC SSO_TICKET 失败: ${errorData.error || errorData.code || "Unknown error"}${RESET$4}`);
5577
+ console.log(`${TEXT$3}如果问题持续,请重新登录: npx ali-skills login --reauth${RESET$4}`);
5563
5578
  return null;
5564
5579
  } catch (error) {
5565
5580
  gatewayDebugLog(`sso-ticket fetch exception: ${error.message}`);
5566
- console.error(`${RED$3}获取 SSO_TICKET 失败: ${error.message}${RESET$3}`);
5581
+ console.error(`${RED$4}获取 SSO_TICKET 失败: ${error.message}${RESET$4}`);
5567
5582
  return null;
5568
5583
  }
5569
5584
  }
@@ -5699,6 +5714,170 @@ function clearCookiesForDomain(hostname) {
5699
5714
  writeJar(jar);
5700
5715
  }
5701
5716
  }
5717
+ const RESET$3 = "\x1B[0m";
5718
+ const BOLD$1 = "\x1B[1m";
5719
+ const DIM$3 = "\x1B[38;5;102m";
5720
+ const RED$3 = "\x1B[31m";
5721
+ const STAFF_ENDPOINT = `${SKILLS_API_BASE_URL.replace(/\/skills\/?$/, "")}/staff-info`;
5722
+ const SUPPORTED_FLAGS = [
5723
+ "workNo",
5724
+ "nickName",
5725
+ "name",
5726
+ "licenseNo",
5727
+ "workNoList"
5728
+ ];
5729
+ function showStaffHelp() {
5730
+ console.log(`
5731
+ ${BOLD$1}Usage:${RESET$3} ali-skills staff <workNo|nickName> [options]
5732
+
5733
+ ${BOLD$1}Options:${RESET$3}
5734
+ --workNo=<工号> 按工号查询
5735
+ --nickName=<花名> 按花名查询
5736
+ --name=<姓名> 按姓名查询
5737
+ --licenseNo=<证件号> 按证件号查询
5738
+ --workNoList=<工号1,工号2> 批量工号查询
5739
+ --format=<md|json> 输出格式(默认 md)
5740
+
5741
+ ${BOLD$1}Examples:${RESET$3}
5742
+ ${DIM$3}$${RESET$3} ali-skills staff 000001
5743
+ ${DIM$3}$${RESET$3} ali-skills staff 花名
5744
+ ${DIM$3}$${RESET$3} ali-skills staff --name=姓名
5745
+ ${DIM$3}$${RESET$3} ali-skills staff --workNoList=000001,000002
5746
+ ${DIM$3}$${RESET$3} ali-skills staff 000001 --format=json
5747
+ `);
5748
+ }
5749
+ function parseStaffArgs(args) {
5750
+ for (let i = 0; i < args.length; i++) {
5751
+ const arg = args[i];
5752
+ for (const flag of SUPPORTED_FLAGS) {
5753
+ const prefix = `--${flag}=`;
5754
+ if (arg.startsWith(prefix)) {
5755
+ const value = arg.slice(prefix.length).trim();
5756
+ if (value) return {
5757
+ param: flag,
5758
+ value
5759
+ };
5760
+ }
5761
+ }
5762
+ if (arg.startsWith("--")) {
5763
+ const withoutDashes = arg.slice(2);
5764
+ if (withoutDashes.indexOf("=") === -1) {
5765
+ const flagName = withoutDashes;
5766
+ const nextVal = args[i + 1];
5767
+ if (nextVal && SUPPORTED_FLAGS.includes(flagName)) return {
5768
+ param: flagName,
5769
+ value: nextVal
5770
+ };
5771
+ }
5772
+ }
5773
+ }
5774
+ const positional = args.find((a, idx) => !a.startsWith("-") && args[idx - 1] !== "--format");
5775
+ if (positional) return {
5776
+ param: /^\d+$/.test(positional) || /^wb\d+$/i.test(positional) ? "workNo" : "nickName",
5777
+ value: positional
5778
+ };
5779
+ return null;
5780
+ }
5781
+ function displayWidth(str) {
5782
+ let width = 0;
5783
+ for (const char of str) {
5784
+ const code = char.codePointAt(0) ?? 0;
5785
+ if (code >= 4352 && code <= 4447 || code >= 11904 && code <= 42191 && code !== 12351 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65281 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 131072 && code <= 196605 || code >= 196608 && code <= 262141) width += 2;
5786
+ else width += 1;
5787
+ }
5788
+ return width;
5789
+ }
5790
+ function padEnd(str, targetWidth) {
5791
+ const diff = targetWidth - displayWidth(str);
5792
+ return diff > 0 ? str + " ".repeat(diff) : str;
5793
+ }
5794
+ function formatColumns(records) {
5795
+ const headers = [
5796
+ "NickName",
5797
+ "WorkNo",
5798
+ "Name",
5799
+ "Email"
5800
+ ];
5801
+ const rows = records.map((r) => [
5802
+ r.nickName,
5803
+ r.workNo,
5804
+ r.name,
5805
+ r.buMail
5806
+ ]);
5807
+ const widths = headers.map((h, i) => {
5808
+ const colValues = rows.map((row) => displayWidth(row[i] ?? ""));
5809
+ return Math.max(displayWidth(h), ...colValues);
5810
+ });
5811
+ const lines = [];
5812
+ lines.push(headers.map((h, i) => padEnd(h, widths[i])).join(" "));
5813
+ for (const row of rows) lines.push(row.map((cell, i) => padEnd(cell ?? "", widths[i])).join(" "));
5814
+ return lines.join("\n");
5815
+ }
5816
+ function parseFormat(args) {
5817
+ for (let i = 0; i < args.length; i++) {
5818
+ const arg = args[i];
5819
+ if (arg === "--format" && args[i + 1]) return args[i + 1] === "json" ? "json" : "md";
5820
+ if (arg.startsWith("--format=")) return arg.slice(9) === "json" ? "json" : "md";
5821
+ }
5822
+ return "md";
5823
+ }
5824
+ async function runStaff(args) {
5825
+ if (args.includes("--help") || args.includes("-h")) {
5826
+ showStaffHelp();
5827
+ return;
5828
+ }
5829
+ const format = parseFormat(args);
5830
+ const parsed = parseStaffArgs(args);
5831
+ if (!parsed) {
5832
+ showStaffHelp();
5833
+ return;
5834
+ }
5835
+ const url = `${STAFF_ENDPOINT}?${encodeURIComponent(parsed.param)}=${encodeURIComponent(parsed.value)}`;
5836
+ try {
5837
+ await ensureLogin();
5838
+ const ssoRefreshToken = await ensureSsoRefreshToken();
5839
+ if (!ssoRefreshToken) {
5840
+ console.error(`${RED$3}Error:${RESET$3} 缺少登录态,请先执行: npx ali-skills login`);
5841
+ process.exit(1);
5842
+ }
5843
+ const hostname = new URL(url).hostname;
5844
+ const res = await fetch(url, {
5845
+ headers: {
5846
+ "User-Agent": "ali-skills-cli/1.0",
5847
+ Cookie: buildCookieHeader(ssoRefreshToken, hostname)
5848
+ },
5849
+ redirect: "manual"
5850
+ });
5851
+ if (res.status >= 300 && res.status < 400) {
5852
+ console.error(`${RED$3}Error:${RESET$3} 登录态已过期,请执行: npx ali-skills login --reauth`);
5853
+ process.exit(1);
5854
+ }
5855
+ if (!(res.headers.get("content-type") ?? "").includes("application/json")) {
5856
+ console.error(`${RED$3}Error:${RESET$3} 服务端返回非 JSON 响应 (HTTP ${res.status}),可能是查询结果过多导致超时,请尝试更精确的查询条件`);
5857
+ process.exit(1);
5858
+ }
5859
+ const json = await res.json();
5860
+ if (!res.ok || !json.success) {
5861
+ console.error(`${RED$3}Error:${RESET$3} ${json.error || `Request failed (${res.status})`}`);
5862
+ process.exit(1);
5863
+ }
5864
+ const records = json.data?.records ?? [];
5865
+ track({
5866
+ event: "staff",
5867
+ query: parsed.param
5868
+ });
5869
+ if (records.length === 0) {
5870
+ console.log(`${DIM$3}No results found.${RESET$3}`);
5871
+ return;
5872
+ }
5873
+ if (format === "json") console.log(JSON.stringify(records, null, 2));
5874
+ else console.log(formatColumns(records));
5875
+ } catch (error) {
5876
+ if (error.code === "ERR_INVALID_URL") console.error(`${RED$3}Error:${RESET$3} Invalid API URL: ${url}`);
5877
+ else console.error(`${RED$3}Error:${RESET$3} ${error instanceof Error ? error.message : "Network request failed"}`);
5878
+ process.exit(1);
5879
+ }
5880
+ }
5702
5881
  const DIM$2 = "\x1B[38;5;102m";
5703
5882
  const TEXT$2 = "\x1B[38;5;145m";
5704
5883
  const RESET$2 = "\x1B[0m";
@@ -6914,6 +7093,8 @@ function showBanner() {
6914
7093
  console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills check${RESET} ${DIM}Check for updates${RESET}`);
6915
7094
  console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills update${RESET} ${DIM}Update all skills${RESET}`);
6916
7095
  console.log();
7096
+ console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills staff ${DIM}<query>${RESET} ${DIM}Query staff info${RESET}`);
7097
+ console.log();
6917
7098
  console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills experimental_install${RESET} ${DIM}Restore from skills-lock.json${RESET}`);
6918
7099
  console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills init ${DIM}[name]${RESET} ${DIM}Create a new skill${RESET}`);
6919
7100
  console.log(` ${DIM}$${RESET} ${TEXT}npx ali-skills experimental_sync${RESET} ${DIM}Sync skills from node_modules${RESET}`);
@@ -6949,6 +7130,13 @@ ${BOLD}Updates:${RESET}
6949
7130
  ${BOLD}Project:${RESET}
6950
7131
  init [name] Initialize a skill (creates <name>/SKILL.md or ./SKILL.md)
6951
7132
 
7133
+ ${BOLD}Staff:${RESET}
7134
+ staff <query> Query employee info (auto-detect workNo or nickName)
7135
+ staff --nickName=X Query by nick name
7136
+ staff --name=X Query by real name
7137
+ staff --workNoList=X Query by comma-separated work numbers
7138
+ staff --format=json Output as JSON (default: md)
7139
+
6952
7140
  ${BOLD}Gateway:${RESET}
6953
7141
  gateway 鉴权请求能力入口(login/logout/status/req)
6954
7142
  支持 privateToken/accessKey 身份托管请求(code、yuque、o2)
@@ -7001,6 +7189,8 @@ ${BOLD}Examples:${RESET}
7001
7189
  ${DIM}$${RESET} ali-skills ls --json ${DIM}# JSON output${RESET}
7002
7190
  ${DIM}$${RESET} ali-skills find ${DIM}# interactive search${RESET}
7003
7191
  ${DIM}$${RESET} ali-skills find typescript ${DIM}# search by keyword${RESET}
7192
+ ${DIM}$${RESET} ali-skills staff 工号 ${DIM}# query by workNo${RESET}
7193
+ ${DIM}$${RESET} ali-skills staff 花名 ${DIM}# query by nickName${RESET}
7004
7194
  ${DIM}$${RESET} ali-skills check
7005
7195
  ${DIM}$${RESET} ali-skills check web-design react-best-practices
7006
7196
  ${DIM}$${RESET} ali-skills update
@@ -8131,6 +8321,9 @@ async function main() {
8131
8321
  });
8132
8322
  break;
8133
8323
  }
8324
+ case "staff":
8325
+ await runStaff(restArgs);
8326
+ break;
8134
8327
  case "gateway":
8135
8328
  case "gw":
8136
8329
  await runGatewayCommand(restArgs);
@@ -8153,6 +8346,7 @@ async function main() {
8153
8346
  }
8154
8347
  }
8155
8348
  main().then(async () => {
8349
+ await flushTelemetry();
8156
8350
  if (getPendingTelemetryCount() > 0) {
8157
8351
  const syncStartAt = Date.now();
8158
8352
  const longSyncThresholdMs = 800;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ali/cli-skills",
3
- "version": "2.0.32",
3
+ "version": "2.0.34",
4
4
  "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ali-skills",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,7 +31,7 @@
31
31
  "author": "",
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@ali/cli-skills": "^2.0.32"
34
+ "@ali/cli-skills": "^2.0.34"
35
35
  },
36
36
  "bundleDependencies": [
37
37
  "@ali/cli-skills"