skild 0.10.21 → 0.11.0
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/README.md +10 -0
- package/dist/index.js +300 -118
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -113,6 +113,16 @@ skild install ./path/to/my-skill
|
|
|
113
113
|
| `--force` | Overwrite existing skill |
|
|
114
114
|
| `-y, --yes` | Skip confirmation prompts |
|
|
115
115
|
|
|
116
|
+
## 🔄 Update / Uninstall
|
|
117
|
+
|
|
118
|
+
If you do not pass `--target`, `skild update` and `skild uninstall` will prompt you to select target platforms (default: all). You can also choose scope:
|
|
119
|
+
|
|
120
|
+
| Option | Description |
|
|
121
|
+
|--------|-------------|
|
|
122
|
+
| `-t, --target <platform>` | Target platform |
|
|
123
|
+
| `-l, --local` | Target project-level scope |
|
|
124
|
+
| `-g, --global` | Target global scope |
|
|
125
|
+
|
|
116
126
|
## 🎯 Supported Platforms
|
|
117
127
|
|
|
118
128
|
| Platform | Global Path |
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
|
|
9
9
|
// src/index.ts
|
|
10
10
|
import { Command } from "commander";
|
|
11
|
-
import
|
|
11
|
+
import chalk20 from "chalk";
|
|
12
12
|
import { createRequire } from "module";
|
|
13
13
|
|
|
14
14
|
// src/commands/install.ts
|
|
@@ -103,6 +103,10 @@ var PLATFORM_DISPLAY = {
|
|
|
103
103
|
cursor: "Cursor",
|
|
104
104
|
windsurf: "Windsurf"
|
|
105
105
|
};
|
|
106
|
+
var SCOPE_DISPLAY = {
|
|
107
|
+
global: "Global (home)",
|
|
108
|
+
project: "Project (cwd)"
|
|
109
|
+
};
|
|
106
110
|
function createTreeNode(id, name, depth, isLeaf, leafIndices = []) {
|
|
107
111
|
return { id, name, depth, children: [], leafIndices, isLeaf };
|
|
108
112
|
}
|
|
@@ -187,6 +191,15 @@ function buildPlatformTree(items) {
|
|
|
187
191
|
}
|
|
188
192
|
return wrapWithRoot(allNode);
|
|
189
193
|
}
|
|
194
|
+
function buildScopeTree(items) {
|
|
195
|
+
const allNode = createTreeNode("all", "All Scopes", 1, false);
|
|
196
|
+
for (let i = 0; i < items.length; i++) {
|
|
197
|
+
const scope = items[i].scope;
|
|
198
|
+
allNode.children.push(createTreeNode(scope, scope, 2, true, [i]));
|
|
199
|
+
allNode.leafIndices.push(i);
|
|
200
|
+
}
|
|
201
|
+
return wrapWithRoot(allNode);
|
|
202
|
+
}
|
|
190
203
|
function buildSyncTree(choices) {
|
|
191
204
|
const root = createTreeNode("root", "All targets", 1, false);
|
|
192
205
|
const platforms = /* @__PURE__ */ new Map();
|
|
@@ -333,7 +346,7 @@ async function promptPlatformsInteractive(options = {}) {
|
|
|
333
346
|
const platforms = options.platforms && options.platforms.length > 0 ? options.platforms : PLATFORMS;
|
|
334
347
|
const platformItems = platforms.map((p) => ({ platform: p }));
|
|
335
348
|
const installedSet = new Set(options.installedPlatforms ?? []);
|
|
336
|
-
const defaultSelected = installedSet.size > 0 ? new Set(platforms.flatMap((p, idx) => installedSet.has(p) ? [idx] : [])) : void 0;
|
|
349
|
+
const defaultSelected = options.defaultAll === false && installedSet.size > 0 ? new Set(platforms.flatMap((p, idx) => installedSet.has(p) ? [idx] : [])) : void 0;
|
|
337
350
|
const selectedIndices = await interactiveTreeSelect(platformItems, {
|
|
338
351
|
title: "Select target platforms",
|
|
339
352
|
subtitle: "\u2191\u2193 navigate \u2022 Space toggle \u2022 Enter confirm",
|
|
@@ -361,6 +374,34 @@ async function promptPlatformsInteractive(options = {}) {
|
|
|
361
374
|
);
|
|
362
375
|
return selected;
|
|
363
376
|
}
|
|
377
|
+
async function promptScopesInteractive(options = {}) {
|
|
378
|
+
const scopes = options.scopes && options.scopes.length > 0 ? options.scopes : ["global", "project"];
|
|
379
|
+
const scopeItems = scopes.map((scope) => ({ scope }));
|
|
380
|
+
const selectedIndices = await interactiveTreeSelect(scopeItems, {
|
|
381
|
+
title: "Select target scopes",
|
|
382
|
+
subtitle: "\u2191\u2193 navigate \u2022 Space toggle \u2022 Enter confirm",
|
|
383
|
+
buildTree: buildScopeTree,
|
|
384
|
+
formatNode: (node, selection, isCursor, maxWidth) => {
|
|
385
|
+
const displayScope = node.name;
|
|
386
|
+
const displayName = node.name === "All Scopes" ? node.name : SCOPE_DISPLAY[displayScope] || node.name;
|
|
387
|
+
return formatTreeNode({ ...node, name: displayName }, selection, isCursor, maxWidth, {
|
|
388
|
+
hintText: buildSpaceHint(node, selection)
|
|
389
|
+
});
|
|
390
|
+
},
|
|
391
|
+
defaultAll: options.defaultAll !== false
|
|
392
|
+
});
|
|
393
|
+
if (!selectedIndices) return null;
|
|
394
|
+
const selected = selectedIndices.map((i) => scopes[i]);
|
|
395
|
+
const names = selected.map((scope) => SCOPE_DISPLAY[scope] || scope);
|
|
396
|
+
enqueuePostPromptLog(
|
|
397
|
+
chalk2.green(
|
|
398
|
+
`
|
|
399
|
+
\u2713 Selected ${selected.length} scope${selected.length > 1 ? "s" : ""}: ${chalk2.cyan(names.join(", "))}
|
|
400
|
+
`
|
|
401
|
+
)
|
|
402
|
+
);
|
|
403
|
+
return selected;
|
|
404
|
+
}
|
|
364
405
|
async function promptSyncTargetsInteractive(choices) {
|
|
365
406
|
if (choices.length === 0) return null;
|
|
366
407
|
const selectedIndices = await interactiveTreeSelect(choices, {
|
|
@@ -2080,55 +2121,196 @@ ${chalk6.cyan(displayName)}
|
|
|
2080
2121
|
}
|
|
2081
2122
|
|
|
2082
2123
|
// src/commands/uninstall.ts
|
|
2124
|
+
import chalk8 from "chalk";
|
|
2125
|
+
import {
|
|
2126
|
+
canonicalNameToInstallDirName as canonicalNameToInstallDirName2,
|
|
2127
|
+
uninstallSkill,
|
|
2128
|
+
SkildError as SkildError3
|
|
2129
|
+
} from "@skild/core";
|
|
2130
|
+
|
|
2131
|
+
// src/utils/target-selection.ts
|
|
2083
2132
|
import chalk7 from "chalk";
|
|
2084
|
-
import {
|
|
2133
|
+
import { listSkills as listSkills3, PLATFORMS as PLATFORMS4 } from "@skild/core";
|
|
2134
|
+
var ALL_SCOPES = ["global", "project"];
|
|
2135
|
+
function formatTargetLabel(platform, scope) {
|
|
2136
|
+
return `${platform} (${scope})`;
|
|
2137
|
+
}
|
|
2138
|
+
function formatTargetSummary(platforms, scopes) {
|
|
2139
|
+
const platformLabel = platforms.length === PLATFORMS4.length ? "all platforms" : platforms.length === 1 ? platforms[0] : `${platforms.length} platforms`;
|
|
2140
|
+
const scopeLabel = scopes.length === ALL_SCOPES.length ? "all scopes" : scopes.length === 1 ? scopes[0] : `${scopes.length} scopes`;
|
|
2141
|
+
return `${platformLabel}, ${scopeLabel}`;
|
|
2142
|
+
}
|
|
2143
|
+
function resolveScopeSelection(options, interactive) {
|
|
2144
|
+
const wantsLocal = Boolean(options.local);
|
|
2145
|
+
const wantsGlobal = Boolean(options.global);
|
|
2146
|
+
if (wantsLocal && wantsGlobal) return { scopes: [...ALL_SCOPES], needsPrompt: false };
|
|
2147
|
+
if (wantsLocal) return { scopes: ["project"], needsPrompt: false };
|
|
2148
|
+
if (wantsGlobal) return { scopes: ["global"], needsPrompt: false };
|
|
2149
|
+
if (!interactive) return { scopes: ["global"], needsPrompt: false };
|
|
2150
|
+
return { scopes: [...ALL_SCOPES], needsPrompt: true };
|
|
2151
|
+
}
|
|
2152
|
+
function resolvePlatformSelection(options, interactive) {
|
|
2153
|
+
if (options.target) return { platforms: [options.target], needsPrompt: false };
|
|
2154
|
+
if (!interactive) return { platforms: ["claude"], needsPrompt: false };
|
|
2155
|
+
return { platforms: [...PLATFORMS4], needsPrompt: true };
|
|
2156
|
+
}
|
|
2157
|
+
function listInstalledPlatforms(scopes) {
|
|
2158
|
+
const installed = [];
|
|
2159
|
+
for (const platform of PLATFORMS4) {
|
|
2160
|
+
for (const scope of scopes) {
|
|
2161
|
+
if (listSkills3({ platform, scope }).length > 0) {
|
|
2162
|
+
installed.push(platform);
|
|
2163
|
+
break;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
return installed;
|
|
2168
|
+
}
|
|
2169
|
+
async function resolveTargetSelection(options, interactive) {
|
|
2170
|
+
const scopeSelection = resolveScopeSelection(options, interactive);
|
|
2171
|
+
let scopes = scopeSelection.scopes;
|
|
2172
|
+
if (scopeSelection.needsPrompt) {
|
|
2173
|
+
const selectedScopes = await promptScopesInteractive({ defaultAll: true });
|
|
2174
|
+
if (!selectedScopes) {
|
|
2175
|
+
console.log(chalk7.red("No scopes selected."));
|
|
2176
|
+
process.exitCode = 1;
|
|
2177
|
+
return null;
|
|
2178
|
+
}
|
|
2179
|
+
scopes = selectedScopes;
|
|
2180
|
+
flushInteractiveUiNow();
|
|
2181
|
+
}
|
|
2182
|
+
const platformSelection = resolvePlatformSelection(options, interactive);
|
|
2183
|
+
let platforms = platformSelection.platforms;
|
|
2184
|
+
if (platformSelection.needsPrompt) {
|
|
2185
|
+
const installedPlatforms = listInstalledPlatforms(scopes);
|
|
2186
|
+
const selectedPlatforms = await promptPlatformsInteractive({
|
|
2187
|
+
defaultAll: true,
|
|
2188
|
+
platforms: [...PLATFORMS4],
|
|
2189
|
+
installedPlatforms
|
|
2190
|
+
});
|
|
2191
|
+
if (!selectedPlatforms) {
|
|
2192
|
+
console.log(chalk7.red("No platforms selected."));
|
|
2193
|
+
process.exitCode = 1;
|
|
2194
|
+
return null;
|
|
2195
|
+
}
|
|
2196
|
+
platforms = selectedPlatforms;
|
|
2197
|
+
flushInteractiveUiNow();
|
|
2198
|
+
}
|
|
2199
|
+
return { platforms, scopes };
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
// src/commands/uninstall.ts
|
|
2085
2203
|
async function uninstall(skill, options = {}) {
|
|
2086
|
-
const platform = options.target || "claude";
|
|
2087
|
-
const scope = options.local ? "project" : "global";
|
|
2088
2204
|
const canonical = skill.trim();
|
|
2089
2205
|
const resolvedName = canonical.startsWith("@") && canonical.includes("/") ? canonicalNameToInstallDirName2(canonical) : canonical;
|
|
2090
|
-
const
|
|
2206
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2207
|
+
const selection = await resolveTargetSelection(options, interactive);
|
|
2208
|
+
if (!selection) return;
|
|
2209
|
+
const { platforms, scopes } = selection;
|
|
2210
|
+
const spinner = createSpinner(`Uninstalling ${chalk8.cyan(canonical)}...`);
|
|
2211
|
+
const errors = [];
|
|
2091
2212
|
try {
|
|
2092
|
-
|
|
2093
|
-
platform
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2213
|
+
for (const scope of scopes) {
|
|
2214
|
+
for (const platform of platforms) {
|
|
2215
|
+
spinner.text = `Uninstalling ${chalk8.cyan(canonical)} from ${chalk8.dim(platform)} (${scope})...`;
|
|
2216
|
+
try {
|
|
2217
|
+
uninstallSkill(resolvedName, {
|
|
2218
|
+
platform,
|
|
2219
|
+
scope,
|
|
2220
|
+
allowMissingMetadata: Boolean(options.force),
|
|
2221
|
+
withDeps: Boolean(options.withDeps)
|
|
2222
|
+
});
|
|
2223
|
+
} catch (error) {
|
|
2224
|
+
const message = error instanceof SkildError3 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2225
|
+
errors.push({ platform, scope, error: message });
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
const targetSummary = formatTargetSummary(platforms, scopes);
|
|
2230
|
+
if (errors.length === 0) {
|
|
2231
|
+
spinner.succeed(`Uninstalled ${chalk8.green(canonical)} \u2192 ${chalk8.dim(targetSummary)}.`);
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
spinner.fail(`Uninstalled ${chalk8.green(canonical)} with ${chalk8.red(errors.length.toString())} error(s) \u2192 ${chalk8.dim(targetSummary)}.`);
|
|
2235
|
+
console.log(chalk8.red("\n Errors:"));
|
|
2236
|
+
for (const entry of errors.slice(0, 10)) {
|
|
2237
|
+
console.log(chalk8.red(` \u2717 ${formatTargetLabel(entry.platform, entry.scope)}: ${entry.error}`));
|
|
2238
|
+
}
|
|
2239
|
+
if (errors.length > 10) {
|
|
2240
|
+
console.log(chalk8.dim(` ... and ${errors.length - 10} more errors`));
|
|
2241
|
+
}
|
|
2242
|
+
process.exitCode = 1;
|
|
2099
2243
|
} catch (error) {
|
|
2100
|
-
spinner.fail(`Failed to uninstall ${
|
|
2244
|
+
spinner.fail(`Failed to uninstall ${chalk8.red(canonical)}`);
|
|
2101
2245
|
const message = error instanceof SkildError3 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2102
|
-
console.error(
|
|
2246
|
+
console.error(chalk8.red(message));
|
|
2103
2247
|
process.exitCode = 1;
|
|
2104
2248
|
}
|
|
2105
2249
|
}
|
|
2106
2250
|
|
|
2107
2251
|
// src/commands/update.ts
|
|
2108
|
-
import
|
|
2109
|
-
import {
|
|
2252
|
+
import chalk9 from "chalk";
|
|
2253
|
+
import {
|
|
2254
|
+
canonicalNameToInstallDirName as canonicalNameToInstallDirName3,
|
|
2255
|
+
updateSkill,
|
|
2256
|
+
SkildError as SkildError4
|
|
2257
|
+
} from "@skild/core";
|
|
2110
2258
|
async function update(skill, options = {}) {
|
|
2111
|
-
const platform = options.target || "claude";
|
|
2112
|
-
const scope = options.local ? "project" : "global";
|
|
2113
2259
|
const label = skill ? skill : "all skills";
|
|
2114
2260
|
const resolvedName = skill && skill.trim().startsWith("@") && skill.includes("/") ? canonicalNameToInstallDirName3(skill.trim()) : skill;
|
|
2115
|
-
const
|
|
2261
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !options.json;
|
|
2262
|
+
const selection = await resolveTargetSelection(options, interactive);
|
|
2263
|
+
if (!selection) return;
|
|
2264
|
+
const { platforms, scopes } = selection;
|
|
2265
|
+
const spinner = createSpinner(`Updating ${chalk9.cyan(label)}...`);
|
|
2266
|
+
const results = [];
|
|
2267
|
+
const errors = [];
|
|
2116
2268
|
try {
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2269
|
+
for (const scope of scopes) {
|
|
2270
|
+
for (const platform of platforms) {
|
|
2271
|
+
spinner.text = `Updating ${chalk9.cyan(label)} on ${chalk9.dim(platform)} (${scope})...`;
|
|
2272
|
+
try {
|
|
2273
|
+
const updated = await updateSkill(resolvedName, { platform, scope });
|
|
2274
|
+
results.push(...updated);
|
|
2275
|
+
} catch (error) {
|
|
2276
|
+
const message = error instanceof SkildError4 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2277
|
+
errors.push({ platform, scope, error: message });
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2119
2281
|
if (options.json) {
|
|
2120
|
-
|
|
2282
|
+
if (errors.length === 0 && platforms.length === 1 && scopes.length === 1) {
|
|
2283
|
+
console.log(JSON.stringify(results, null, 2));
|
|
2284
|
+
} else {
|
|
2285
|
+
console.log(JSON.stringify({ ok: errors.length === 0, platforms, scopes, results, errors }, null, 2));
|
|
2286
|
+
}
|
|
2287
|
+
process.exitCode = errors.length ? 1 : 0;
|
|
2288
|
+
return;
|
|
2289
|
+
}
|
|
2290
|
+
const targetSummary = formatTargetSummary(platforms, scopes);
|
|
2291
|
+
if (errors.length === 0) {
|
|
2292
|
+
spinner.succeed(`Updated ${chalk9.green(results.length.toString())} skill(s) \u2192 ${chalk9.dim(targetSummary)}.`);
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
spinner.fail(`Updated ${chalk9.green(results.length.toString())} skill(s) with ${chalk9.red(errors.length.toString())} error(s) \u2192 ${chalk9.dim(targetSummary)}.`);
|
|
2296
|
+
console.log(chalk9.red("\n Errors:"));
|
|
2297
|
+
for (const entry of errors.slice(0, 10)) {
|
|
2298
|
+
console.log(chalk9.red(` \u2717 ${formatTargetLabel(entry.platform, entry.scope)}: ${entry.error}`));
|
|
2299
|
+
}
|
|
2300
|
+
if (errors.length > 10) {
|
|
2301
|
+
console.log(chalk9.dim(` ... and ${errors.length - 10} more errors`));
|
|
2121
2302
|
}
|
|
2303
|
+
process.exitCode = 1;
|
|
2122
2304
|
} catch (error) {
|
|
2123
|
-
spinner.fail(`Failed to update ${
|
|
2305
|
+
spinner.fail(`Failed to update ${chalk9.red(label)}`);
|
|
2124
2306
|
const message = error instanceof SkildError4 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2125
|
-
console.error(
|
|
2307
|
+
console.error(chalk9.red(message));
|
|
2126
2308
|
process.exitCode = 1;
|
|
2127
2309
|
}
|
|
2128
2310
|
}
|
|
2129
2311
|
|
|
2130
2312
|
// src/commands/validate.ts
|
|
2131
|
-
import
|
|
2313
|
+
import chalk10 from "chalk";
|
|
2132
2314
|
import { canonicalNameToInstallDirName as canonicalNameToInstallDirName4, validateSkill } from "@skild/core";
|
|
2133
2315
|
async function validate(target, options = {}) {
|
|
2134
2316
|
const platform = options.target || "claude";
|
|
@@ -2142,41 +2324,41 @@ async function validate(target, options = {}) {
|
|
|
2142
2324
|
return;
|
|
2143
2325
|
}
|
|
2144
2326
|
if (result.ok) {
|
|
2145
|
-
console.log(
|
|
2146
|
-
if (result.frontmatter?.name) console.log(
|
|
2327
|
+
console.log(chalk10.green("\u2713"), "Valid skill");
|
|
2328
|
+
if (result.frontmatter?.name) console.log(chalk10.dim(` name: ${result.frontmatter.name}`));
|
|
2147
2329
|
return;
|
|
2148
2330
|
}
|
|
2149
|
-
console.error(
|
|
2331
|
+
console.error(chalk10.red("\u2717"), "Invalid skill");
|
|
2150
2332
|
for (const issue of result.issues) {
|
|
2151
|
-
const color = issue.level === "error" ?
|
|
2333
|
+
const color = issue.level === "error" ? chalk10.red : chalk10.yellow;
|
|
2152
2334
|
console.error(` - ${color(issue.level)}: ${issue.message}`);
|
|
2153
2335
|
}
|
|
2154
2336
|
process.exitCode = 1;
|
|
2155
2337
|
}
|
|
2156
2338
|
|
|
2157
2339
|
// src/commands/init.ts
|
|
2158
|
-
import
|
|
2340
|
+
import chalk11 from "chalk";
|
|
2159
2341
|
import { initSkill, SkildError as SkildError5 } from "@skild/core";
|
|
2160
2342
|
async function init(name, options = {}) {
|
|
2161
|
-
const spinner = createSpinner(`Initializing ${
|
|
2343
|
+
const spinner = createSpinner(`Initializing ${chalk11.cyan(name)}...`);
|
|
2162
2344
|
try {
|
|
2163
2345
|
const createdDir = initSkill(name, {
|
|
2164
2346
|
dir: options.dir,
|
|
2165
2347
|
description: options.description,
|
|
2166
2348
|
force: Boolean(options.force)
|
|
2167
2349
|
});
|
|
2168
|
-
spinner.succeed(`Created ${
|
|
2169
|
-
console.log(
|
|
2350
|
+
spinner.succeed(`Created ${chalk11.green(name)} at ${chalk11.dim(createdDir)}`);
|
|
2351
|
+
console.log(chalk11.dim(`Next: cd ${createdDir} && skild validate .`));
|
|
2170
2352
|
} catch (error) {
|
|
2171
|
-
spinner.fail(`Failed to init ${
|
|
2353
|
+
spinner.fail(`Failed to init ${chalk11.red(name)}`);
|
|
2172
2354
|
const message = error instanceof SkildError5 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2173
|
-
console.error(
|
|
2355
|
+
console.error(chalk11.red(message));
|
|
2174
2356
|
process.exitCode = 1;
|
|
2175
2357
|
}
|
|
2176
2358
|
}
|
|
2177
2359
|
|
|
2178
2360
|
// src/commands/signup.ts
|
|
2179
|
-
import
|
|
2361
|
+
import chalk12 from "chalk";
|
|
2180
2362
|
import { fetchWithTimeout as fetchWithTimeout3, resolveRegistryUrl as resolveRegistryUrl2, SkildError as SkildError6 } from "@skild/core";
|
|
2181
2363
|
|
|
2182
2364
|
// src/utils/prompt.ts
|
|
@@ -2245,7 +2427,7 @@ async function signup(options) {
|
|
|
2245
2427
|
const handle = options.handle?.trim() || "";
|
|
2246
2428
|
const password = options.password || "";
|
|
2247
2429
|
if ((!email || !handle || !password) && (!interactive || options.json)) {
|
|
2248
|
-
console.error(
|
|
2430
|
+
console.error(chalk12.red("Missing signup fields. Use --email/--handle/--password, or run `skild signup` interactively."));
|
|
2249
2431
|
process.exitCode = 1;
|
|
2250
2432
|
return;
|
|
2251
2433
|
}
|
|
@@ -2280,13 +2462,13 @@ async function signup(options) {
|
|
|
2280
2462
|
);
|
|
2281
2463
|
text = await res.text();
|
|
2282
2464
|
if (!res.ok) {
|
|
2283
|
-
console.error(
|
|
2465
|
+
console.error(chalk12.red(`Signup failed (${res.status}): ${text}`));
|
|
2284
2466
|
process.exitCode = 1;
|
|
2285
2467
|
return;
|
|
2286
2468
|
}
|
|
2287
2469
|
} catch (error) {
|
|
2288
2470
|
const message = error instanceof SkildError6 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2289
|
-
console.error(
|
|
2471
|
+
console.error(chalk12.red(`Signup failed: ${message}`));
|
|
2290
2472
|
process.exitCode = 1;
|
|
2291
2473
|
return;
|
|
2292
2474
|
}
|
|
@@ -2294,29 +2476,29 @@ async function signup(options) {
|
|
|
2294
2476
|
console.log(text || JSON.stringify({ ok: true }, null, 2));
|
|
2295
2477
|
return;
|
|
2296
2478
|
}
|
|
2297
|
-
console.log(
|
|
2479
|
+
console.log(chalk12.green("Signup successful."));
|
|
2298
2480
|
try {
|
|
2299
2481
|
const parsed = JSON.parse(text);
|
|
2300
2482
|
if (parsed.verification?.requiredForPublish) {
|
|
2301
2483
|
if (parsed.verification.mode === "log") {
|
|
2302
|
-
console.log(
|
|
2484
|
+
console.log(chalk12.dim("Dev mode: email sending is disabled. Check the registry dev logs for the verification link."));
|
|
2303
2485
|
} else if (parsed.verification.sent) {
|
|
2304
|
-
console.log(
|
|
2486
|
+
console.log(chalk12.dim("Verification email sent. Check your inbox (and spam)."));
|
|
2305
2487
|
} else {
|
|
2306
|
-
console.log(
|
|
2488
|
+
console.log(chalk12.yellow("Verification email was not sent. You may need to resend from the Skild Hub."));
|
|
2307
2489
|
}
|
|
2308
|
-
console.log(
|
|
2490
|
+
console.log(chalk12.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
|
|
2309
2491
|
} else if (parsed.verification) {
|
|
2310
|
-
console.log(
|
|
2311
|
-
console.log(
|
|
2492
|
+
console.log(chalk12.dim("Email verification is recommended. Publishing may be restricted in the future."));
|
|
2493
|
+
console.log(chalk12.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
|
|
2312
2494
|
}
|
|
2313
2495
|
} catch {
|
|
2314
2496
|
}
|
|
2315
|
-
console.log(
|
|
2497
|
+
console.log(chalk12.dim("Next: run `skild login`"));
|
|
2316
2498
|
}
|
|
2317
2499
|
|
|
2318
2500
|
// src/commands/login.ts
|
|
2319
|
-
import
|
|
2501
|
+
import chalk13 from "chalk";
|
|
2320
2502
|
import { fetchWithTimeout as fetchWithTimeout4, resolveRegistryUrl as resolveRegistryUrl3, saveRegistryAuth, SkildError as SkildError7 } from "@skild/core";
|
|
2321
2503
|
async function login(options) {
|
|
2322
2504
|
const registry = resolveRegistryUrl3(options.registry);
|
|
@@ -2324,7 +2506,7 @@ async function login(options) {
|
|
|
2324
2506
|
const handleOrEmail = options.handleOrEmail?.trim() || "";
|
|
2325
2507
|
const password = options.password || "";
|
|
2326
2508
|
if ((!handleOrEmail || !password) && (!interactive || options.json)) {
|
|
2327
|
-
console.error(
|
|
2509
|
+
console.error(chalk13.red("Missing credentials. Use --handle-or-email and --password, or run `skild login` interactively."));
|
|
2328
2510
|
process.exitCode = 1;
|
|
2329
2511
|
return;
|
|
2330
2512
|
}
|
|
@@ -2359,13 +2541,13 @@ async function login(options) {
|
|
|
2359
2541
|
);
|
|
2360
2542
|
text = await res.text();
|
|
2361
2543
|
if (!res.ok) {
|
|
2362
|
-
console.error(
|
|
2544
|
+
console.error(chalk13.red(`Login failed (${res.status}): ${text}`));
|
|
2363
2545
|
process.exitCode = 1;
|
|
2364
2546
|
return;
|
|
2365
2547
|
}
|
|
2366
2548
|
} catch (error) {
|
|
2367
2549
|
const message = error instanceof SkildError7 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2368
|
-
console.error(
|
|
2550
|
+
console.error(chalk13.red(`Login failed: ${message}`));
|
|
2369
2551
|
process.exitCode = 1;
|
|
2370
2552
|
return;
|
|
2371
2553
|
}
|
|
@@ -2381,28 +2563,28 @@ async function login(options) {
|
|
|
2381
2563
|
console.log(JSON.stringify({ ok: true, publisher: json.publisher }, null, 2));
|
|
2382
2564
|
return;
|
|
2383
2565
|
}
|
|
2384
|
-
console.log(
|
|
2566
|
+
console.log(chalk13.green(`Logged in as ${chalk13.cyan(json.publisher.handle)}.`));
|
|
2385
2567
|
if (json.publisher.emailVerified === false) {
|
|
2386
|
-
console.log(
|
|
2387
|
-
console.log(
|
|
2568
|
+
console.log(chalk13.yellow("Email not verified. Publishing may be restricted by server policy."));
|
|
2569
|
+
console.log(chalk13.dim("Open the Skild Hub to verify: https://hub.skild.sh/verify-email/request"));
|
|
2388
2570
|
}
|
|
2389
2571
|
}
|
|
2390
2572
|
|
|
2391
2573
|
// src/commands/logout.ts
|
|
2392
|
-
import
|
|
2574
|
+
import chalk14 from "chalk";
|
|
2393
2575
|
import { clearRegistryAuth } from "@skild/core";
|
|
2394
2576
|
async function logout() {
|
|
2395
2577
|
clearRegistryAuth();
|
|
2396
|
-
console.log(
|
|
2578
|
+
console.log(chalk14.green("Logged out."));
|
|
2397
2579
|
}
|
|
2398
2580
|
|
|
2399
2581
|
// src/commands/whoami.ts
|
|
2400
|
-
import
|
|
2582
|
+
import chalk15 from "chalk";
|
|
2401
2583
|
import { fetchWithTimeout as fetchWithTimeout5, loadRegistryAuth as loadRegistryAuth2, resolveRegistryUrl as resolveRegistryUrl4, SkildError as SkildError8 } from "@skild/core";
|
|
2402
2584
|
async function whoami() {
|
|
2403
2585
|
const auth = loadRegistryAuth2();
|
|
2404
2586
|
if (!auth) {
|
|
2405
|
-
console.error(
|
|
2587
|
+
console.error(chalk15.red("Not logged in. Run `skild login` first."));
|
|
2406
2588
|
process.exitCode = 1;
|
|
2407
2589
|
return;
|
|
2408
2590
|
}
|
|
@@ -2415,16 +2597,16 @@ async function whoami() {
|
|
|
2415
2597
|
);
|
|
2416
2598
|
const text = await res.text();
|
|
2417
2599
|
if (!res.ok) {
|
|
2418
|
-
console.error(
|
|
2600
|
+
console.error(chalk15.red(`whoami failed (${res.status}): ${text}`));
|
|
2419
2601
|
process.exitCode = 1;
|
|
2420
2602
|
return;
|
|
2421
2603
|
}
|
|
2422
2604
|
const json = JSON.parse(text);
|
|
2423
|
-
console.log(
|
|
2605
|
+
console.log(chalk15.cyan(json.publisher.handle));
|
|
2424
2606
|
} catch (error) {
|
|
2425
2607
|
const message = error instanceof SkildError8 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2426
|
-
console.error(
|
|
2427
|
-
console.error(
|
|
2608
|
+
console.error(chalk15.red(`whoami failed: ${message}`));
|
|
2609
|
+
console.error(chalk15.dim("Tip: if you previously logged into a local registry, run `skild logout` then `skild login`."));
|
|
2428
2610
|
process.exitCode = 1;
|
|
2429
2611
|
}
|
|
2430
2612
|
}
|
|
@@ -2435,7 +2617,7 @@ import os from "os";
|
|
|
2435
2617
|
import path4 from "path";
|
|
2436
2618
|
import crypto from "crypto";
|
|
2437
2619
|
import * as tar from "tar";
|
|
2438
|
-
import
|
|
2620
|
+
import chalk16 from "chalk";
|
|
2439
2621
|
import { assertValidAlias, fetchWithTimeout as fetchWithTimeout6, loadRegistryAuth as loadRegistryAuth3, normalizeAlias, resolveRegistryUrl as resolveRegistryUrl5, SkildError as SkildError9, splitCanonicalName, validateSkillDir } from "@skild/core";
|
|
2440
2622
|
function sha256Hex(buf) {
|
|
2441
2623
|
const h = crypto.createHash("sha256");
|
|
@@ -2451,15 +2633,15 @@ async function publish(options = {}) {
|
|
|
2451
2633
|
const registry = resolveRegistryUrl5(options.registry || auth?.registryUrl);
|
|
2452
2634
|
const token = auth?.token;
|
|
2453
2635
|
if (!token) {
|
|
2454
|
-
console.error(
|
|
2636
|
+
console.error(chalk16.red("Not logged in. Run `skild login` first."));
|
|
2455
2637
|
process.exitCode = 1;
|
|
2456
2638
|
return;
|
|
2457
2639
|
}
|
|
2458
2640
|
const dir = path4.resolve(options.dir || process.cwd());
|
|
2459
2641
|
const validation = validateSkillDir(dir);
|
|
2460
2642
|
if (!validation.ok) {
|
|
2461
|
-
console.error(
|
|
2462
|
-
for (const issue of validation.issues) console.error(
|
|
2643
|
+
console.error(chalk16.red("Skill validation failed:"));
|
|
2644
|
+
for (const issue of validation.issues) console.error(chalk16.red(`- ${issue.message}`));
|
|
2463
2645
|
process.exitCode = 1;
|
|
2464
2646
|
return;
|
|
2465
2647
|
}
|
|
@@ -2473,14 +2655,14 @@ async function publish(options = {}) {
|
|
|
2473
2655
|
const skillset = fm.skillset === true;
|
|
2474
2656
|
const dependencies = Array.isArray(fm.dependencies) ? fm.dependencies : [];
|
|
2475
2657
|
if (!name) {
|
|
2476
|
-
console.error(
|
|
2658
|
+
console.error(chalk16.red("Missing name. Provide SKILL.md frontmatter.name or --name."));
|
|
2477
2659
|
process.exitCode = 1;
|
|
2478
2660
|
return;
|
|
2479
2661
|
}
|
|
2480
2662
|
if (!name.startsWith("@")) {
|
|
2481
2663
|
const seg = name.trim();
|
|
2482
2664
|
if (!/^[a-z0-9][a-z0-9-]{1,63}$/.test(seg)) {
|
|
2483
|
-
console.error(
|
|
2665
|
+
console.error(chalk16.red("Invalid name. Use @publisher/skill or a simple skill name (lowercase letters/digits/dashes)."));
|
|
2484
2666
|
process.exitCode = 1;
|
|
2485
2667
|
return;
|
|
2486
2668
|
}
|
|
@@ -2491,26 +2673,26 @@ async function publish(options = {}) {
|
|
|
2491
2673
|
);
|
|
2492
2674
|
const meText = await meRes.text();
|
|
2493
2675
|
if (!meRes.ok) {
|
|
2494
|
-
console.error(
|
|
2676
|
+
console.error(chalk16.red(`Failed to infer publisher scope (${meRes.status}): ${meText}`));
|
|
2495
2677
|
process.exitCode = 1;
|
|
2496
2678
|
return;
|
|
2497
2679
|
}
|
|
2498
2680
|
const meJson = JSON.parse(meText);
|
|
2499
2681
|
const handle = String(meJson?.publisher?.handle || "").trim().toLowerCase();
|
|
2500
2682
|
if (!handle) {
|
|
2501
|
-
console.error(
|
|
2683
|
+
console.error(chalk16.red("Failed to infer publisher scope from registry response."));
|
|
2502
2684
|
process.exitCode = 1;
|
|
2503
2685
|
return;
|
|
2504
2686
|
}
|
|
2505
2687
|
name = `@${handle}/${seg}`;
|
|
2506
2688
|
}
|
|
2507
2689
|
if (!/^@[a-z0-9][a-z0-9-]{1,31}\/[a-z0-9][a-z0-9-]{1,63}$/.test(name)) {
|
|
2508
|
-
console.error(
|
|
2690
|
+
console.error(chalk16.red("Invalid publish name. Expected @publisher/skill (lowercase letters/digits/dashes)."));
|
|
2509
2691
|
process.exitCode = 1;
|
|
2510
2692
|
return;
|
|
2511
2693
|
}
|
|
2512
2694
|
if (!version2) {
|
|
2513
|
-
console.error(
|
|
2695
|
+
console.error(chalk16.red("Missing version. Provide semver like 1.2.3 via SKILL.md frontmatter or --skill-version."));
|
|
2514
2696
|
process.exitCode = 1;
|
|
2515
2697
|
return;
|
|
2516
2698
|
}
|
|
@@ -2519,12 +2701,12 @@ async function publish(options = {}) {
|
|
|
2519
2701
|
assertValidAlias(alias);
|
|
2520
2702
|
} catch (error) {
|
|
2521
2703
|
const message = error instanceof SkildError9 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2522
|
-
console.error(
|
|
2704
|
+
console.error(chalk16.red(message));
|
|
2523
2705
|
process.exitCode = 1;
|
|
2524
2706
|
return;
|
|
2525
2707
|
}
|
|
2526
2708
|
}
|
|
2527
|
-
const spinner = createSpinner(`Publishing ${
|
|
2709
|
+
const spinner = createSpinner(`Publishing ${chalk16.cyan(`${name}@${version2}`)} to ${chalk16.dim(registry)}...`);
|
|
2528
2710
|
const tempDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "skild-publish-"));
|
|
2529
2711
|
const tarballPath = path4.join(tempDir, "skill.tgz");
|
|
2530
2712
|
try {
|
|
@@ -2561,12 +2743,12 @@ async function publish(options = {}) {
|
|
|
2561
2743
|
const text = await res.text();
|
|
2562
2744
|
if (!res.ok) {
|
|
2563
2745
|
spinner.fail(`Publish failed (${res.status})`);
|
|
2564
|
-
console.error(
|
|
2746
|
+
console.error(chalk16.red(text));
|
|
2565
2747
|
process.exitCode = 1;
|
|
2566
2748
|
return;
|
|
2567
2749
|
}
|
|
2568
2750
|
if (alias) {
|
|
2569
|
-
spinner.text = `Publishing ${
|
|
2751
|
+
spinner.text = `Publishing ${chalk16.cyan(`${name}@${version2}`)} \u2014 setting alias ${chalk16.cyan(alias)}...`;
|
|
2570
2752
|
const aliasRes = await fetchWithTimeout6(
|
|
2571
2753
|
`${registry}/publisher/skills/${encodeURIComponent(scope)}/${encodeURIComponent(skillName)}/alias`,
|
|
2572
2754
|
{
|
|
@@ -2582,7 +2764,7 @@ async function publish(options = {}) {
|
|
|
2582
2764
|
const aliasText = await aliasRes.text();
|
|
2583
2765
|
if (!aliasRes.ok) {
|
|
2584
2766
|
spinner.fail(`Failed to set alias (${aliasRes.status})`);
|
|
2585
|
-
console.error(
|
|
2767
|
+
console.error(chalk16.red(aliasText));
|
|
2586
2768
|
process.exitCode = 1;
|
|
2587
2769
|
return;
|
|
2588
2770
|
}
|
|
@@ -2591,18 +2773,18 @@ async function publish(options = {}) {
|
|
|
2591
2773
|
console.log(text);
|
|
2592
2774
|
return;
|
|
2593
2775
|
}
|
|
2594
|
-
const suffix = alias ? ` (alias: ${
|
|
2595
|
-
spinner.succeed(`Published ${
|
|
2776
|
+
const suffix = alias ? ` (alias: ${chalk16.cyan(alias)})` : "";
|
|
2777
|
+
spinner.succeed(`Published ${chalk16.green(`${name}@${version2}`)}${suffix} (sha256:${integrity.slice(0, 12)}\u2026)`);
|
|
2596
2778
|
try {
|
|
2597
2779
|
const parsed = JSON.parse(text);
|
|
2598
2780
|
const warnings = Array.isArray(parsed.warnings) ? parsed.warnings.map(String).filter(Boolean) : [];
|
|
2599
|
-
for (const w of warnings) console.warn(
|
|
2781
|
+
for (const w of warnings) console.warn(chalk16.yellow(`Warning: ${w}`));
|
|
2600
2782
|
} catch {
|
|
2601
2783
|
}
|
|
2602
2784
|
} catch (error) {
|
|
2603
2785
|
spinner.fail("Publish failed");
|
|
2604
2786
|
const message = error instanceof SkildError9 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2605
|
-
console.error(
|
|
2787
|
+
console.error(chalk16.red(message));
|
|
2606
2788
|
process.exitCode = 1;
|
|
2607
2789
|
} finally {
|
|
2608
2790
|
fs4.rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -2610,7 +2792,7 @@ async function publish(options = {}) {
|
|
|
2610
2792
|
}
|
|
2611
2793
|
|
|
2612
2794
|
// src/commands/search.ts
|
|
2613
|
-
import
|
|
2795
|
+
import chalk17 from "chalk";
|
|
2614
2796
|
import { resolveRegistryUrl as resolveRegistryUrl6, searchRegistrySkills, SkildError as SkildError10 } from "@skild/core";
|
|
2615
2797
|
async function search(query, options = {}) {
|
|
2616
2798
|
const registryUrl = resolveRegistryUrl6(options.registry);
|
|
@@ -2622,21 +2804,21 @@ async function search(query, options = {}) {
|
|
|
2622
2804
|
return;
|
|
2623
2805
|
}
|
|
2624
2806
|
if (!skills.length) {
|
|
2625
|
-
console.log(
|
|
2807
|
+
console.log(chalk17.dim("No results."));
|
|
2626
2808
|
return;
|
|
2627
2809
|
}
|
|
2628
|
-
console.log(
|
|
2629
|
-
\u{1F50E} Results (${skills.length}) \u2014 ${
|
|
2810
|
+
console.log(chalk17.bold(`
|
|
2811
|
+
\u{1F50E} Results (${skills.length}) \u2014 ${chalk17.dim(registryUrl)}
|
|
2630
2812
|
`));
|
|
2631
2813
|
for (const s of skills) {
|
|
2632
2814
|
const name = String(s.name || "").trim();
|
|
2633
2815
|
const desc = String(s.description || "").trim();
|
|
2634
2816
|
if (!name) continue;
|
|
2635
|
-
console.log(` ${
|
|
2817
|
+
console.log(` ${chalk17.cyan(name)}${desc ? chalk17.dim(` \u2014 ${desc}`) : ""}`);
|
|
2636
2818
|
}
|
|
2637
2819
|
} catch (error) {
|
|
2638
2820
|
const message = error instanceof SkildError10 ? error.message : error instanceof Error ? error.message : String(error);
|
|
2639
|
-
console.error(
|
|
2821
|
+
console.error(chalk17.red(message));
|
|
2640
2822
|
process.exitCode = 1;
|
|
2641
2823
|
}
|
|
2642
2824
|
}
|
|
@@ -2645,7 +2827,7 @@ async function search(query, options = {}) {
|
|
|
2645
2827
|
import fs5 from "fs";
|
|
2646
2828
|
import path5 from "path";
|
|
2647
2829
|
import os2 from "os";
|
|
2648
|
-
import
|
|
2830
|
+
import chalk18 from "chalk";
|
|
2649
2831
|
import {
|
|
2650
2832
|
deriveChildSource as deriveChildSource3,
|
|
2651
2833
|
materializeSourceToTemp as materializeSourceToTemp3,
|
|
@@ -2659,7 +2841,7 @@ async function extractGithubSkills(source, options) {
|
|
|
2659
2841
|
if (jsonOnly) {
|
|
2660
2842
|
process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
|
|
2661
2843
|
} else {
|
|
2662
|
-
console.error(
|
|
2844
|
+
console.error(chalk18.red(message));
|
|
2663
2845
|
}
|
|
2664
2846
|
process.exitCode = 1;
|
|
2665
2847
|
return;
|
|
@@ -2676,12 +2858,12 @@ async function extractGithubSkills(source, options) {
|
|
|
2676
2858
|
if (jsonOnly) {
|
|
2677
2859
|
process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
|
|
2678
2860
|
} else {
|
|
2679
|
-
console.error(
|
|
2861
|
+
console.error(chalk18.red(message));
|
|
2680
2862
|
}
|
|
2681
2863
|
process.exitCode = 1;
|
|
2682
2864
|
return;
|
|
2683
2865
|
}
|
|
2684
|
-
const spinner = createSpinner(`Parsing markdown at ${
|
|
2866
|
+
const spinner = createSpinner(`Parsing markdown at ${chalk18.cyan(resolvedSource)}...`);
|
|
2685
2867
|
if (!jsonOnly) spinner.start();
|
|
2686
2868
|
let skills = [];
|
|
2687
2869
|
let tree = [];
|
|
@@ -2704,7 +2886,7 @@ async function extractGithubSkills(source, options) {
|
|
|
2704
2886
|
tree = markdownResult.tree;
|
|
2705
2887
|
cleanup = markdownResult.cleanup;
|
|
2706
2888
|
} else {
|
|
2707
|
-
if (!jsonOnly) spinner.text = `Scanning repository at ${
|
|
2889
|
+
if (!jsonOnly) spinner.text = `Scanning repository at ${chalk18.cyan(resolvedSource)}...`;
|
|
2708
2890
|
const materialized = await materializeSourceToTemp3(resolvedSource);
|
|
2709
2891
|
cleanup = materialized.cleanup;
|
|
2710
2892
|
const discovered = discoverSkillDirsWithHeuristics(materialized.dir, { maxDepth: maxSkillDepth, maxSkills });
|
|
@@ -2769,7 +2951,7 @@ async function extractGithubSkills(source, options) {
|
|
|
2769
2951
|
for (const entry of repoCache.values()) entry.cleanup();
|
|
2770
2952
|
cleanup?.();
|
|
2771
2953
|
if (!jsonOnly) {
|
|
2772
|
-
spinner.succeed(`Exported ${skills.length} skill${skills.length > 1 ? "s" : ""} to ${
|
|
2954
|
+
spinner.succeed(`Exported ${skills.length} skill${skills.length > 1 ? "s" : ""} to ${chalk18.cyan(outDir)}`);
|
|
2773
2955
|
} else {
|
|
2774
2956
|
process.stdout.write(JSON.stringify({ ok: true, outDir, skills: catalogSkills }, null, 2) + "\n");
|
|
2775
2957
|
}
|
|
@@ -2780,7 +2962,7 @@ async function extractGithubSkills(source, options) {
|
|
|
2780
2962
|
if (jsonOnly) {
|
|
2781
2963
|
process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
|
|
2782
2964
|
} else {
|
|
2783
|
-
console.error(
|
|
2965
|
+
console.error(chalk18.red(message));
|
|
2784
2966
|
}
|
|
2785
2967
|
process.exitCode = 1;
|
|
2786
2968
|
}
|
|
@@ -2939,14 +3121,14 @@ function collapseNode2(node) {
|
|
|
2939
3121
|
}
|
|
2940
3122
|
|
|
2941
3123
|
// src/commands/sync.ts
|
|
2942
|
-
import
|
|
3124
|
+
import chalk19 from "chalk";
|
|
2943
3125
|
import {
|
|
2944
|
-
PLATFORMS as
|
|
3126
|
+
PLATFORMS as PLATFORMS5,
|
|
2945
3127
|
getSkillInfo as getSkillInfo2,
|
|
2946
3128
|
getSkillInstallDir,
|
|
2947
3129
|
installRegistrySkill as installRegistrySkill2,
|
|
2948
3130
|
installSkill as installSkill2,
|
|
2949
|
-
listSkills as
|
|
3131
|
+
listSkills as listSkills4,
|
|
2950
3132
|
loadOrCreateGlobalConfig
|
|
2951
3133
|
} from "@skild/core";
|
|
2952
3134
|
function parsePlatformList(value) {
|
|
@@ -2954,7 +3136,7 @@ function parsePlatformList(value) {
|
|
|
2954
3136
|
const parts = value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
2955
3137
|
const valid = /* @__PURE__ */ new Set();
|
|
2956
3138
|
for (const p of parts) {
|
|
2957
|
-
if (
|
|
3139
|
+
if (PLATFORMS5.includes(p)) valid.add(p);
|
|
2958
3140
|
}
|
|
2959
3141
|
return Array.from(valid);
|
|
2960
3142
|
}
|
|
@@ -2982,8 +3164,8 @@ function getDisplayName2(record) {
|
|
|
2982
3164
|
}
|
|
2983
3165
|
function collectInstalled(scope) {
|
|
2984
3166
|
const map = /* @__PURE__ */ new Map();
|
|
2985
|
-
for (const platform of
|
|
2986
|
-
const skills =
|
|
3167
|
+
for (const platform of PLATFORMS5) {
|
|
3168
|
+
const skills = listSkills4({ platform, scope });
|
|
2987
3169
|
const inner = /* @__PURE__ */ new Map();
|
|
2988
3170
|
for (const s of skills) {
|
|
2989
3171
|
if (!s.record) continue;
|
|
@@ -3001,11 +3183,11 @@ function deriveMissingTargets(scope, preferredSource, filterSkills, targetFilter
|
|
|
3001
3183
|
for (const name of records.keys()) skillNames.add(name);
|
|
3002
3184
|
}
|
|
3003
3185
|
const filteredSkillNames = filterSkills && filterSkills.length > 0 ? Array.from(skillNames).filter((s) => filterSkills.includes(s)) : Array.from(skillNames);
|
|
3004
|
-
const targetSet = targetFilter && targetFilter.length > 0 ? new Set(targetFilter) : new Set(
|
|
3186
|
+
const targetSet = targetFilter && targetFilter.length > 0 ? new Set(targetFilter) : new Set(PLATFORMS5);
|
|
3005
3187
|
const plans = [];
|
|
3006
3188
|
const missingByPlatform = /* @__PURE__ */ new Map();
|
|
3007
3189
|
for (const skill of filteredSkillNames) {
|
|
3008
|
-
const sources =
|
|
3190
|
+
const sources = PLATFORMS5.map((p) => installed.get(p)?.get(skill)).filter(Boolean);
|
|
3009
3191
|
if (sources.length === 0) continue;
|
|
3010
3192
|
const sourcePlatforms = sources.map((r) => r.platform);
|
|
3011
3193
|
const displayName = getDisplayName2(sources[0]);
|
|
@@ -3014,7 +3196,7 @@ function deriveMissingTargets(scope, preferredSource, filterSkills, targetFilter
|
|
|
3014
3196
|
warnings.push(`\u8DF3\u8FC7 ${skill}\uFF1A\u7F3A\u5C11\u53EF\u7528\u7684\u6E90\u8BB0\u5F55`);
|
|
3015
3197
|
continue;
|
|
3016
3198
|
}
|
|
3017
|
-
for (const platform of
|
|
3199
|
+
for (const platform of PLATFORMS5) {
|
|
3018
3200
|
if (!targetSet.has(platform)) continue;
|
|
3019
3201
|
if (installed.get(platform)?.has(skill)) continue;
|
|
3020
3202
|
plans.push({
|
|
@@ -3047,7 +3229,7 @@ async function sync(skills = [], options = {}) {
|
|
|
3047
3229
|
if (!options.json) {
|
|
3048
3230
|
logger.header(`
|
|
3049
3231
|
Cross-platform sync (scope: ${scope})`);
|
|
3050
|
-
const platformsToReport = targetFilter.length > 0 ? targetFilter :
|
|
3232
|
+
const platformsToReport = targetFilter.length > 0 ? targetFilter : PLATFORMS5;
|
|
3051
3233
|
for (const p of platformsToReport) {
|
|
3052
3234
|
const missing = missingByPlatform.get(p) || 0;
|
|
3053
3235
|
if (missing > 0) {
|
|
@@ -3158,26 +3340,26 @@ Cross-platform sync (scope: ${scope})`);
|
|
|
3158
3340
|
const skipped = results.filter((r) => r.status === "skipped").length;
|
|
3159
3341
|
const failed = results.filter((r) => r.status === "failed").length;
|
|
3160
3342
|
logger.header(`
|
|
3161
|
-
\u5B8C\u6210\uFF1A${
|
|
3343
|
+
\u5B8C\u6210\uFF1A${chalk19.green(`${synced} \u6210\u529F`)} / ${chalk19.yellow(`${skipped} \u8DF3\u8FC7`)} / ${chalk19.red(`${failed} \u5931\u8D25`)}`);
|
|
3162
3344
|
if (failed > 0) {
|
|
3163
3345
|
process.exitCode = 1;
|
|
3164
3346
|
}
|
|
3165
3347
|
}
|
|
3166
3348
|
|
|
3167
3349
|
// src/index.ts
|
|
3168
|
-
import { PLATFORMS as
|
|
3350
|
+
import { PLATFORMS as PLATFORMS6 } from "@skild/core";
|
|
3169
3351
|
var require2 = createRequire(import.meta.url);
|
|
3170
3352
|
var { version } = require2("../package.json");
|
|
3171
3353
|
var program = new Command();
|
|
3172
3354
|
program.name("skild").description("The npm for Agent Skills \u2014 Discover, install, manage, and publish AI Agent Skills with ease.").version(version);
|
|
3173
|
-
program.command("install <source>").alias("i").alias("add").description("Install a Skill from a Git URL, degit shorthand, or local directory").option("-t, --target <platform>", `Target platform: ${
|
|
3355
|
+
program.command("install <source>").alias("i").alias("add").description("Install a Skill from a Git URL, degit shorthand, or local directory").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")}`).option("--all", `Install to all platforms: ${PLATFORMS6.join(", ")}`).option("--recursive", "If source is a multi-skill directory/repo, install all discovered skills").option("--skill <path-or-name>", "Select a single skill when the source contains multiple skills").option("-y, --yes", "Skip confirmation prompts (assume yes)").option("--depth <n>", "Max markdown recursion depth (default: 0)", "0").option("--scan-depth <n>", "Max directory depth to scan for SKILL.md (default: 6)", "6").option("--max-skills <n>", "Max discovered skills to install (default: 200)", "200").option("-l, --local", "Install to project-level directory instead of global").option("-f, --force", "Overwrite existing installation").option("--registry <url>", "Registry base URL (default: https://registry.skild.sh)").option("--json", "Output JSON").action(async (source, options) => {
|
|
3174
3356
|
await install(source, options);
|
|
3175
3357
|
});
|
|
3176
|
-
program.command("list").alias("ls").description("List installed Skills").option("-t, --target <platform>", `Target platform: ${
|
|
3177
|
-
program.command("info <skill>").description("Show installed Skill details").option("-t, --target <platform>", `Target platform: ${
|
|
3178
|
-
program.command("uninstall <skill>").alias("rm").description("Uninstall a Skill").option("-t, --target <platform>", `Target platform: ${
|
|
3179
|
-
program.command("update [skill]").alias("up").description("Update one or all installed Skills").option("-t, --target <platform>", `Target platform: ${
|
|
3180
|
-
program.command("validate [target]").alias("v").description("Validate a Skill folder (path) or an installed Skill name").option("-t, --target <platform>", `Target platform: ${
|
|
3358
|
+
program.command("list").alias("ls").description("List installed Skills").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")} (optional; omit to list all)`).option("-l, --local", "List project-level directory instead of global").option("--paths", "Show install paths").option("--verbose", "Show skillset dependency details").option("--json", "Output JSON").action(async (options) => list(options));
|
|
3359
|
+
program.command("info <skill>").description("Show installed Skill details").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")}`, "claude").option("-l, --local", "Use project-level directory instead of global").option("--json", "Output JSON").action(async (skill, options) => info(skill, options));
|
|
3360
|
+
program.command("uninstall <skill>").alias("rm").description("Uninstall a Skill").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")}`).option("-l, --local", "Target project-level directory (can combine with --global)").option("-g, --global", "Target global directory (can combine with --local)").option("-f, --force", "Uninstall even if metadata is missing").option("--with-deps", "Uninstall dependencies that are only required by this skill").action(async (skill, options) => uninstall(skill, options));
|
|
3361
|
+
program.command("update [skill]").alias("up").description("Update one or all installed Skills").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")}`).option("-l, --local", "Target project-level directory (can combine with --global)").option("-g, --global", "Target global directory (can combine with --local)").option("--json", "Output JSON").action(async (skill, options) => update(skill, options));
|
|
3362
|
+
program.command("validate [target]").alias("v").description("Validate a Skill folder (path) or an installed Skill name").option("-t, --target <platform>", `Target platform: ${PLATFORMS6.join(", ")}`, "claude").option("-l, --local", "Use project-level directory instead of global").option("--json", "Output JSON").action(async (target, options) => validate(target, options));
|
|
3181
3363
|
program.command("init <name>").description("Create a new Skill project").option("--dir <path>", "Target directory (defaults to <name>)").option("--description <text>", "Skill description").option("-f, --force", "Overwrite target directory if it exists").action(async (name, options) => init(name, options));
|
|
3182
3364
|
program.command("signup").description("Create a publisher account in the registry (no GitHub required)").option("--registry <url>", "Registry base URL (default: https://registry.skild.sh)").option("--email <email>", "Email (optional; will prompt)").option("--handle <handle>", "Publisher handle (owns @handle/* scope) (optional; will prompt)").option("--password <password>", "Password (optional; will prompt)").option("--json", "Output JSON").action(async (options) => signup(options));
|
|
3183
3365
|
program.command("login").description("Login to a registry and store an access token locally").option("--registry <url>", "Registry base URL (default: https://registry.skild.sh)").option("--handle-or-email <value>", "Handle or email (optional; will prompt)").option("--password <password>", "Password (optional; will prompt)").option("--token-name <name>", "Token label").option("--json", "Output JSON").action(async (options) => login(options));
|
|
@@ -3188,14 +3370,14 @@ program.command("search <query>").description("Search Skills in the registry").o
|
|
|
3188
3370
|
program.command("extract-github-skills <source>").description("Extract GitHub skills into a local catalog directory").option("--out <dir>", "Output directory (default: ./skild-github-skills)").option("-f, --force", "Overwrite existing output directory").option("--depth <n>", "Max markdown recursion depth (default: 0)", "0").option("--scan-depth <n>", "Max directory depth to scan for SKILL.md (default: 6)", "6").option("--max-skills <n>", "Max discovered skills to export (default: 200)", "200").option("--json", "Output JSON").action(async (source, options) => {
|
|
3189
3371
|
await extractGithubSkills(source, options);
|
|
3190
3372
|
});
|
|
3191
|
-
program.command("sync [skills...]").description("Sync missing skills across platforms (auto-detect + tree selection)").option("--to <platforms>", `Comma-separated target platforms to include: ${
|
|
3373
|
+
program.command("sync [skills...]").description("Sync missing skills across platforms (auto-detect + tree selection)").option("--to <platforms>", `Comma-separated target platforms to include: ${PLATFORMS6.join(", ")}`).option("--all", "Alias for default (all platforms)").option("-l, --local", "Use project-level directory instead of global").option("-y, --yes", "Skip interactive prompts (defaults to all other platforms)").option("-f, --force", "Force reinstall even if target already exists").option("--json", "Output JSON").action(async (skills = [], options) => {
|
|
3192
3374
|
await sync(skills, options);
|
|
3193
3375
|
});
|
|
3194
3376
|
program.action(() => {
|
|
3195
|
-
const dim =
|
|
3196
|
-
const cyan =
|
|
3197
|
-
const bold =
|
|
3198
|
-
const green =
|
|
3377
|
+
const dim = chalk20.dim;
|
|
3378
|
+
const cyan = chalk20.cyan;
|
|
3379
|
+
const bold = chalk20.bold;
|
|
3380
|
+
const green = chalk20.green;
|
|
3199
3381
|
console.log("");
|
|
3200
3382
|
console.log(cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 "));
|
|
3201
3383
|
console.log(cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skild",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "The npm for Agent Skills — Discover, install, manage, and publish AI Agent Skills with ease.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"string-width": "^8.1.0",
|
|
44
44
|
"tar": "^7.4.3",
|
|
45
45
|
"unified": "^11.0.4",
|
|
46
|
-
"@skild/core": "^0.
|
|
46
|
+
"@skild/core": "^0.11.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/mdast": "^4.0.4",
|