skillio 0.1.15 → 0.1.16
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/cli.js +57 -36
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -861,9 +861,8 @@ var listCommand = defineCommand({
|
|
|
861
861
|
render: () => {
|
|
862
862
|
if (rows.lock.totalCount === 0)
|
|
863
863
|
return "";
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return orphans.map((n) => red(n.name)).join(" ");
|
|
864
|
+
const orphanSet = new Set(orphans.map((n) => n.name));
|
|
865
|
+
return rows.lock.names.map((n) => orphanSet.has(n.name) ? red(n.name) : n.name).join(" ");
|
|
867
866
|
}
|
|
868
867
|
}
|
|
869
868
|
];
|
|
@@ -900,7 +899,6 @@ var listCommand = defineCommand({
|
|
|
900
899
|
});
|
|
901
900
|
|
|
902
901
|
// src/commands/remove.ts
|
|
903
|
-
import { existsSync as existsSync3, lstatSync as lstatSync3 } from "node:fs";
|
|
904
902
|
import { homedir as homedir2 } from "node:os";
|
|
905
903
|
import { dirname as dirname2, join as join3, resolve as resolve3 } from "node:path";
|
|
906
904
|
|
|
@@ -988,17 +986,24 @@ function createConfirmer(opts = {}) {
|
|
|
988
986
|
}
|
|
989
987
|
|
|
990
988
|
// src/utils/fs-rm.ts
|
|
991
|
-
import {
|
|
989
|
+
import { lstatSync as lstatSync2, readdirSync, rmSync } from "node:fs";
|
|
992
990
|
import { join as join2, resolve as resolve2 } from "node:path";
|
|
993
991
|
function isInside(target, root) {
|
|
994
992
|
const t = resolve2(target);
|
|
995
993
|
const r = resolve2(root);
|
|
996
994
|
return t === r || t.startsWith(`${r}/`);
|
|
997
995
|
}
|
|
996
|
+
function lstatOrNull(path) {
|
|
997
|
+
try {
|
|
998
|
+
return lstatSync2(path);
|
|
999
|
+
} catch {
|
|
1000
|
+
return null;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
998
1003
|
function countFiles(path) {
|
|
999
|
-
|
|
1004
|
+
const stat = lstatOrNull(path);
|
|
1005
|
+
if (!stat)
|
|
1000
1006
|
return 0;
|
|
1001
|
-
const stat = lstatSync2(path);
|
|
1002
1007
|
if (stat.isFile())
|
|
1003
1008
|
return 1;
|
|
1004
1009
|
if (!stat.isDirectory())
|
|
@@ -1029,7 +1034,7 @@ function rmSkillDir(path, opts) {
|
|
|
1029
1034
|
if (!safe) {
|
|
1030
1035
|
throw new Error(`Refusing to delete: "${path}" is outside allowed roots`);
|
|
1031
1036
|
}
|
|
1032
|
-
if (!
|
|
1037
|
+
if (!lstatOrNull(path))
|
|
1033
1038
|
return { removed: false, fileCount: 0 };
|
|
1034
1039
|
const fileCount = countFiles(path);
|
|
1035
1040
|
rmSync(path, { recursive: true, force: true });
|
|
@@ -1038,12 +1043,13 @@ function rmSkillDir(path, opts) {
|
|
|
1038
1043
|
|
|
1039
1044
|
// src/commands/remove.ts
|
|
1040
1045
|
function buildLocation(dir) {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1046
|
+
const stat = lstatOrNull(dir);
|
|
1047
|
+
if (!stat)
|
|
1048
|
+
return { kind: "missing", subfolders: 0, files: 0 };
|
|
1049
|
+
if (stat.isSymbolicLink())
|
|
1050
|
+
return { kind: "symlink", subfolders: 0, files: 0 };
|
|
1045
1051
|
const { folders, files } = countFoldersAndFiles(dir);
|
|
1046
|
-
return { kind: "real", folders, files };
|
|
1052
|
+
return { kind: "real", subfolders: folders, files };
|
|
1047
1053
|
}
|
|
1048
1054
|
function rootFor2(base, isGlobal, lockPath) {
|
|
1049
1055
|
return isGlobal ? join3(homedir2(), base, "skills") : join3(dirname2(resolve3(lockPath)), base, "skills");
|
|
@@ -1072,53 +1078,63 @@ function header(targets, verb) {
|
|
|
1072
1078
|
}
|
|
1073
1079
|
function aggregateLocations(infos) {
|
|
1074
1080
|
let folders = 0;
|
|
1081
|
+
let subfolders = 0;
|
|
1075
1082
|
let files = 0;
|
|
1076
1083
|
let symlinks = 0;
|
|
1077
1084
|
for (const info of infos) {
|
|
1078
1085
|
if (info.kind === "real") {
|
|
1079
|
-
folders +=
|
|
1086
|
+
folders += 1;
|
|
1087
|
+
subfolders += info.subfolders;
|
|
1080
1088
|
files += info.files;
|
|
1081
1089
|
} else if (info.kind === "symlink") {
|
|
1082
1090
|
symlinks += 1;
|
|
1083
1091
|
}
|
|
1084
1092
|
}
|
|
1085
|
-
return { folders, files, symlinks, found: infos.some((i) => i.kind !== "missing") };
|
|
1093
|
+
return { folders, subfolders, files, symlinks, found: infos.some((i) => i.kind !== "missing") };
|
|
1086
1094
|
}
|
|
1087
|
-
function
|
|
1088
|
-
const displayLabel = singleName ? `${label}/${singleName}/` : label;
|
|
1095
|
+
function diskCell(infos, variant) {
|
|
1089
1096
|
const agg = aggregateLocations(infos);
|
|
1090
1097
|
if (!agg.found)
|
|
1091
|
-
return
|
|
1098
|
+
return "not found";
|
|
1092
1099
|
const parts = [];
|
|
1093
1100
|
if (agg.folders > 0 || agg.files > 0) {
|
|
1094
|
-
const text = `${plural(agg.folders, "folder")}, ${plural(agg.files, "file")}`;
|
|
1101
|
+
const text = `${plural(agg.folders, "folder")}, ${plural(agg.subfolders, "subfolder")}, ${plural(agg.files, "file")}`;
|
|
1095
1102
|
parts.push(variant === "summary" ? red(text) : green(text));
|
|
1096
1103
|
}
|
|
1097
1104
|
if (agg.symlinks > 0) {
|
|
1098
1105
|
const text = plural(agg.symlinks, "symlink");
|
|
1099
1106
|
parts.push(variant === "summary" ? red(text) : yellow(text));
|
|
1100
1107
|
}
|
|
1101
|
-
return
|
|
1108
|
+
return parts.join(", ");
|
|
1102
1109
|
}
|
|
1103
|
-
function
|
|
1104
|
-
const label = "skills-lock.json";
|
|
1110
|
+
function lockCell(n, variant) {
|
|
1105
1111
|
if (n === 0)
|
|
1106
|
-
return
|
|
1112
|
+
return "not in lock";
|
|
1107
1113
|
if (variant === "kept")
|
|
1108
|
-
return
|
|
1109
|
-
return
|
|
1114
|
+
return green(`${plural(n, "line")} kept`);
|
|
1115
|
+
return red(plural(n, "line"));
|
|
1110
1116
|
}
|
|
1111
1117
|
function printBlock(targets, scope, verb, lockLinesToRemove, diskVariant, lockVariant) {
|
|
1112
1118
|
console.log(header(targets, verb));
|
|
1113
|
-
const
|
|
1119
|
+
const rows = [];
|
|
1114
1120
|
if (scope === "all" || scope === "agents-only") {
|
|
1115
|
-
|
|
1121
|
+
rows.push([
|
|
1122
|
+
".agents/skills/",
|
|
1123
|
+
diskCell(targets.map((t) => t.agents), diskVariant)
|
|
1124
|
+
]);
|
|
1116
1125
|
}
|
|
1117
1126
|
if (scope === "all" || scope === "claude-only") {
|
|
1118
|
-
|
|
1127
|
+
rows.push([
|
|
1128
|
+
".claude/skills/",
|
|
1129
|
+
diskCell(targets.map((t) => t.claude), diskVariant)
|
|
1130
|
+
]);
|
|
1119
1131
|
}
|
|
1120
1132
|
if (scope === "all" || scope === "lock-only") {
|
|
1121
|
-
|
|
1133
|
+
rows.push(["skills-lock.json", lockCell(lockLinesToRemove, lockVariant)]);
|
|
1134
|
+
}
|
|
1135
|
+
const labelWidth = Math.max(...rows.map(([label]) => label.length));
|
|
1136
|
+
for (const [label, cell] of rows) {
|
|
1137
|
+
console.log(`${label.padEnd(labelWidth)} ${cell}`);
|
|
1122
1138
|
}
|
|
1123
1139
|
}
|
|
1124
1140
|
var removeCommand = defineCommand({
|
|
@@ -1190,6 +1206,7 @@ var removeCommand = defineCommand({
|
|
|
1190
1206
|
printBlock(targets, scope, "will be removed from:", lockLinesToRemove, "plan", "removed");
|
|
1191
1207
|
const ask = createConfirmer();
|
|
1192
1208
|
if (!yes) {
|
|
1209
|
+
console.log("");
|
|
1193
1210
|
const ok = await ask("Proceed?");
|
|
1194
1211
|
if (!ok) {
|
|
1195
1212
|
console.log("Aborted");
|
|
@@ -1211,7 +1228,11 @@ var removeCommand = defineCommand({
|
|
|
1211
1228
|
removeSkillFromLock(lockPath, t.name);
|
|
1212
1229
|
lockCleaned = true;
|
|
1213
1230
|
} else if (scope === "all" && lockLinesToRemove > 0) {
|
|
1214
|
-
|
|
1231
|
+
let cleanLock = yes;
|
|
1232
|
+
if (!yes) {
|
|
1233
|
+
console.log("");
|
|
1234
|
+
cleanLock = await ask(`Clean skills-lock.json (${plural(lockLinesToRemove, "line")})?`);
|
|
1235
|
+
}
|
|
1215
1236
|
if (cleanLock) {
|
|
1216
1237
|
for (const t of targets)
|
|
1217
1238
|
removeSkillFromLock(lockPath, t.name);
|
|
@@ -1224,7 +1245,7 @@ var removeCommand = defineCommand({
|
|
|
1224
1245
|
});
|
|
1225
1246
|
|
|
1226
1247
|
// src/commands/usage.ts
|
|
1227
|
-
import { existsSync as
|
|
1248
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
1228
1249
|
import { join as join7 } from "node:path";
|
|
1229
1250
|
|
|
1230
1251
|
// src/readers/claude.ts
|
|
@@ -1558,10 +1579,10 @@ function readClaudeUsage(options) {
|
|
|
1558
1579
|
}
|
|
1559
1580
|
|
|
1560
1581
|
// src/readers/codex.ts
|
|
1561
|
-
import { existsSync as
|
|
1582
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
1562
1583
|
|
|
1563
1584
|
// src/utils/scope.ts
|
|
1564
|
-
import { existsSync as
|
|
1585
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
1565
1586
|
import { homedir as homedir4 } from "node:os";
|
|
1566
1587
|
import { dirname as dirname3, join as join6 } from "node:path";
|
|
1567
1588
|
function detectScope(opts) {
|
|
@@ -1583,7 +1604,7 @@ function encodeClaudeProjectDir(absPath) {
|
|
|
1583
1604
|
function findGitRoot(start) {
|
|
1584
1605
|
let dir = start;
|
|
1585
1606
|
while (true) {
|
|
1586
|
-
if (
|
|
1607
|
+
if (existsSync2(join6(dir, ".git")))
|
|
1587
1608
|
return dir;
|
|
1588
1609
|
const parent = dirname3(dir);
|
|
1589
1610
|
if (parent === dir)
|
|
@@ -1656,7 +1677,7 @@ function readCodexMentions(options) {
|
|
|
1656
1677
|
const historyPath = expandHome(options.history ?? "~/.codex/history.jsonl");
|
|
1657
1678
|
const counts = new Map;
|
|
1658
1679
|
let linesRead = 0;
|
|
1659
|
-
if (!
|
|
1680
|
+
if (!existsSync3(historyPath))
|
|
1660
1681
|
return { counts, filesRead: 0, linesRead: 0 };
|
|
1661
1682
|
for (const line of readFileSync3(historyPath, "utf8").split(`
|
|
1662
1683
|
`)) {
|
|
@@ -1766,7 +1787,7 @@ async function runUsage(args) {
|
|
|
1766
1787
|
});
|
|
1767
1788
|
const claudeProjectsRoot = expandHome("~/.claude/projects");
|
|
1768
1789
|
const claudeRoot = args.root ?? (scope.projectRoot ? join7(claudeProjectsRoot, encodeClaudeProjectDir(scope.projectRoot)) : claudeProjectsRoot);
|
|
1769
|
-
const claudeRootMissing = !args.root && !!scope.projectRoot && !
|
|
1790
|
+
const claudeRootMissing = !args.root && !!scope.projectRoot && !existsSync4(claudeRoot);
|
|
1770
1791
|
const lockPath = getLockPath(args.global);
|
|
1771
1792
|
const skillUniverse = discoverSkills({
|
|
1772
1793
|
isGlobal: args.global,
|