skill-atlas-cli 0.1.23 → 0.1.25
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/lib/index.js +40 -17
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -313,7 +313,7 @@ var import_picocolors = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin((
|
|
|
313
313
|
async function get(apiPath, params = {}) {
|
|
314
314
|
const url = new URL(apiPath, config_default.getApiBase());
|
|
315
315
|
for (const [k, v] of Object.entries(params)) if (v !== void 0 && v !== null && v !== "") url.searchParams.set(k, String(v));
|
|
316
|
-
const res = await fetch(url.toString(), { headers: {
|
|
316
|
+
const res = await fetch(url.toString(), { headers: { "X-SkillAtlas-Agent-Id": config_default.getAgentId() } });
|
|
317
317
|
if (!res.ok) {
|
|
318
318
|
const body = await res.text().catch(() => "");
|
|
319
319
|
throw new Error(`API error ${res.status}: ${body || res.statusText}`);
|
|
@@ -953,6 +953,10 @@ ${asset.readme || ""}
|
|
|
953
953
|
}
|
|
954
954
|
//#endregion
|
|
955
955
|
//#region src/commands/install.ts
|
|
956
|
+
/** 非 TTY 环境(如 OpenClaw、CI、管道)下自动启用非交互模式,避免阻塞 */
|
|
957
|
+
function isNonInteractiveEnv() {
|
|
958
|
+
return !process.stdin.isTTY;
|
|
959
|
+
}
|
|
956
960
|
async function promptForAgents(message, choices, initialValues) {
|
|
957
961
|
return await searchMultiselect({
|
|
958
962
|
message,
|
|
@@ -980,8 +984,12 @@ function buildAgentChoices(globalInstall) {
|
|
|
980
984
|
function getDefaultAgents(choices) {
|
|
981
985
|
return ["claude-code", "openclaw"].filter((agent) => choices.some((choice) => choice.value === agent));
|
|
982
986
|
}
|
|
983
|
-
async function resolveSkillName(inputSkill) {
|
|
987
|
+
async function resolveSkillName(inputSkill, nonInteractive) {
|
|
984
988
|
if (inputSkill?.trim()) return inputSkill.trim();
|
|
989
|
+
if (nonInteractive) errorAndExit("Please provide skill name", {
|
|
990
|
+
title: "Usage",
|
|
991
|
+
body: "skill-atlas install <skillName>\n\nExample: skill-atlas install my-skill"
|
|
992
|
+
});
|
|
985
993
|
const input = await p.text({
|
|
986
994
|
message: "Enter skill to install",
|
|
987
995
|
placeholder: "my-skill",
|
|
@@ -992,9 +1000,9 @@ async function resolveSkillName(inputSkill) {
|
|
|
992
1000
|
if (p.isCancel(input)) cancelAndExit("Cancelled");
|
|
993
1001
|
return input.trim();
|
|
994
1002
|
}
|
|
995
|
-
async function resolveTargetAgents(options) {
|
|
996
|
-
const allAgentChoices = buildAgentChoices(Boolean(options.global ?? options.yes));
|
|
997
|
-
if (options.yes) {
|
|
1003
|
+
async function resolveTargetAgents(options, nonInteractive) {
|
|
1004
|
+
const allAgentChoices = buildAgentChoices(Boolean(options.global ?? options.yes ?? nonInteractive));
|
|
1005
|
+
if (options.yes || nonInteractive) {
|
|
998
1006
|
const defaults = getDefaultAgents(allAgentChoices);
|
|
999
1007
|
if (defaults.length === 0) cancelAndExit("No default agents available");
|
|
1000
1008
|
return defaults;
|
|
@@ -1003,9 +1011,9 @@ async function resolveTargetAgents(options) {
|
|
|
1003
1011
|
if (p.isCancel(selected) || selected.length === 0) cancelAndExit("Installation cancelled");
|
|
1004
1012
|
return selected;
|
|
1005
1013
|
}
|
|
1006
|
-
async function resolveInstallScope(options, targetAgents) {
|
|
1014
|
+
async function resolveInstallScope(options, targetAgents, nonInteractive) {
|
|
1007
1015
|
const supportsGlobal = targetAgents.some((agent) => agents[agent].globalSkillsDir !== void 0);
|
|
1008
|
-
if (options.global !== void 0 || options.yes || !supportsGlobal) return options.global ?? (options.yes ? true : false);
|
|
1016
|
+
if (options.global !== void 0 || options.yes || nonInteractive || !supportsGlobal) return options.global ?? (options.yes || nonInteractive ? true : false);
|
|
1009
1017
|
const scope = await p.select({
|
|
1010
1018
|
message: "Installation scope",
|
|
1011
1019
|
options: [{
|
|
@@ -1021,15 +1029,30 @@ async function resolveInstallScope(options, targetAgents) {
|
|
|
1021
1029
|
if (p.isCancel(scope)) cancelAndExit("Installation cancelled");
|
|
1022
1030
|
return scope;
|
|
1023
1031
|
}
|
|
1032
|
+
/** 非 TTY 下使用静态输出替代 spinner,避免动画帧被逐行打印造成刷屏 */
|
|
1033
|
+
function createProgressReporter(nonInteractive) {
|
|
1034
|
+
if (nonInteractive) return {
|
|
1035
|
+
start: (msg) => p.log.message(msg),
|
|
1036
|
+
stop: (msg) => {
|
|
1037
|
+
if (msg) p.log.message(msg);
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
const s = p.spinner();
|
|
1041
|
+
return {
|
|
1042
|
+
start: (msg) => s.start(msg),
|
|
1043
|
+
stop: (msg) => s.stop(msg ?? "")
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1024
1046
|
const run = async (args, options = {}) => {
|
|
1047
|
+
const nonInteractive = options.yes || isNonInteractiveEnv();
|
|
1025
1048
|
p.intro(chalk.bold("skill-atlas install"));
|
|
1026
|
-
const skill = await resolveSkillName(args[0]);
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1049
|
+
const skill = await resolveSkillName(args[0], nonInteractive);
|
|
1050
|
+
const progress = createProgressReporter(nonInteractive);
|
|
1051
|
+
progress.start(`Searching for ${chalk.bold(skill)}...`);
|
|
1029
1052
|
try {
|
|
1030
1053
|
const asset = await findAsset(skill);
|
|
1031
1054
|
if (!asset) {
|
|
1032
|
-
|
|
1055
|
+
progress.stop();
|
|
1033
1056
|
errorAndExit(`Not found: ${chalk.bold(skill)}`, {
|
|
1034
1057
|
title: "Suggest",
|
|
1035
1058
|
body: `Try: skill-atlas search ${skill}`
|
|
@@ -1037,12 +1060,12 @@ const run = async (args, options = {}) => {
|
|
|
1037
1060
|
}
|
|
1038
1061
|
const displayName = asset.displayName || asset.slug;
|
|
1039
1062
|
const version = asset.currentVersion.version ?? "0.0.0";
|
|
1040
|
-
|
|
1041
|
-
const targetAgents = await resolveTargetAgents(options);
|
|
1042
|
-
const installGlobally = await resolveInstallScope(options, targetAgents);
|
|
1063
|
+
progress.stop(`${chalk.bold(displayName)} ${chalk.dim(`v${version}`)}`);
|
|
1064
|
+
const targetAgents = await resolveTargetAgents(options, nonInteractive);
|
|
1065
|
+
const installGlobally = await resolveInstallScope(options, targetAgents, nonInteractive);
|
|
1043
1066
|
const selectedLabels = targetAgents.map((a) => agents[a].displayName);
|
|
1044
1067
|
p.log.message(chalk.green("Selected:") + " " + selectedLabels.join(", "));
|
|
1045
|
-
|
|
1068
|
+
progress.start("Installing skills...");
|
|
1046
1069
|
const installMode = options.copy ? "copy" : "symlink";
|
|
1047
1070
|
const installResults = [];
|
|
1048
1071
|
for (const agent of targetAgents) {
|
|
@@ -1056,13 +1079,13 @@ const run = async (args, options = {}) => {
|
|
|
1056
1079
|
path: result.path
|
|
1057
1080
|
});
|
|
1058
1081
|
}
|
|
1059
|
-
|
|
1082
|
+
progress.stop("Skills installed successfully");
|
|
1060
1083
|
const title = import_picocolors.default.green("Installed 1 skill");
|
|
1061
1084
|
const resultLines = installResults.map((r) => ` ${agents[r.agent].displayName}: ${r.path}`);
|
|
1062
1085
|
p.note(resultLines.join("\n"), title);
|
|
1063
1086
|
p.outro(import_picocolors.default.green("Done!") + import_picocolors.default.dim(" Skill ready. Review before use."));
|
|
1064
1087
|
} catch (err) {
|
|
1065
|
-
|
|
1088
|
+
progress.stop();
|
|
1066
1089
|
p.log.error(`Install failed: ${err.message}`);
|
|
1067
1090
|
process.exit(1);
|
|
1068
1091
|
}
|