skild 0.2.5 → 0.2.7
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/dist/index.js +110 -37
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6,8 +6,10 @@ import chalk15 from "chalk";
|
|
|
6
6
|
import { createRequire } from "module";
|
|
7
7
|
|
|
8
8
|
// src/commands/install.ts
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
9
11
|
import chalk2 from "chalk";
|
|
10
|
-
import { fetchWithTimeout, installRegistrySkill, installSkill, loadRegistryAuth, resolveRegistryUrl, SkildError } from "@skild/core";
|
|
12
|
+
import { fetchWithTimeout, installRegistrySkill, installSkill, loadRegistryAuth, resolveRegistryAlias, resolveRegistryUrl, SkildError } from "@skild/core";
|
|
11
13
|
|
|
12
14
|
// src/utils/logger.ts
|
|
13
15
|
import chalk from "chalk";
|
|
@@ -55,10 +57,10 @@ var logger = {
|
|
|
55
57
|
/**
|
|
56
58
|
* Log a skill entry with status indicator.
|
|
57
59
|
*/
|
|
58
|
-
skillEntry: (name,
|
|
60
|
+
skillEntry: (name, path4, hasSkillMd) => {
|
|
59
61
|
const status = hasSkillMd ? chalk.green("\u2713") : chalk.yellow("\u26A0");
|
|
60
62
|
console.log(` ${status} ${chalk.cyan(name)}`);
|
|
61
|
-
console.log(chalk.dim(` \u2514\u2500 ${
|
|
63
|
+
console.log(chalk.dim(` \u2514\u2500 ${path4}`));
|
|
62
64
|
},
|
|
63
65
|
/**
|
|
64
66
|
* Log installation result details.
|
|
@@ -70,17 +72,43 @@ var logger = {
|
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
// src/commands/install.ts
|
|
75
|
+
function looksLikeAlias(input) {
|
|
76
|
+
const s = input.trim();
|
|
77
|
+
if (!s) return false;
|
|
78
|
+
if (s.startsWith("@")) return false;
|
|
79
|
+
if (s.includes("/") || s.includes("\\")) return false;
|
|
80
|
+
if (/^https?:\/\//i.test(s) || s.includes("github.com")) return false;
|
|
81
|
+
if (fs.existsSync(path.resolve(s))) return false;
|
|
82
|
+
if (s.length < 3 || s.length > 64) return false;
|
|
83
|
+
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(s)) return false;
|
|
84
|
+
if (s.includes("--")) return false;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
73
87
|
async function install(source, options = {}) {
|
|
74
88
|
const platform = options.target || "claude";
|
|
75
89
|
const scope = options.local ? "project" : "global";
|
|
76
90
|
const auth = loadRegistryAuth();
|
|
77
91
|
const registryUrlForDeps = options.registry || auth?.registryUrl;
|
|
92
|
+
let resolvedSource = source.trim();
|
|
93
|
+
try {
|
|
94
|
+
if (looksLikeAlias(resolvedSource)) {
|
|
95
|
+
const registryUrl = resolveRegistryUrl(registryUrlForDeps);
|
|
96
|
+
const resolved = await resolveRegistryAlias(registryUrl, resolvedSource);
|
|
97
|
+
if (!options.json) logger.info(`Resolved ${chalk2.cyan(resolvedSource)} \u2192 ${chalk2.cyan(resolved.spec)} (${resolved.type})`);
|
|
98
|
+
resolvedSource = resolved.spec;
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
const message = error instanceof SkildError ? error.message : error instanceof Error ? error.message : String(error);
|
|
102
|
+
console.error(chalk2.red(message));
|
|
103
|
+
process.exitCode = 1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
78
106
|
const spinner = createSpinner(`Installing ${chalk2.cyan(source)} to ${chalk2.dim(platform)} (${scope})...`);
|
|
79
107
|
try {
|
|
80
|
-
const record =
|
|
81
|
-
{ spec:
|
|
108
|
+
const record = resolvedSource.startsWith("@") && resolvedSource.includes("/") ? await installRegistrySkill(
|
|
109
|
+
{ spec: resolvedSource, registryUrl: registryUrlForDeps },
|
|
82
110
|
{ platform, scope, force: Boolean(options.force) }
|
|
83
|
-
) : await installSkill({ source }, { platform, scope, force: Boolean(options.force), registryUrl: registryUrlForDeps });
|
|
111
|
+
) : await installSkill({ source: resolvedSource }, { platform, scope, force: Boolean(options.force), registryUrl: registryUrlForDeps });
|
|
84
112
|
const displayName = record.canonicalName || record.name;
|
|
85
113
|
spinner.succeed(`Installed ${chalk2.green(displayName)} to ${chalk2.dim(record.installDir)}`);
|
|
86
114
|
if (options.json) {
|
|
@@ -138,8 +166,8 @@ async function reportDownload(record, registryOverride) {
|
|
|
138
166
|
|
|
139
167
|
// src/commands/list.ts
|
|
140
168
|
import chalk3 from "chalk";
|
|
141
|
-
import
|
|
142
|
-
import
|
|
169
|
+
import fs2 from "fs";
|
|
170
|
+
import path2 from "path";
|
|
143
171
|
import { PLATFORMS, listAllSkills, listSkills } from "@skild/core";
|
|
144
172
|
function toDisplayName(name, mapping) {
|
|
145
173
|
return mapping.get(name) || name;
|
|
@@ -172,8 +200,8 @@ function buildDisplayEntries(skills) {
|
|
|
172
200
|
if (!inlineDeps.length) continue;
|
|
173
201
|
const ownerName = toDisplayName(skill.name, nameToDisplay);
|
|
174
202
|
for (const dep of inlineDeps) {
|
|
175
|
-
const inlineDir = dep.inlinePath ?
|
|
176
|
-
const hasSkillMd =
|
|
203
|
+
const inlineDir = dep.inlinePath ? path2.join(skill.installDir, dep.inlinePath) : path2.join(skill.installDir, dep.name);
|
|
204
|
+
const hasSkillMd = fs2.existsSync(path2.join(inlineDir, "SKILL.md"));
|
|
177
205
|
entries.push({
|
|
178
206
|
name: dep.name,
|
|
179
207
|
installDir: inlineDir,
|
|
@@ -399,25 +427,48 @@ async function promptLine(question, defaultValue) {
|
|
|
399
427
|
}
|
|
400
428
|
}
|
|
401
429
|
async function promptPassword(question) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
430
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
431
|
+
return promptLine(question);
|
|
432
|
+
}
|
|
433
|
+
const stdin = process.stdin;
|
|
434
|
+
const stdout = process.stdout;
|
|
435
|
+
stdout.write(`${question}: `);
|
|
436
|
+
const wasRaw = Boolean(stdin.isRaw);
|
|
437
|
+
stdin.setRawMode(true);
|
|
438
|
+
stdin.resume();
|
|
439
|
+
readline.emitKeypressEvents(stdin);
|
|
440
|
+
const buf = [];
|
|
441
|
+
return await new Promise((resolve, reject) => {
|
|
442
|
+
function cleanup() {
|
|
443
|
+
stdin.off("keypress", onKeypress);
|
|
444
|
+
stdin.setRawMode(wasRaw);
|
|
445
|
+
stdin.pause();
|
|
409
446
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
447
|
+
function onKeypress(str, key) {
|
|
448
|
+
if (key?.ctrl && key?.name === "c") {
|
|
449
|
+
stdout.write("\n");
|
|
450
|
+
cleanup();
|
|
451
|
+
const err = new Error("Prompt cancelled");
|
|
452
|
+
err.code = "PROMPT_CANCELLED";
|
|
453
|
+
reject(err);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (key?.name === "return" || key?.name === "enter") {
|
|
457
|
+
stdout.write("\n");
|
|
458
|
+
cleanup();
|
|
459
|
+
resolve(buf.join(""));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (key?.name === "backspace" || key?.name === "delete") {
|
|
463
|
+
if (buf.length) buf.pop();
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (!str) return;
|
|
467
|
+
if (key?.ctrl || key?.meta) return;
|
|
468
|
+
buf.push(str);
|
|
469
|
+
}
|
|
470
|
+
stdin.on("keypress", onKeypress);
|
|
471
|
+
});
|
|
421
472
|
}
|
|
422
473
|
|
|
423
474
|
// src/commands/signup.ts
|
|
@@ -434,7 +485,18 @@ async function signup(options) {
|
|
|
434
485
|
}
|
|
435
486
|
const finalEmail = email || await promptLine("Email");
|
|
436
487
|
const finalHandle = handle || (await promptLine("Handle (publisher scope)", void 0)).toLowerCase();
|
|
437
|
-
|
|
488
|
+
let finalPassword = password;
|
|
489
|
+
if (!finalPassword) {
|
|
490
|
+
try {
|
|
491
|
+
finalPassword = await promptPassword("Password");
|
|
492
|
+
} catch (e) {
|
|
493
|
+
if (e?.code === "PROMPT_CANCELLED") {
|
|
494
|
+
process.exitCode = 130;
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
throw e;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
438
500
|
let text = "";
|
|
439
501
|
try {
|
|
440
502
|
const res = await fetchWithTimeout2(
|
|
@@ -501,7 +563,18 @@ async function login(options) {
|
|
|
501
563
|
return;
|
|
502
564
|
}
|
|
503
565
|
const finalHandleOrEmail = handleOrEmail || await promptLine("Handle or email");
|
|
504
|
-
|
|
566
|
+
let finalPassword = password;
|
|
567
|
+
if (!finalPassword) {
|
|
568
|
+
try {
|
|
569
|
+
finalPassword = await promptPassword("Password");
|
|
570
|
+
} catch (e) {
|
|
571
|
+
if (e?.code === "PROMPT_CANCELLED") {
|
|
572
|
+
process.exitCode = 130;
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
throw e;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
505
578
|
const finalTokenName = options.tokenName?.trim() || void 0;
|
|
506
579
|
let text = "";
|
|
507
580
|
try {
|
|
@@ -591,9 +664,9 @@ async function whoami() {
|
|
|
591
664
|
}
|
|
592
665
|
|
|
593
666
|
// src/commands/publish.ts
|
|
594
|
-
import
|
|
667
|
+
import fs3 from "fs";
|
|
595
668
|
import os from "os";
|
|
596
|
-
import
|
|
669
|
+
import path3 from "path";
|
|
597
670
|
import crypto from "crypto";
|
|
598
671
|
import * as tar from "tar";
|
|
599
672
|
import chalk13 from "chalk";
|
|
@@ -616,7 +689,7 @@ async function publish(options = {}) {
|
|
|
616
689
|
process.exitCode = 1;
|
|
617
690
|
return;
|
|
618
691
|
}
|
|
619
|
-
const dir =
|
|
692
|
+
const dir = path3.resolve(options.dir || process.cwd());
|
|
620
693
|
const validation = validateSkillDir(dir);
|
|
621
694
|
if (!validation.ok) {
|
|
622
695
|
console.error(chalk13.red("Skill validation failed:"));
|
|
@@ -675,8 +748,8 @@ async function publish(options = {}) {
|
|
|
675
748
|
return;
|
|
676
749
|
}
|
|
677
750
|
const spinner = createSpinner(`Publishing ${chalk13.cyan(`${name}@${version2}`)} to ${chalk13.dim(registry)}...`);
|
|
678
|
-
const tempDir =
|
|
679
|
-
const tarballPath =
|
|
751
|
+
const tempDir = fs3.mkdtempSync(path3.join(os.tmpdir(), "skild-publish-"));
|
|
752
|
+
const tarballPath = path3.join(tempDir, "skill.tgz");
|
|
680
753
|
try {
|
|
681
754
|
await tar.c(
|
|
682
755
|
{
|
|
@@ -688,7 +761,7 @@ async function publish(options = {}) {
|
|
|
688
761
|
},
|
|
689
762
|
["."]
|
|
690
763
|
);
|
|
691
|
-
const buf =
|
|
764
|
+
const buf = fs3.readFileSync(tarballPath);
|
|
692
765
|
const integrity = sha256Hex(buf);
|
|
693
766
|
const form = new FormData();
|
|
694
767
|
form.set("version", version2);
|
|
@@ -732,7 +805,7 @@ async function publish(options = {}) {
|
|
|
732
805
|
console.error(chalk13.red(message));
|
|
733
806
|
process.exitCode = 1;
|
|
734
807
|
} finally {
|
|
735
|
-
|
|
808
|
+
fs3.rmSync(tempDir, { recursive: true, force: true });
|
|
736
809
|
}
|
|
737
810
|
}
|
|
738
811
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skild",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
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",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"commander": "^12.1.0",
|
|
38
38
|
"ora": "^8.0.1",
|
|
39
39
|
"tar": "^7.4.3",
|
|
40
|
-
"@skild/core": "^0.2.
|
|
40
|
+
"@skild/core": "^0.2.7"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^20.10.0",
|