@kurokeita/add-skill 1.10.0 → 1.10.1
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/bin/cli.js +56 -43
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
select,
|
|
20
20
|
spinner
|
|
21
21
|
} from "@clack/prompts";
|
|
22
|
-
import
|
|
22
|
+
import fs4 from "fs-extra";
|
|
23
23
|
import pc from "picocolors";
|
|
24
24
|
|
|
25
25
|
// src/utils/github.ts
|
|
@@ -98,12 +98,25 @@ async function fetchSkillFromGitHub(url) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// src/utils/paths.ts
|
|
101
|
+
import fs2 from "node:fs";
|
|
101
102
|
import os2 from "node:os";
|
|
102
103
|
import path2 from "node:path";
|
|
103
104
|
import { fileURLToPath } from "node:url";
|
|
104
105
|
var __filename = fileURLToPath(import.meta.url);
|
|
105
106
|
var __dirname = path2.dirname(__filename);
|
|
106
|
-
|
|
107
|
+
function hasBundledAssets(rootDir) {
|
|
108
|
+
return ["skills", "agents", "workflows"].some(
|
|
109
|
+
(dir) => fs2.existsSync(path2.join(rootDir, dir))
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
function resolveProjectRoot(moduleDir) {
|
|
113
|
+
const sourceRoot = path2.resolve(moduleDir, "../..");
|
|
114
|
+
if (hasBundledAssets(sourceRoot)) {
|
|
115
|
+
return sourceRoot;
|
|
116
|
+
}
|
|
117
|
+
return path2.resolve(moduleDir, "..");
|
|
118
|
+
}
|
|
119
|
+
var PROJECT_ROOT = resolveProjectRoot(__dirname);
|
|
107
120
|
var PLATFORM_LABELS = {
|
|
108
121
|
antigravity: "Antigravity",
|
|
109
122
|
codex: "Codex",
|
|
@@ -159,7 +172,7 @@ var AntigravityHandler = class {
|
|
|
159
172
|
|
|
160
173
|
// src/utils/platforms/codex.ts
|
|
161
174
|
import path3 from "node:path";
|
|
162
|
-
import
|
|
175
|
+
import fs3 from "fs-extra";
|
|
163
176
|
import yaml from "js-yaml";
|
|
164
177
|
var frontmatterRegex = /^---\n([\s\S]*?)\n---/;
|
|
165
178
|
var CODEX_TYPE_FIELD = "x-ai-agents-type";
|
|
@@ -214,7 +227,7 @@ async function codexEntryMatchesType(basePath, entry, requestedType) {
|
|
|
214
227
|
}
|
|
215
228
|
if (!targetPath) return false;
|
|
216
229
|
try {
|
|
217
|
-
const content = await
|
|
230
|
+
const content = await fs3.readFile(targetPath, "utf-8");
|
|
218
231
|
return parseCodexType(content) === requestedType;
|
|
219
232
|
} catch {
|
|
220
233
|
return false;
|
|
@@ -463,14 +476,14 @@ function getPlatformOptions(type) {
|
|
|
463
476
|
}
|
|
464
477
|
async function installItem(itemName, overwrite, sourcePath, targetBaseDir) {
|
|
465
478
|
const targetPath = path5.join(targetBaseDir, itemName);
|
|
466
|
-
if (!await
|
|
479
|
+
if (!await fs4.pathExists(sourcePath)) {
|
|
467
480
|
throw new Error(`Item '${itemName}' not found at ${sourcePath}`);
|
|
468
481
|
}
|
|
469
|
-
if (!overwrite && await
|
|
482
|
+
if (!overwrite && await fs4.pathExists(targetPath)) {
|
|
470
483
|
return false;
|
|
471
484
|
}
|
|
472
|
-
await
|
|
473
|
-
await
|
|
485
|
+
await fs4.ensureDir(targetBaseDir);
|
|
486
|
+
await fs4.copy(sourcePath, targetPath, { overwrite });
|
|
474
487
|
return true;
|
|
475
488
|
}
|
|
476
489
|
async function add(type, url, options) {
|
|
@@ -518,12 +531,12 @@ async function add(type, url, options) {
|
|
|
518
531
|
}
|
|
519
532
|
} else {
|
|
520
533
|
const sourceDir = TYPE_DIRS[normalizedType];
|
|
521
|
-
if (!await
|
|
534
|
+
if (!await fs4.pathExists(sourceDir)) {
|
|
522
535
|
cancel(`${normalizedType} directory not found!`);
|
|
523
536
|
process.exit(1);
|
|
524
537
|
return;
|
|
525
538
|
}
|
|
526
|
-
const entries = await
|
|
539
|
+
const entries = await fs4.readdir(sourceDir, { withFileTypes: true });
|
|
527
540
|
const availableItems = entries.filter(
|
|
528
541
|
(entry) => entry.isDirectory() || (normalizedType === "workflow" || normalizedType === "agent") && entry.isFile() && entry.name.endsWith(".md")
|
|
529
542
|
).map((entry) => ({ label: entry.name, value: entry.name })).sort((a, b) => a.label.localeCompare(b.label));
|
|
@@ -558,7 +571,7 @@ async function add(type, url, options) {
|
|
|
558
571
|
required: true
|
|
559
572
|
});
|
|
560
573
|
if (isCancel(platforms)) {
|
|
561
|
-
if (tempDir) await
|
|
574
|
+
if (tempDir) await fs4.remove(tempDir);
|
|
562
575
|
if (isSingleShot) break;
|
|
563
576
|
currentType = void 0;
|
|
564
577
|
continue;
|
|
@@ -572,7 +585,7 @@ async function add(type, url, options) {
|
|
|
572
585
|
for (const item of selectedItems) {
|
|
573
586
|
const targetItemName = handler.getTargetFileName(item, normalizedType);
|
|
574
587
|
const targetPath = path5.join(targetBase, targetItemName);
|
|
575
|
-
if (await
|
|
588
|
+
if (await fs4.pathExists(targetPath)) {
|
|
576
589
|
existingItems.push({ item, platform });
|
|
577
590
|
}
|
|
578
591
|
}
|
|
@@ -589,7 +602,7 @@ async function add(type, url, options) {
|
|
|
589
602
|
initialValue: false
|
|
590
603
|
});
|
|
591
604
|
if (isCancel(shouldOverwrite)) {
|
|
592
|
-
if (tempDir) await
|
|
605
|
+
if (tempDir) await fs4.remove(tempDir);
|
|
593
606
|
if (isSingleShot) break;
|
|
594
607
|
currentType = void 0;
|
|
595
608
|
continue;
|
|
@@ -615,14 +628,14 @@ async function add(type, url, options) {
|
|
|
615
628
|
let currentSourcePath;
|
|
616
629
|
if (url && tempDir) {
|
|
617
630
|
const potentialFile = path5.join(tempDir, item);
|
|
618
|
-
if (await
|
|
631
|
+
if (await fs4.pathExists(potentialFile) && (await fs4.stat(potentialFile)).isFile()) {
|
|
619
632
|
currentSourcePath = potentialFile;
|
|
620
633
|
} else {
|
|
621
634
|
currentSourcePath = tempDir;
|
|
622
635
|
}
|
|
623
636
|
} else {
|
|
624
637
|
const src = path5.join(TYPE_DIRS[normalizedType], item);
|
|
625
|
-
if ((await
|
|
638
|
+
if ((await fs4.stat(src)).isFile()) {
|
|
626
639
|
currentSourcePath = src;
|
|
627
640
|
} else {
|
|
628
641
|
currentSourcePath = src;
|
|
@@ -635,17 +648,17 @@ async function add(type, url, options) {
|
|
|
635
648
|
);
|
|
636
649
|
if ((normalizedType === "agent" || normalizedType === "workflow") && currentSourcePath.endsWith(".md")) {
|
|
637
650
|
const targetPath = path5.join(targetBase, targetItemName);
|
|
638
|
-
if (!overwrite && await
|
|
651
|
+
if (!overwrite && await fs4.pathExists(targetPath)) {
|
|
639
652
|
skippedCount++;
|
|
640
653
|
} else {
|
|
641
|
-
let content = await
|
|
654
|
+
let content = await fs4.readFile(currentSourcePath, "utf-8");
|
|
642
655
|
content = handler.transform(
|
|
643
656
|
content,
|
|
644
657
|
normalizedType,
|
|
645
658
|
path5.parse(item).name
|
|
646
659
|
);
|
|
647
|
-
await
|
|
648
|
-
await
|
|
660
|
+
await fs4.ensureDir(path5.dirname(targetPath));
|
|
661
|
+
await fs4.writeFile(targetPath, content);
|
|
649
662
|
installedCount++;
|
|
650
663
|
}
|
|
651
664
|
continue;
|
|
@@ -668,7 +681,7 @@ async function add(type, url, options) {
|
|
|
668
681
|
}
|
|
669
682
|
}
|
|
670
683
|
if (tempDir) {
|
|
671
|
-
await
|
|
684
|
+
await fs4.remove(tempDir);
|
|
672
685
|
}
|
|
673
686
|
if (errors.length > 0) {
|
|
674
687
|
s.stop(
|
|
@@ -688,7 +701,7 @@ async function add(type, url, options) {
|
|
|
688
701
|
);
|
|
689
702
|
}
|
|
690
703
|
} catch (error) {
|
|
691
|
-
if (tempDir) await
|
|
704
|
+
if (tempDir) await fs4.remove(tempDir);
|
|
692
705
|
cancel(`An error occurred: ${error}`);
|
|
693
706
|
process.exit(1);
|
|
694
707
|
return;
|
|
@@ -713,7 +726,7 @@ import {
|
|
|
713
726
|
spinner as spinner2,
|
|
714
727
|
text
|
|
715
728
|
} from "@clack/prompts";
|
|
716
|
-
import
|
|
729
|
+
import fs5 from "fs-extra";
|
|
717
730
|
import pc2 from "picocolors";
|
|
718
731
|
async function importItem(type, url, options) {
|
|
719
732
|
if (!options?.skipIntro) {
|
|
@@ -773,10 +786,10 @@ async function importItem(type, url, options) {
|
|
|
773
786
|
const shouldFlatten = (normalizedType === "agent" || normalizedType === "workflow") && !isFile;
|
|
774
787
|
const targetPath = shouldFlatten ? targetBaseDir : path6.join(targetBaseDir, itemName);
|
|
775
788
|
if (shouldFlatten) {
|
|
776
|
-
const srcFiles = await
|
|
789
|
+
const srcFiles = await fs5.readdir(tempDir);
|
|
777
790
|
const conflicts = [];
|
|
778
791
|
for (const file of srcFiles) {
|
|
779
|
-
if (await
|
|
792
|
+
if (await fs5.pathExists(path6.join(targetBaseDir, file))) {
|
|
780
793
|
conflicts.push(file);
|
|
781
794
|
}
|
|
782
795
|
}
|
|
@@ -790,40 +803,40 @@ async function importItem(type, url, options) {
|
|
|
790
803
|
initialValue: false
|
|
791
804
|
});
|
|
792
805
|
if (isCancel2(shouldOverwrite) || !shouldOverwrite) {
|
|
793
|
-
await
|
|
806
|
+
await fs5.remove(tempDir);
|
|
794
807
|
return;
|
|
795
808
|
}
|
|
796
809
|
}
|
|
797
|
-
} else if (await
|
|
810
|
+
} else if (await fs5.pathExists(targetPath)) {
|
|
798
811
|
const shouldOverwrite = await confirm2({
|
|
799
812
|
message: `${normalizedType} '${itemName}' already exists in the repo. Overwrite?`,
|
|
800
813
|
initialValue: false
|
|
801
814
|
});
|
|
802
815
|
if (isCancel2(shouldOverwrite) || !shouldOverwrite) {
|
|
803
|
-
await
|
|
816
|
+
await fs5.remove(tempDir);
|
|
804
817
|
return;
|
|
805
818
|
}
|
|
806
819
|
}
|
|
807
820
|
s.start(`Importing ${itemName} to ${targetBaseDir}...`);
|
|
808
|
-
await
|
|
821
|
+
await fs5.ensureDir(targetBaseDir);
|
|
809
822
|
if (isFile) {
|
|
810
|
-
await
|
|
823
|
+
await fs5.copy(path6.join(tempDir, itemName), targetPath, {
|
|
811
824
|
overwrite: true
|
|
812
825
|
});
|
|
813
826
|
} else {
|
|
814
827
|
if (shouldFlatten) {
|
|
815
|
-
await
|
|
828
|
+
await fs5.copy(tempDir, targetBaseDir, { overwrite: true });
|
|
816
829
|
} else {
|
|
817
|
-
await
|
|
830
|
+
await fs5.copy(tempDir, targetPath, { overwrite: true });
|
|
818
831
|
}
|
|
819
832
|
}
|
|
820
833
|
s.stop(pc2.green(`Successfully imported ${itemName}!`));
|
|
821
|
-
await
|
|
834
|
+
await fs5.remove(tempDir);
|
|
822
835
|
if (!options?.skipIntro) {
|
|
823
836
|
outro2(`${normalizedType} available at: ${targetPath}`);
|
|
824
837
|
}
|
|
825
838
|
} catch (error) {
|
|
826
|
-
if (tempDir) await
|
|
839
|
+
if (tempDir) await fs5.remove(tempDir);
|
|
827
840
|
cancel2(`An error occurred: ${error}`);
|
|
828
841
|
process.exit(1);
|
|
829
842
|
return;
|
|
@@ -832,7 +845,7 @@ async function importItem(type, url, options) {
|
|
|
832
845
|
|
|
833
846
|
// src/commands/list.ts
|
|
834
847
|
import { intro as intro3, isCancel as isCancel3, outro as outro3, select as select3 } from "@clack/prompts";
|
|
835
|
-
import
|
|
848
|
+
import fs6 from "fs-extra";
|
|
836
849
|
import pc3 from "picocolors";
|
|
837
850
|
async function performListing(type, local) {
|
|
838
851
|
const normalizedType = type.toLowerCase().endsWith("s") ? type.slice(0, -1) : type.toLowerCase();
|
|
@@ -842,8 +855,8 @@ async function performListing(type, local) {
|
|
|
842
855
|
let foundAny = false;
|
|
843
856
|
for (const [platform, pathStr] of Object.entries(targetPaths)) {
|
|
844
857
|
const fullPath = pathStr;
|
|
845
|
-
if (await
|
|
846
|
-
const entries = await
|
|
858
|
+
if (await fs6.pathExists(fullPath)) {
|
|
859
|
+
const entries = await fs6.readdir(fullPath, {
|
|
847
860
|
withFileTypes: true
|
|
848
861
|
});
|
|
849
862
|
const items = [];
|
|
@@ -882,13 +895,13 @@ async function performListing(type, local) {
|
|
|
882
895
|
return;
|
|
883
896
|
}
|
|
884
897
|
const dirPath = TYPE_DIRS[normalizedType];
|
|
885
|
-
if (!await
|
|
898
|
+
if (!await fs6.pathExists(dirPath)) {
|
|
886
899
|
console.log(
|
|
887
900
|
pc3.yellow(`No ${normalizedType} directory found at: ${dirPath}`)
|
|
888
901
|
);
|
|
889
902
|
return;
|
|
890
903
|
}
|
|
891
|
-
const entries = await
|
|
904
|
+
const entries = await fs6.readdir(dirPath, { withFileTypes: true });
|
|
892
905
|
const items = entries.filter(
|
|
893
906
|
(entry) => entry.isDirectory() || normalizedType !== "skill" && entry.isFile() && entry.name.endsWith(".md")
|
|
894
907
|
).map((entry) => entry.name).sort();
|
|
@@ -963,7 +976,7 @@ import {
|
|
|
963
976
|
select as select4,
|
|
964
977
|
spinner as spinner3
|
|
965
978
|
} from "@clack/prompts";
|
|
966
|
-
import
|
|
979
|
+
import fs7 from "fs-extra";
|
|
967
980
|
import pc4 from "picocolors";
|
|
968
981
|
async function remove(type, options) {
|
|
969
982
|
if (!options?.skipIntro) {
|
|
@@ -993,8 +1006,8 @@ async function remove(type, options) {
|
|
|
993
1006
|
const s = spinner3();
|
|
994
1007
|
s.start("Scanning for installed items...");
|
|
995
1008
|
for (const [platform, pathStr] of Object.entries(targetPaths)) {
|
|
996
|
-
if (await
|
|
997
|
-
const entries = await
|
|
1009
|
+
if (await fs7.pathExists(pathStr)) {
|
|
1010
|
+
const entries = await fs7.readdir(pathStr, {
|
|
998
1011
|
withFileTypes: true
|
|
999
1012
|
});
|
|
1000
1013
|
for (const entry of entries) {
|
|
@@ -1067,10 +1080,10 @@ async function remove(type, options) {
|
|
|
1067
1080
|
if (!targetBase) continue;
|
|
1068
1081
|
for (const item of selectedItems) {
|
|
1069
1082
|
const targetPath = path7.join(targetBase, item);
|
|
1070
|
-
if (await
|
|
1083
|
+
if (await fs7.pathExists(targetPath)) {
|
|
1071
1084
|
sDel.message(`Removing ${pc4.bold(item)} from ${pc4.cyan(platform)}...`);
|
|
1072
1085
|
try {
|
|
1073
|
-
await
|
|
1086
|
+
await fs7.remove(targetPath);
|
|
1074
1087
|
removedCount++;
|
|
1075
1088
|
} catch (err) {
|
|
1076
1089
|
const msg = err instanceof Error ? err.message : String(err);
|