skill-atlas-cli 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -29,7 +29,7 @@ function showLogo() {
29
29
  const PKG = getPackageJson();
30
30
  const VERSION = PKG.version;
31
31
  async function main() {
32
- checkForUpdate(PKG);
32
+ await checkForUpdate(PKG);
33
33
  if (!process.argv.includes("-y") && !process.argv.includes("--yes")) showLogo();
34
34
  const parseArgv = process.argv.slice(2).length === 0 ? [...process.argv.slice(0, 2), "--help"] : process.argv;
35
35
  const cli = cac("skill-atlas");
@@ -41,11 +41,12 @@ async function main() {
41
41
  }
42
42
  await runSearch({ keyword: keyword.trim() });
43
43
  });
44
- cli.command("update", "快速升级 CLI 到最新版本").option("-y, --yes", "非交互模式,跳过确认直接升级").action(async (options) => {
44
+ cli.command("update", "快速升级 CLI 到最新版本").option("-y, --yes", "非交互模式,跳过确认直接升级").option("-p, --plugin", "使用官方安装脚本,同步更新 agent 插件与 CLI(推荐: skill-atlas update -y -p)").action(async (options) => {
45
45
  await runUpdate({
46
46
  pkgName: PKG.name,
47
47
  currentVersion: PKG.version,
48
- yes: options.yes
48
+ yes: options.yes,
49
+ plugin: options.plugin
49
50
  });
50
51
  });
51
52
  cli.command("install [name]", "安装 skill(支持 skill 名称)").option("-y, --yes", "非交互模式,默认安装到全局").option("-g, --global", "安装到全局目录").option("-p, --path <dir>", "安装到自定义路径(目录),如 -p /path/to/skills 或 -p .qoder/skills").option("-a, --agent <agent...>", "非 TTY 模式下指定目标 agent(如 cursor、openclaw),可传多个").action(async (name, options) => {
package/lib/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  //#region src/core/update-notifier.d.ts
2
2
  /**
3
- * 检查更新,有新版本时输出提示(无需重装,直接 update)
3
+ * 检查更新:TTY 任意新版本提示;非交互下 minor+ 自动执行官方安装脚本升级,patch 仅一行提示
4
4
  */
5
5
  declare function checkForUpdate(pkg: {
6
6
  name: string;
7
7
  version: string;
8
- }): void;
8
+ }): Promise<void>;
9
9
  //#endregion
10
10
  //#region src/commands/install.d.ts
11
11
  interface AddOptions {
@@ -51,6 +51,10 @@ interface UpdateOptions {
51
51
  currentVersion: string;
52
52
  /** 非交互模式,跳过确认 */
53
53
  yes?: boolean;
54
+ /**
55
+ * 使用官方 install 脚本升级(同步 IDE 插件与 CLI),非交互下可与 -y 合用
56
+ */
57
+ plugin?: boolean;
54
58
  }
55
59
  declare function runUpdate(options: UpdateOptions): Promise<void>;
56
60
  //#endregion
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@ import path, { join } from "node:path";
3
3
  import semver from "semver";
4
4
  import os from "node:os";
5
5
  import crypto, { createHash, randomBytes } from "node:crypto";
6
+ import { spawn } from "node:child_process";
6
7
  import * as p from "@clack/prompts";
7
8
  import chalk from "chalk";
8
9
  import axios from "axios";
@@ -15,7 +16,6 @@ import { cp, lstat, mkdir, readdir, readlink, realpath, rename, rm, stat, symlin
15
16
  import { execSync } from "child_process";
16
17
  import { info } from "console";
17
18
  import secp256k1 from "secp256k1";
18
- import { spawn } from "node:child_process";
19
19
  import { createConsola } from "consola";
20
20
  //#region \0rolldown/runtime.js
21
21
  var __create = Object.create;
@@ -243,9 +243,60 @@ var config_default = {
243
243
  getAgentCredentials
244
244
  };
245
245
  //#endregion
246
+ //#region src/core/npm-global-install.ts
247
+ /**
248
+ * 全局升级 skill-atlas-cli:
249
+ * - update 子命令:npm install -g(保持原方式)
250
+ * - 非 TTY 自动检查升级:与 skillhub 一致的官方安装脚本(curl|bash / PowerShell)
251
+ */
252
+ /** unpkg 上发布的包根路径(与 skillhub.md 安装说明一致) */
253
+ const UNPKG_PACKAGE_ROOT = "https://unpkg.com/skill-atlas-cli";
254
+ /** 用户可手动执行的命令行(文档 / 报错提示用) */
255
+ const OFFICIAL_INSTALL_CMD_UNIX = `curl -fsSL ${UNPKG_PACKAGE_ROOT}/install.sh | bash`;
256
+ const OFFICIAL_INSTALL_CMD_WIN = `irm ${UNPKG_PACKAGE_ROOT}/install.ps1 | iex`;
257
+ function officialInstallManualForPlatform() {
258
+ return process.platform === "win32" ? OFFICIAL_INSTALL_CMD_WIN : OFFICIAL_INSTALL_CMD_UNIX;
259
+ }
260
+ /** 执行 npm install -g <pkg>@latest(供 update 指令使用) */
261
+ function runNpmInstallGlobalLatest(pkgName) {
262
+ return new Promise((resolve) => {
263
+ const child = spawn("npm", [
264
+ "install",
265
+ "-g",
266
+ `${pkgName}@latest`,
267
+ "--force"
268
+ ], {
269
+ stdio: "inherit",
270
+ shell: true
271
+ });
272
+ child.on("close", (code) => resolve(code ?? 0));
273
+ child.on("error", () => resolve(1));
274
+ });
275
+ }
276
+ /**
277
+ * 执行官方安装脚本升级(与 skillhub:macOS/Linux 用 install.sh,Windows 用 install.ps1)
278
+ * 供非交互场景下 checkForUpdate 自动升级使用
279
+ */
280
+ function runOfficialInstallScriptUpdate() {
281
+ return new Promise((resolve) => {
282
+ const child = process.platform === "win32" ? spawn("powershell.exe", [
283
+ "-NoProfile",
284
+ "-ExecutionPolicy",
285
+ "Bypass",
286
+ "-Command",
287
+ OFFICIAL_INSTALL_CMD_WIN
288
+ ], {
289
+ stdio: "inherit",
290
+ windowsHide: true
291
+ }) : spawn("bash", ["-c", OFFICIAL_INSTALL_CMD_UNIX], { stdio: "inherit" });
292
+ child.on("close", (code) => resolve(code ?? 0));
293
+ child.on("error", () => resolve(1));
294
+ });
295
+ }
296
+ //#endregion
246
297
  //#region src/core/update-notifier.ts
247
298
  /**
248
- * npm 包更新检查:有新版本时提示无需重装,直接 npm update 即可
299
+ * npm 包更新检查:TTY 下提示任意新版本;非 TTY 下 minor 及以上通过官方 install 脚本更新,patch 仅 stderr 提示
249
300
  */
250
301
  const CACHE_DIR = config_default.CONFIG_DIR;
251
302
  const CACHE_FILE = join(CACHE_DIR, "update-check.json");
@@ -273,14 +324,23 @@ function saveCache(latest) {
273
324
  }) + "\n");
274
325
  } catch {}
275
326
  }
327
+ /** 从 current 升到 latest 是否为至少 minor 级别(含 major),纯 patch 不算 */
328
+ function isAtLeastMinorBump(current, latest) {
329
+ const diff = semver.diff(current, latest);
330
+ if (!diff) return false;
331
+ return diff === "major" || diff === "premajor" || diff === "minor" || diff === "preminor";
332
+ }
276
333
  /**
277
- * 检查更新,有新版本时输出提示(无需重装,直接 update)
334
+ * 检查更新:TTY 任意新版本提示;非交互下 minor+ 自动执行官方安装脚本升级,patch 仅一行提示
278
335
  */
279
- function checkForUpdate(pkg) {
336
+ async function checkForUpdate(pkg) {
280
337
  const cache = getCache();
281
- if (cache?.latest && semver.gt(cache.latest, pkg.version)) {
282
- if (process.stdout.isTTY) console.error(`\n 📦 Update available: \x1b[31m${pkg.version}\x1b[0m → \x1b[32m${cache.latest}\x1b[0m\n 👉 Run: \x1b[36mskill-atlas update\x1b[0m\n`);
283
- }
338
+ if (cache?.latest && semver.gt(cache.latest, pkg.version)) if (process.stdout.isTTY) console.error(`\n 📦 Update available: \x1b[31m${pkg.version}\x1b[0m → \x1b[32m${cache.latest}\x1b[0m\n 👉 Run: \x1b[36mskill-atlas update\x1b[0m\n`);
339
+ else if (isAtLeastMinorBump(pkg.version, cache.latest)) {
340
+ console.error(`[skill-atlas] 检测到 minor 及以上新版本 ${pkg.version} → ${cache.latest}(非交互环境),正在通过官方安装脚本更新…`);
341
+ const code = await runOfficialInstallScriptUpdate();
342
+ if (code !== 0) console.error(`[skill-atlas] 自动更新失败(退出码 ${code}),可手动执行: ${officialInstallManualForPlatform()}`);
343
+ } else console.error(`[skill-atlas] 检测到新版本 ${pkg.version} → ${cache.latest}(非 minor/major 升级,非交互环境不自动安装),可执行: ${officialInstallManualForPlatform()}`);
284
344
  const lastCheck = cache?.lastCheck || 0;
285
345
  if (Date.now() - lastCheck < CHECK_INTERVAL) return;
286
346
  fetchLatestVersion$1(pkg.name).then((latest) => {
@@ -1598,23 +1658,8 @@ async function fetchLatestVersion(pkgName) {
1598
1658
  if (!res.ok) throw new Error("获取最新版本失败");
1599
1659
  return (await res.json()).latest || "0.0.0";
1600
1660
  }
1601
- /** 执行 npm install -g <pkg>@latest */
1602
- function runNpmUpdate(pkgName) {
1603
- return new Promise((resolve) => {
1604
- const child = spawn("npm", [
1605
- "install",
1606
- "-g",
1607
- `${pkgName}@latest --force`
1608
- ], {
1609
- stdio: "inherit",
1610
- shell: true
1611
- });
1612
- child.on("close", (code) => resolve(code ?? 0));
1613
- child.on("error", () => resolve(1));
1614
- });
1615
- }
1616
1661
  async function runUpdate(options) {
1617
- const { pkgName, currentVersion, yes } = options;
1662
+ const { pkgName, currentVersion, yes, plugin } = options;
1618
1663
  const spinner = p.spinner();
1619
1664
  spinner.start("检查最新版本...");
1620
1665
  try {
@@ -1628,7 +1673,7 @@ async function runUpdate(options) {
1628
1673
  p.log.success(`已是最新版本 ${chalk.cyan(currentVersion)}`);
1629
1674
  return;
1630
1675
  }
1631
- p.log.message(`发现新版本: ${chalk.red(currentVersion)} → ${chalk.green(latest)}`);
1676
+ p.log.message(`发现新版本: ${chalk.red(currentVersion)} → ${chalk.green(latest)}` + (plugin ? chalk.dim("(将使用官方安装脚本更新 CLI 与插件)") : ""));
1632
1677
  const proceed = yes || !process.stdin.isTTY ? true : await p.confirm({
1633
1678
  message: "是否立即升级?",
1634
1679
  initialValue: true
@@ -1637,18 +1682,20 @@ async function runUpdate(options) {
1637
1682
  p.cancel("已取消升级");
1638
1683
  return;
1639
1684
  }
1640
- spinner.start("正在升级...");
1641
- const code = await runNpmUpdate(pkgName);
1685
+ spinner.start(plugin ? "正在通过官方脚本升级(CLI + 插件)…" : "正在升级...");
1686
+ const code = plugin ? await runOfficialInstallScriptUpdate() : await runNpmInstallGlobalLatest(pkgName);
1642
1687
  spinner.stop(code === 0 ? "升级完成" : "升级失败");
1643
1688
  if (code !== 0) {
1644
- logger_default.error("升级失败,可手动执行: npm install -g " + pkgName + "@latest");
1689
+ if (plugin) logger_default.error("升级失败,可手动执行: " + officialInstallManualForPlatform());
1690
+ else logger_default.error("升级失败,可手动执行: npm install -g " + pkgName + "@latest");
1645
1691
  process.exit(1);
1646
1692
  }
1647
- p.log.success(`已升级到 ${chalk.green(latest)}`);
1693
+ p.log.success(plugin ? `已通过官方脚本更新(目标版本 ${chalk.green(latest)})` : `已升级到 ${chalk.green(latest)}`);
1648
1694
  } catch (err) {
1649
1695
  spinner.stop("检查失败");
1650
1696
  p.log.error(err.message);
1651
- logger_default.info("可手动执行: npm install -g " + pkgName + "@latest");
1697
+ if (plugin) logger_default.info("可手动执行: " + officialInstallManualForPlatform());
1698
+ else logger_default.info("可手动执行: npm install -g " + pkgName + "@latest");
1652
1699
  process.exit(1);
1653
1700
  }
1654
1701
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skill-atlas-cli",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "skill-atlas CLI - 虾小宝 命令行工具",
5
5
  "homepage": "https://skillatlas.cn/",
6
6
  "type": "module",