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 +4 -3
- package/lib/index.d.ts +6 -2
- package/lib/index.js +76 -29
- package/package.json +1 -1
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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("升级失败,可手动执行:
|
|
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("可手动执行:
|
|
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
|
}
|