@danieldeusing/seedr 0.1.97 → 0.1.98
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/{chunk-PEGEA2KN.js → chunk-NQOS5TI7.js} +159 -22
- package/dist/cli.js +840 -340
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@ function registryDirName(config) {
|
|
|
18
18
|
}
|
|
19
19
|
return value;
|
|
20
20
|
}
|
|
21
|
-
var ALL_TYPES = ["skill", "plugin", "hook", "agent", "mcp", "settings", "command"];
|
|
21
|
+
var ALL_TYPES = ["skill", "plugin", "hook", "agent", "mcp", "settings", "command", "rule"];
|
|
22
22
|
var KNOWN_TYPES = new Set(ALL_TYPES);
|
|
23
23
|
function typeDirName(type) {
|
|
24
24
|
return type === "settings" || type === "mcp" ? type : `${type}s`;
|
|
@@ -46,6 +46,23 @@ function canonicalAgents(values) {
|
|
|
46
46
|
const present = new Set(values.map(canonicalAgent).filter((a) => a !== null));
|
|
47
47
|
return CANONICAL_AGENTS.filter((a) => present.has(a));
|
|
48
48
|
}
|
|
49
|
+
var AGENT_COMPATIBILITY = {
|
|
50
|
+
skill: ["claude", "copilot", "antigravity", "codex", "opencode"],
|
|
51
|
+
command: ["claude"],
|
|
52
|
+
// Copilot's subagent files carry the same name/description frontmatter.
|
|
53
|
+
// OpenCode's do not — theirs use `mode` and a `tools` map — so porting there
|
|
54
|
+
// needs a frontmatter translation, not a path.
|
|
55
|
+
agent: ["claude", "copilot"],
|
|
56
|
+
hook: ["claude"],
|
|
57
|
+
plugin: ["claude", "copilot", "antigravity", "codex", "opencode"],
|
|
58
|
+
settings: ["claude"],
|
|
59
|
+
mcp: ["claude", "codex", "opencode", "copilot"],
|
|
60
|
+
rule: ["claude", "copilot", "antigravity", "codex", "opencode"]
|
|
61
|
+
};
|
|
62
|
+
function isTypeSupported(type, agent) {
|
|
63
|
+
const canonical = canonicalAgent(agent);
|
|
64
|
+
return canonical !== null && AGENT_COMPATIBILITY[type].includes(canonical);
|
|
65
|
+
}
|
|
49
66
|
|
|
50
67
|
// ../registry-ops/src/sourceTypes.ts
|
|
51
68
|
var CANONICAL_SOURCE_TYPES = ["official", "seedr", "community"];
|
|
@@ -759,14 +776,20 @@ async function fetchItemToDestination(item, destPath) {
|
|
|
759
776
|
import { homedir as homedir2 } from "os";
|
|
760
777
|
import { join as join14 } from "path";
|
|
761
778
|
var home = homedir2();
|
|
779
|
+
var claudeUserRoot = () => process.env.CLAUDE_CONFIG_DIR || join14(home, ".claude");
|
|
762
780
|
var SKILL_DIRECTORY = {
|
|
763
781
|
path: "skills"
|
|
764
782
|
};
|
|
765
783
|
var ANTIGRAVITY = {
|
|
766
784
|
name: "Google Antigravity",
|
|
767
785
|
shortName: "antigravity",
|
|
786
|
+
// Project content is the agent-neutral `.agents/` tree, which IS Antigravity's
|
|
787
|
+
// own project root. The personal tier is not the same spelling: the shipped
|
|
788
|
+
// CLI reads `~/.gemini/config/skills`, and the vendor documentation states
|
|
789
|
+
// outright that `~/.agents` does not exist for it. `~/.gemini/skills` is the
|
|
790
|
+
// predecessor Gemini CLI location and is not written.
|
|
768
791
|
projectRoot: ".agents",
|
|
769
|
-
userRoot: join14(home, ".
|
|
792
|
+
userRoot: join14(home, ".gemini", "config"),
|
|
770
793
|
contentTypes: { skill: SKILL_DIRECTORY }
|
|
771
794
|
};
|
|
772
795
|
var CODING_AGENTS = {
|
|
@@ -774,7 +797,7 @@ var CODING_AGENTS = {
|
|
|
774
797
|
name: "Claude Code",
|
|
775
798
|
shortName: "claude",
|
|
776
799
|
projectRoot: ".claude",
|
|
777
|
-
userRoot:
|
|
800
|
+
userRoot: claudeUserRoot(),
|
|
778
801
|
contentTypes: {
|
|
779
802
|
skill: SKILL_DIRECTORY,
|
|
780
803
|
command: {
|
|
@@ -800,9 +823,15 @@ var CODING_AGENTS = {
|
|
|
800
823
|
copilot: {
|
|
801
824
|
name: "GitHub Copilot",
|
|
802
825
|
shortName: "copilot",
|
|
826
|
+
// Project content is `.github/`, but the personal tier is `~/.copilot/` —
|
|
827
|
+
// the two are not the same spelling. `~/.github/skills` is read by nothing;
|
|
828
|
+
// `~/.copilot/skills` is what the CLI itself populates.
|
|
803
829
|
projectRoot: ".github",
|
|
804
|
-
userRoot: join14(home, ".
|
|
805
|
-
|
|
830
|
+
userRoot: join14(home, ".copilot"),
|
|
831
|
+
// Subagents are `<name>.agent.md` under `agents/`, with the same
|
|
832
|
+
// `name` + `description` frontmatter a Claude subagent carries — confirmed
|
|
833
|
+
// from files on a real machine.
|
|
834
|
+
contentTypes: { skill: SKILL_DIRECTORY, agent: { path: "agents" } }
|
|
806
835
|
},
|
|
807
836
|
antigravity: ANTIGRAVITY,
|
|
808
837
|
gemini: ANTIGRAVITY,
|
|
@@ -849,7 +878,7 @@ function getSettingsPath(scope, cwd = process.cwd()) {
|
|
|
849
878
|
case "project":
|
|
850
879
|
return join14(cwd, ".claude/settings.json");
|
|
851
880
|
case "user":
|
|
852
|
-
return join14(
|
|
881
|
+
return join14(claudeUserRoot(), "settings.json");
|
|
853
882
|
case "local":
|
|
854
883
|
return join14(cwd, ".claude/settings.local.json");
|
|
855
884
|
}
|
|
@@ -858,11 +887,13 @@ function getMcpConfigPath(agent, scope, cwd = process.cwd()) {
|
|
|
858
887
|
const isUser = scope === "user";
|
|
859
888
|
switch (canonicalAgent(agent) ?? agent) {
|
|
860
889
|
case "claude":
|
|
861
|
-
return isUser ? join14(home, ".claude.json") : join14(cwd, ".mcp.json");
|
|
890
|
+
return isUser ? join14(process.env.CLAUDE_CONFIG_DIR || home, ".claude.json") : join14(cwd, ".mcp.json");
|
|
862
891
|
case "codex":
|
|
863
892
|
return isUser ? join14(home, ".codex", "config.toml") : join14(cwd, ".codex", "config.toml");
|
|
864
893
|
case "opencode":
|
|
865
894
|
return isUser ? join14(home, ".config", "opencode", "opencode.json") : join14(cwd, "opencode.json");
|
|
895
|
+
case "copilot":
|
|
896
|
+
return isUser ? join14(home, ".copilot", "mcp-config.json") : join14(cwd, ".github", "mcp.json");
|
|
866
897
|
default:
|
|
867
898
|
throw new Error(`${agent} has no verified MCP configuration format`);
|
|
868
899
|
}
|
|
@@ -1041,18 +1072,94 @@ function error(message) {
|
|
|
1041
1072
|
}
|
|
1042
1073
|
|
|
1043
1074
|
// src/handlers/skill.ts
|
|
1044
|
-
import { relative as relative5, dirname as
|
|
1075
|
+
import { relative as relative5, dirname as dirname8, join as join15 } from "path";
|
|
1045
1076
|
import { homedir as homedir3 } from "os";
|
|
1046
1077
|
import { readdir as readdir2, symlink as symlink2 } from "fs/promises";
|
|
1047
1078
|
import chalk2 from "chalk";
|
|
1048
1079
|
import ora from "ora";
|
|
1080
|
+
|
|
1081
|
+
// src/utils/json.ts
|
|
1082
|
+
import { readFile as readFile4, stat as stat2 } from "fs/promises";
|
|
1083
|
+
import { dirname as dirname7 } from "path";
|
|
1084
|
+
async function readJson(path) {
|
|
1085
|
+
try {
|
|
1086
|
+
const content = await readFile4(path, "utf-8");
|
|
1087
|
+
return JSON.parse(content);
|
|
1088
|
+
} catch (error2) {
|
|
1089
|
+
if (error2.code === "ENOENT") {
|
|
1090
|
+
return {};
|
|
1091
|
+
}
|
|
1092
|
+
if (error2 instanceof SyntaxError) {
|
|
1093
|
+
throw new Error(`${path} is not valid JSON: ${error2.message}`, { cause: error2 });
|
|
1094
|
+
}
|
|
1095
|
+
throw error2;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
async function existingFileMode(path) {
|
|
1099
|
+
try {
|
|
1100
|
+
return (await stat2(path)).mode & 511;
|
|
1101
|
+
} catch (error2) {
|
|
1102
|
+
if (error2.code === "ENOENT") return void 0;
|
|
1103
|
+
throw error2;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async function writeJson(path, data) {
|
|
1107
|
+
await ensureDir(dirname7(path));
|
|
1108
|
+
const mode = await existingFileMode(path);
|
|
1109
|
+
await writeFileAtomic(path, JSON.stringify(data, null, 2) + "\n", { mode });
|
|
1110
|
+
}
|
|
1111
|
+
function deepMerge(target, source) {
|
|
1112
|
+
const result = { ...target };
|
|
1113
|
+
for (const key of Object.keys(source)) {
|
|
1114
|
+
const sourceValue = source[key];
|
|
1115
|
+
const targetValue = result[key];
|
|
1116
|
+
if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
1117
|
+
result[key] = deepMerge(
|
|
1118
|
+
targetValue,
|
|
1119
|
+
sourceValue
|
|
1120
|
+
);
|
|
1121
|
+
} else if (sourceValue !== void 0) {
|
|
1122
|
+
result[key] = sourceValue;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return result;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// src/handlers/skill.ts
|
|
1049
1129
|
var SLUG_LABEL = "skill slug";
|
|
1050
|
-
|
|
1130
|
+
function readsCentralDir(agent, scope) {
|
|
1131
|
+
const canonical = canonicalAgent(agent) ?? agent;
|
|
1132
|
+
if (canonical === "antigravity") return scope !== "user";
|
|
1133
|
+
return canonical === "codex" || canonical === "opencode";
|
|
1134
|
+
}
|
|
1135
|
+
var OWNERS_FILE = ".seedr-central-owners.json";
|
|
1136
|
+
async function readOwners(scope, cwd) {
|
|
1137
|
+
return readJson(join15(centralSkillsDir(scope, cwd), OWNERS_FILE));
|
|
1138
|
+
}
|
|
1139
|
+
async function writeOwners(owners, scope, cwd) {
|
|
1140
|
+
await writeJson(join15(centralSkillsDir(scope, cwd), OWNERS_FILE), owners);
|
|
1141
|
+
}
|
|
1142
|
+
async function addOwners(slug, agents, scope, cwd) {
|
|
1143
|
+
if (agents.length === 0) return;
|
|
1144
|
+
const owners = await readOwners(scope, cwd);
|
|
1145
|
+
owners[slug] = [.../* @__PURE__ */ new Set([...owners[slug] ?? [], ...agents])];
|
|
1146
|
+
await writeOwners(owners, scope, cwd);
|
|
1147
|
+
}
|
|
1148
|
+
async function dropOwner(slug, agent, scope, cwd) {
|
|
1149
|
+
const owners = await readOwners(scope, cwd);
|
|
1150
|
+
const recorded = owners[slug];
|
|
1151
|
+
if (!recorded) return [];
|
|
1152
|
+
const remaining = recorded.filter((owner) => owner !== (canonicalAgent(agent) ?? agent));
|
|
1153
|
+
if (remaining.length > 0) owners[slug] = remaining;
|
|
1154
|
+
else delete owners[slug];
|
|
1155
|
+
await writeOwners(owners, scope, cwd);
|
|
1156
|
+
return remaining;
|
|
1157
|
+
}
|
|
1051
1158
|
function getScopeRoot(scope, cwd) {
|
|
1052
1159
|
return scope === "user" ? homedir3() : cwd;
|
|
1053
1160
|
}
|
|
1054
1161
|
function centralSkillsDir(scope, cwd) {
|
|
1055
|
-
return
|
|
1162
|
+
return dirname8(getAgentsPath("skill", "any-slug", scope, cwd));
|
|
1056
1163
|
}
|
|
1057
1164
|
async function resolveCentralPath(slug, scope, cwd) {
|
|
1058
1165
|
const scopeRoot = getScopeRoot(scope, cwd);
|
|
@@ -1077,9 +1184,9 @@ async function installToCentralLocation(item, sourcePath, scope, force, cwd) {
|
|
|
1077
1184
|
return { centralPath, created: !existed };
|
|
1078
1185
|
}
|
|
1079
1186
|
async function createAgentSymlink(centralPath, destPath) {
|
|
1080
|
-
await ensureDir(
|
|
1187
|
+
await ensureDir(dirname8(destPath));
|
|
1081
1188
|
await removePathEntry(destPath);
|
|
1082
|
-
const relPath = relative5(
|
|
1189
|
+
const relPath = relative5(dirname8(destPath), centralPath);
|
|
1083
1190
|
await symlink2(relPath, destPath);
|
|
1084
1191
|
}
|
|
1085
1192
|
async function installSkillForAgent(item, agent, scope, method, force, cwd, centralPath) {
|
|
@@ -1121,7 +1228,7 @@ async function installSkill(item, agents, scope, method, force, cwd = process.cw
|
|
|
1121
1228
|
central = await installToCentralLocation(item, sourcePath, scope, force, cwd);
|
|
1122
1229
|
}
|
|
1123
1230
|
for (const agent of agents) {
|
|
1124
|
-
if (
|
|
1231
|
+
if (readsCentralDir(agent, scope) && central) {
|
|
1125
1232
|
results.push({ agent, success: true, path: central.centralPath });
|
|
1126
1233
|
continue;
|
|
1127
1234
|
}
|
|
@@ -1138,15 +1245,30 @@ async function installSkill(item, agents, scope, method, force, cwd = process.cw
|
|
|
1138
1245
|
}
|
|
1139
1246
|
if (central?.created && !results.some((result) => result.success)) {
|
|
1140
1247
|
await removePathEntry(central.centralPath);
|
|
1248
|
+
return results;
|
|
1249
|
+
}
|
|
1250
|
+
if (central) {
|
|
1251
|
+
const centralReaders = agents.filter(
|
|
1252
|
+
(agent) => readsCentralDir(agent, scope) && results.some((result) => result.agent === agent && result.success)
|
|
1253
|
+
);
|
|
1254
|
+
await addOwners(item.slug, centralReaders, scope, cwd);
|
|
1141
1255
|
}
|
|
1142
1256
|
return results;
|
|
1143
1257
|
}
|
|
1144
1258
|
async function uninstallSkill(slug, agent, scope, cwd = process.cwd()) {
|
|
1145
1259
|
assertValidSlug(slug, SLUG_LABEL);
|
|
1260
|
+
const central = await resolveCentralPath(slug, scope, cwd);
|
|
1146
1261
|
const destPath = await resolveAgentSkillPath(agent, slug, scope, cwd);
|
|
1147
|
-
if (
|
|
1148
|
-
|
|
1149
|
-
|
|
1262
|
+
if (readsCentralDir(agent, scope) || destPath === central) {
|
|
1263
|
+
const remaining = await dropOwner(slug, agent, scope, cwd);
|
|
1264
|
+
if (remaining.length > 0) {
|
|
1265
|
+
return true;
|
|
1266
|
+
}
|
|
1267
|
+
return removePathEntry(central);
|
|
1268
|
+
}
|
|
1269
|
+
if (destPath && await removePathEntry(destPath)) {
|
|
1270
|
+
await dropOwner(slug, agent, scope, cwd);
|
|
1271
|
+
return true;
|
|
1150
1272
|
}
|
|
1151
1273
|
return false;
|
|
1152
1274
|
}
|
|
@@ -1154,13 +1276,21 @@ async function getInstalledSkills(agent, scope, cwd = process.cwd()) {
|
|
|
1154
1276
|
const dirs = /* @__PURE__ */ new Set();
|
|
1155
1277
|
const own = getContentPath(agent, "skill", scope, cwd);
|
|
1156
1278
|
if (own) dirs.add(own);
|
|
1157
|
-
if (
|
|
1279
|
+
if (readsCentralDir(agent, scope)) dirs.add(centralSkillsDir(scope, cwd));
|
|
1280
|
+
const owners = await readOwners(scope, cwd);
|
|
1281
|
+
const centralDir = centralSkillsDir(scope, cwd);
|
|
1282
|
+
const canonical = canonicalAgent(agent) ?? agent;
|
|
1283
|
+
const isInstalledHere = (entry, dir) => {
|
|
1284
|
+
if (entry.name.startsWith(".")) return false;
|
|
1285
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) return false;
|
|
1286
|
+
const recorded = dir === centralDir ? owners[entry.name] : void 0;
|
|
1287
|
+
return !recorded || recorded.includes(canonical);
|
|
1288
|
+
};
|
|
1158
1289
|
const slugs = /* @__PURE__ */ new Set();
|
|
1159
1290
|
for (const dir of dirs) {
|
|
1160
1291
|
if (!await exists(dir)) continue;
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
if ((entry.isDirectory() || entry.isSymbolicLink()) && !entry.name.startsWith(".")) slugs.add(entry.name);
|
|
1292
|
+
for (const entry of await readdir2(dir, { withFileTypes: true })) {
|
|
1293
|
+
if (isInstalledHere(entry, dir)) slugs.add(entry.name);
|
|
1164
1294
|
}
|
|
1165
1295
|
}
|
|
1166
1296
|
return [...slugs];
|
|
@@ -1172,7 +1302,7 @@ async function planSkill(item, agents, scope, method, cwd) {
|
|
|
1172
1302
|
let centralPath;
|
|
1173
1303
|
if (method === "symlink") {
|
|
1174
1304
|
centralPath = await resolveCentralPath(item.slug, scope, cwd);
|
|
1175
|
-
const sharedBy = agents.filter((agent) =>
|
|
1305
|
+
const sharedBy = agents.filter((agent) => readsCentralDir(agent, scope));
|
|
1176
1306
|
changes.push({
|
|
1177
1307
|
agent: "shared",
|
|
1178
1308
|
kind: await kindFor(centralPath),
|
|
@@ -1181,7 +1311,7 @@ async function planSkill(item, agents, scope, method, cwd) {
|
|
|
1181
1311
|
});
|
|
1182
1312
|
}
|
|
1183
1313
|
for (const agent of agents) {
|
|
1184
|
-
if (centralPath &&
|
|
1314
|
+
if (centralPath && readsCentralDir(agent, scope)) continue;
|
|
1185
1315
|
const destPath = await resolveAgentSkillPath(agent, item.slug, scope, cwd);
|
|
1186
1316
|
if (!destPath) throw new Error(`${CODING_AGENTS[agent].name} does not support skills`);
|
|
1187
1317
|
changes.push({
|
|
@@ -1208,10 +1338,13 @@ var skillHandler = {
|
|
|
1208
1338
|
};
|
|
1209
1339
|
|
|
1210
1340
|
export {
|
|
1341
|
+
ALL_TYPES,
|
|
1211
1342
|
mainFileName,
|
|
1212
1343
|
isLegacyAgent,
|
|
1213
1344
|
canonicalAgent,
|
|
1214
1345
|
canonicalAgents,
|
|
1346
|
+
AGENT_COMPATIBILITY,
|
|
1347
|
+
isTypeSupported,
|
|
1215
1348
|
SLUG_PATTERN2 as SLUG_PATTERN,
|
|
1216
1349
|
MAX_SLUG_LENGTH2 as MAX_SLUG_LENGTH,
|
|
1217
1350
|
isValidSlug2 as isValidSlug,
|
|
@@ -1242,6 +1375,7 @@ export {
|
|
|
1242
1375
|
fetchItemFile,
|
|
1243
1376
|
getItemSourcePath,
|
|
1244
1377
|
fetchItemToDestination,
|
|
1378
|
+
claudeUserRoot,
|
|
1245
1379
|
CODING_AGENTS,
|
|
1246
1380
|
ALL_AGENTS,
|
|
1247
1381
|
getAgentConfig,
|
|
@@ -1269,6 +1403,9 @@ export {
|
|
|
1269
1403
|
success,
|
|
1270
1404
|
warn,
|
|
1271
1405
|
error,
|
|
1406
|
+
readJson,
|
|
1407
|
+
writeJson,
|
|
1408
|
+
deepMerge,
|
|
1272
1409
|
installSkill,
|
|
1273
1410
|
uninstallSkill,
|
|
1274
1411
|
getInstalledSkills,
|