ht-skills 0.1.1 → 0.1.3
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 +2 -1
- package/bin/ht-skills.js +4 -0
- package/lib/cli.js +99 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ CLI for installing and submitting skills from HT Skills Marketplace.
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
7
|
```powershell
|
|
8
|
-
npx ht-skills
|
|
8
|
+
npx ht-skills add http://skills.ic.aeroht.local --skill repo-bug-analyze
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Commands
|
|
@@ -14,4 +14,5 @@ npx ht-skills install repo-bug-analyze --registry http://skills.ic.aeroht.local
|
|
|
14
14
|
ht-skills search <query> [--registry <url>] [--limit <n>]
|
|
15
15
|
ht-skills submit <skillDir> [--registry <url>] [--submitter <name>] [--visibility public|private|shared] [--shared-with a@b.com,c@d.com] [--publish-now]
|
|
16
16
|
ht-skills install <slug[@version]> [--registry <url>] [--target <dir>] [--tool codex|claude|vscode]
|
|
17
|
+
ht-skills add <registry> --skill <slug[@version]> [--tool codex|claude|vscode]
|
|
17
18
|
```
|
package/bin/ht-skills.js
CHANGED
package/lib/cli.js
CHANGED
|
@@ -41,13 +41,15 @@ function printHelp() {
|
|
|
41
41
|
ht-skills search <query> [--registry <url>] [--limit <n>]
|
|
42
42
|
ht-skills submit <skillDir> [--registry <url>] [--submitter <name>] [--visibility public|private|shared] [--shared-with a@b.com,c@d.com] [--publish-now]
|
|
43
43
|
ht-skills install <slug[@version]> [--registry <url>] [--target <dir>] [--tool codex|claude|vscode]
|
|
44
|
+
ht-skills add <registry> --skill <slug[@version]> [--tool codex|claude|vscode]
|
|
44
45
|
|
|
45
46
|
Examples:
|
|
46
47
|
ht-skills search openai --registry http://localhost:8787
|
|
47
48
|
ht-skills submit ./examples/hello-skill --registry http://localhost:8787
|
|
48
49
|
ht-skills install hello-skill@1.0.0 --registry http://localhost:8787 --tool codex
|
|
49
50
|
ht-skills install hello-skill@1.0.0 --registry http://localhost:8787 --tool codex,claude,vscode
|
|
50
|
-
ht-skills install hello-skill --registry http://localhost:8787
|
|
51
|
+
ht-skills install hello-skill --registry http://localhost:8787
|
|
52
|
+
ht-skills add http://localhost:8787 --skill hello-skill`);
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
function parseArgs(argv) {
|
|
@@ -91,11 +93,37 @@ async function requestJson(url, options = {}) {
|
|
|
91
93
|
}
|
|
92
94
|
if (!res.ok) {
|
|
93
95
|
const message = payload.error || text || `HTTP ${res.status}`;
|
|
94
|
-
|
|
96
|
+
const error = new Error(message);
|
|
97
|
+
error.status = res.status;
|
|
98
|
+
error.url = url;
|
|
99
|
+
throw error;
|
|
95
100
|
}
|
|
96
101
|
return payload;
|
|
97
102
|
}
|
|
98
103
|
|
|
104
|
+
function formatInstallError(error, { slug, version = null, registry, stage = "resolve" }) {
|
|
105
|
+
const rawMessage = String(error?.message || "Install failed").trim();
|
|
106
|
+
const status = Number(error?.status || 0);
|
|
107
|
+
const lowerMessage = rawMessage.toLowerCase();
|
|
108
|
+
const isNotFound = status === 404 || lowerMessage === "not found";
|
|
109
|
+
|
|
110
|
+
if (isNotFound && stage === "resolve") {
|
|
111
|
+
return `Skill "${slug}" was not found in registry ${registry}.`;
|
|
112
|
+
}
|
|
113
|
+
if (isNotFound && stage === "metadata") {
|
|
114
|
+
return version
|
|
115
|
+
? `Skill "${slug}@${version}" metadata was not found in registry ${registry}.`
|
|
116
|
+
: `Skill "${slug}" metadata was not found in registry ${registry}.`;
|
|
117
|
+
}
|
|
118
|
+
if (isNotFound && stage === "bundle") {
|
|
119
|
+
return version
|
|
120
|
+
? `Skill bundle "${slug}@${version}" was not found in registry ${registry}.`
|
|
121
|
+
: `Skill bundle for "${slug}" was not found in registry ${registry}.`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return rawMessage;
|
|
125
|
+
}
|
|
126
|
+
|
|
99
127
|
async function walkFiles(baseDir) {
|
|
100
128
|
const results = [];
|
|
101
129
|
const ignored = new Set([".git", "node_modules", ".DS_Store"]);
|
|
@@ -448,15 +476,31 @@ async function cmdInstall(flags, deps = {}) {
|
|
|
448
476
|
const parsed = parseSpec(spec);
|
|
449
477
|
|
|
450
478
|
const resolveSpinner = ui ? ui.spinner() : null;
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
479
|
+
let version;
|
|
480
|
+
try {
|
|
481
|
+
if (resolveSpinner) {
|
|
482
|
+
// eslint-disable-next-line no-console
|
|
483
|
+
console.log(`\n${renderGradientBanner()}\n`);
|
|
484
|
+
ui.intro(ui.pc.bgCyan(ui.pc.black(" ht-skills ")));
|
|
485
|
+
resolveSpinner.start(`Resolving ${parsed.slug}`);
|
|
486
|
+
}
|
|
487
|
+
version = await fetchResolvedVersion(registry, parsed, requestJsonImpl);
|
|
488
|
+
if (resolveSpinner) {
|
|
489
|
+
resolveSpinner.stop(`Resolved ${parsed.slug}@${version}`);
|
|
490
|
+
}
|
|
491
|
+
} catch (error) {
|
|
492
|
+
const friendlyMessage = formatInstallError(error, {
|
|
493
|
+
slug: parsed.slug,
|
|
494
|
+
registry,
|
|
495
|
+
stage: "resolve",
|
|
496
|
+
});
|
|
497
|
+
if (resolveSpinner) {
|
|
498
|
+
resolveSpinner.stop(ui.pc.red(`Unable to resolve ${parsed.slug}`));
|
|
499
|
+
ui.outro(ui.pc.red(friendlyMessage));
|
|
500
|
+
error.reported = true;
|
|
501
|
+
}
|
|
502
|
+
error.message = friendlyMessage;
|
|
503
|
+
throw error;
|
|
460
504
|
}
|
|
461
505
|
|
|
462
506
|
let toolIds = normalizeToolIds(flags.tool);
|
|
@@ -467,7 +511,15 @@ async function cmdInstall(flags, deps = {}) {
|
|
|
467
511
|
metadata = await requestJsonImpl(
|
|
468
512
|
`${registry}/api/skills/${encodeURIComponent(parsed.slug)}/${encodeURIComponent(version)}`,
|
|
469
513
|
);
|
|
470
|
-
} catch {
|
|
514
|
+
} catch (error) {
|
|
515
|
+
if (Number(error?.status || 0) !== 404 && String(error?.message || "").toLowerCase() !== "not found") {
|
|
516
|
+
throw new Error(formatInstallError(error, {
|
|
517
|
+
slug: parsed.slug,
|
|
518
|
+
version,
|
|
519
|
+
registry,
|
|
520
|
+
stage: "metadata",
|
|
521
|
+
}));
|
|
522
|
+
}
|
|
471
523
|
metadata = null;
|
|
472
524
|
}
|
|
473
525
|
|
|
@@ -540,7 +592,16 @@ async function cmdInstall(flags, deps = {}) {
|
|
|
540
592
|
}
|
|
541
593
|
const bundle = await requestJsonImpl(
|
|
542
594
|
`${registry}/api/skills/${encodeURIComponent(parsed.slug)}/${encodeURIComponent(version)}/bundle`,
|
|
543
|
-
)
|
|
595
|
+
).catch((error) => {
|
|
596
|
+
const friendlyError = new Error(formatInstallError(error, {
|
|
597
|
+
slug: parsed.slug,
|
|
598
|
+
version,
|
|
599
|
+
registry,
|
|
600
|
+
stage: "bundle",
|
|
601
|
+
}));
|
|
602
|
+
friendlyError.status = error?.status;
|
|
603
|
+
throw friendlyError;
|
|
604
|
+
});
|
|
544
605
|
if (bundleSpinner) {
|
|
545
606
|
bundleSpinner.stop(`Downloaded ${parsed.slug}@${version}`);
|
|
546
607
|
}
|
|
@@ -644,6 +705,26 @@ async function cmdSubmit(flags, deps = {}) {
|
|
|
644
705
|
log(JSON.stringify(result, null, 2));
|
|
645
706
|
}
|
|
646
707
|
|
|
708
|
+
async function cmdAdd(flags, deps = {}) {
|
|
709
|
+
const source = String(flags._[0] || "").trim();
|
|
710
|
+
const skill = String(flags.skill || "").trim();
|
|
711
|
+
|
|
712
|
+
if (!source) {
|
|
713
|
+
throw new Error("add requires a registry URL, for example ht-skills add http://localhost:8787 --skill hello-skill");
|
|
714
|
+
}
|
|
715
|
+
if (!skill) {
|
|
716
|
+
throw new Error("add requires --skill <slug> or --skill <slug@version>");
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
const installFlags = {
|
|
720
|
+
...flags,
|
|
721
|
+
_: [skill],
|
|
722
|
+
registry: source,
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
return cmdInstall(installFlags, deps);
|
|
726
|
+
}
|
|
727
|
+
|
|
647
728
|
async function main(argv = process.argv) {
|
|
648
729
|
const [, , command, ...rest] = argv;
|
|
649
730
|
const flags = parseArgs(rest);
|
|
@@ -660,6 +741,10 @@ async function main(argv = process.argv) {
|
|
|
660
741
|
await cmdInstall(flags);
|
|
661
742
|
return;
|
|
662
743
|
}
|
|
744
|
+
if (command === "add") {
|
|
745
|
+
await cmdAdd(flags);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
663
748
|
if (command === "submit") {
|
|
664
749
|
await cmdSubmit(flags);
|
|
665
750
|
return;
|
|
@@ -678,6 +763,7 @@ module.exports = {
|
|
|
678
763
|
resolveInstallTargets,
|
|
679
764
|
fetchResolvedVersion,
|
|
680
765
|
cmdInstall,
|
|
766
|
+
cmdAdd,
|
|
681
767
|
cmdSearch,
|
|
682
768
|
cmdSubmit,
|
|
683
769
|
main,
|