@danieldeusing/seedr 0.1.91 → 0.1.93

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.
@@ -2,17 +2,30 @@
2
2
 
3
3
  // src/config/registry.ts
4
4
  import { readFile as readFile3, readdir, writeFile as writeFile2, mkdir as mkdir2, mkdtemp, rm as rm2 } from "fs/promises";
5
- import { existsSync } from "fs";
5
+ import { existsSync as existsSync11 } from "fs";
6
6
  import { tmpdir } from "os";
7
- import { join as join3, dirname as dirname2 } from "path";
7
+ import { join as join13, dirname as dirname6 } from "path";
8
8
  import { fileURLToPath } from "url";
9
9
 
10
10
  // ../registry-ops/src/paths.ts
11
+ var DEFAULT_REGISTRY_DIR = "registry";
12
+ function registryDirName(config) {
13
+ if (typeof config !== "object" || config === null) return DEFAULT_REGISTRY_DIR;
14
+ const value = config.registryDir;
15
+ if (value === void 0) return DEFAULT_REGISTRY_DIR;
16
+ if (typeof value !== "string" || !/^registry[a-z0-9._-]*$/i.test(value)) {
17
+ throw new Error(`seedr.config.json: registryDir must be a single directory name starting with "registry", not ${JSON.stringify(value)}`);
18
+ }
19
+ return value;
20
+ }
11
21
  var ALL_TYPES = ["skill", "plugin", "hook", "agent", "mcp", "settings", "command"];
12
22
  var KNOWN_TYPES = new Set(ALL_TYPES);
13
23
  function typeDirName(type) {
14
24
  return type === "settings" || type === "mcp" ? type : `${type}s`;
15
25
  }
26
+ function mainFileName(type) {
27
+ return type === "skill" ? "SKILL.md" : `${type}.md`;
28
+ }
16
29
 
17
30
  // ../registry-ops/src/agents.ts
18
31
  var CANONICAL_AGENTS = ["claude", "copilot", "antigravity", "codex", "opencode"];
@@ -36,23 +49,100 @@ function canonicalAgents(values) {
36
49
 
37
50
  // ../registry-ops/src/sourceTypes.ts
38
51
  var CANONICAL_SOURCE_TYPES = ["official", "seedr", "community"];
39
- var SOURCE_TYPE_ALIASES = { toolr: "seedr" };
40
- var KNOWN_SOURCE_TYPES = [...CANONICAL_SOURCE_TYPES, ...Object.keys(SOURCE_TYPE_ALIASES)];
41
52
  function isCanonicalSourceType(value) {
42
53
  return typeof value === "string" && CANONICAL_SOURCE_TYPES.includes(value);
43
54
  }
44
- function isLegacySourceType(value) {
45
- return typeof value === "string" && Object.hasOwn(SOURCE_TYPE_ALIASES, value);
46
- }
47
55
  function canonicalSourceType(value) {
48
- if (isCanonicalSourceType(value)) return value;
49
- if (isLegacySourceType(value)) return SOURCE_TYPE_ALIASES[value];
50
- return null;
56
+ return isCanonicalSourceType(value) ? value : null;
51
57
  }
52
58
  function isFirstParty(sourceType) {
53
59
  return canonicalSourceType(sourceType) === "seedr";
54
60
  }
55
61
 
62
+ // ../registry-ops/src/fsPaths.ts
63
+ import { existsSync, readFileSync } from "fs";
64
+ import { dirname, join } from "path";
65
+ var REPO_CONFIG_FILE = "seedr.config.json";
66
+ function resolveRegistryDir(repoRoot) {
67
+ const config = join(repoRoot, REPO_CONFIG_FILE);
68
+ if (!existsSync(config)) return join(repoRoot, DEFAULT_REGISTRY_DIR);
69
+ let parsed;
70
+ try {
71
+ parsed = JSON.parse(readFileSync(config, "utf8"));
72
+ } catch (error2) {
73
+ throw new Error(`${REPO_CONFIG_FILE} is not readable JSON: ${error2.message}`, { cause: error2 });
74
+ }
75
+ return join(repoRoot, registryDirName(parsed));
76
+ }
77
+
78
+ // ../registry-ops/src/hash.ts
79
+ import { createHash } from "crypto";
80
+ import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "fs";
81
+ import { join as join2, relative } from "path";
82
+
83
+ // ../registry-ops/src/localSource.ts
84
+ import { createHash as createHash2 } from "crypto";
85
+ import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync } from "fs";
86
+ import { basename, join as join3, relative as relative2 } from "path";
87
+
88
+ // ../registry-ops/src/gitIgnore.ts
89
+ import { spawnSync } from "child_process";
90
+
91
+ // ../registry-ops/src/localSources.ts
92
+ import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
93
+ import { dirname as dirname2, join as join4 } from "path";
94
+ var LOCAL_SOURCES_FILE = join4(".seedr", "local-sources.json");
95
+
96
+ // ../registry-ops/src/sourceDiff.ts
97
+ import { spawnSync as spawnSync2 } from "child_process";
98
+ import { existsSync as existsSync5, statSync as statSync2 } from "fs";
99
+ import { basename as basename2, join as join5 } from "path";
100
+
101
+ // ../registry-ops/src/read.ts
102
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "fs";
103
+ import { join as join6 } from "path";
104
+
105
+ // ../registry-ops/src/compile.ts
106
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
107
+
108
+ // ../registry-ops/src/identity.ts
109
+ import { execFile } from "child_process";
110
+ import { promisify } from "util";
111
+ var execFileAsync = promisify(execFile);
112
+
113
+ // ../registry-ops/src/ops/addLocal.ts
114
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, statSync as statSync4, writeFileSync as writeFileSync3 } from "fs";
115
+ import { basename as basename3, join as join8 } from "path";
116
+
117
+ // ../registry-ops/src/ops/copy.ts
118
+ import { copyFileSync, mkdirSync as mkdirSync3, readdirSync as readdirSync4, realpathSync, rmdirSync, rmSync, statSync as statSync3 } from "fs";
119
+ import { join as join7 } from "path";
120
+
121
+ // ../registry-ops/src/ops/addRemote.ts
122
+ import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
123
+
124
+ // ../registry-ops/src/ops/remove.ts
125
+ import { rmSync as rmSync2 } from "fs";
126
+
127
+ // ../registry-ops/src/ops/setLabels.ts
128
+ import { writeFileSync as writeFileSync5 } from "fs";
129
+
130
+ // ../registry-ops/src/ops/source.ts
131
+ import { existsSync as existsSync8, mkdirSync as mkdirSync6, rmSync as rmSync3, statSync as statSync5, writeFileSync as writeFileSync6 } from "fs";
132
+ import { basename as basename4, join as join9 } from "path";
133
+
134
+ // ../registry-ops/src/ops/update.ts
135
+ import { existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
136
+ import { dirname as dirname3, resolve, sep } from "path";
137
+
138
+ // ../registry-ops/src/tx.ts
139
+ import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync6, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
140
+ import { dirname as dirname4, join as join10, relative as relative3, resolve as resolve2 } from "path";
141
+ var DEFAULT_LOCK_STALE_MS = 10 * 60 * 1e3;
142
+
143
+ // ../registry-ops/src/migrate.ts
144
+ import { writeFileSync as writeFileSync9 } from "fs";
145
+
56
146
  // src/utils/slug.ts
57
147
  var SLUG_PATTERN2 = /^[a-z0-9][a-z0-9-]*$/;
58
148
  var MAX_SLUG_LENGTH2 = 100;
@@ -68,11 +158,11 @@ function assertValidSlug(value, what = "item slug") {
68
158
  }
69
159
 
70
160
  // src/utils/digest.ts
71
- import { createHash } from "crypto";
161
+ import { createHash as createHash3 } from "crypto";
72
162
  import { readFile } from "fs/promises";
73
- import { join } from "path";
163
+ import { join as join11 } from "path";
74
164
  function sha256Hex(bytes) {
75
- return createHash("sha256").update(bytes).digest("hex");
165
+ return createHash3("sha256").update(bytes).digest("hex");
76
166
  }
77
167
  function digestFromFileHashes(entries) {
78
168
  const sorted = [...entries].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -88,7 +178,7 @@ async function computeContentDigest(root, relativePaths) {
88
178
  const entries = await Promise.all(
89
179
  relativePaths.map(async (relativePath) => ({
90
180
  path: relativePath,
91
- sha256: sha256Hex(await readFile(join(root, ...relativePath.split("/"))))
181
+ sha256: sha256Hex(await readFile(join11(root, ...relativePath.split("/"))))
92
182
  }))
93
183
  );
94
184
  return digestFromFileHashes(entries);
@@ -132,7 +222,7 @@ import {
132
222
  } from "fs/promises";
133
223
  import { randomBytes } from "crypto";
134
224
  import { homedir } from "os";
135
- import { basename, dirname, join as join2, relative, resolve, isAbsolute, sep } from "path";
225
+ import { basename as basename5, dirname as dirname5, join as join12, relative as relative4, resolve as resolve3, isAbsolute, sep as sep2 } from "path";
136
226
  async function exists(path) {
137
227
  try {
138
228
  await access(path);
@@ -165,11 +255,11 @@ function assertSafePathSegment(value, what) {
165
255
  }
166
256
  }
167
257
  function isStrictDescendant(root, candidate) {
168
- const rel = relative(root, candidate);
169
- return rel !== "" && !isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${sep}`);
258
+ const rel = relative4(root, candidate);
259
+ return rel !== "" && !isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${sep2}`);
170
260
  }
171
261
  function isSameOrDescendant(root, candidate) {
172
- return relative(root, candidate) === "" || isStrictDescendant(root, candidate);
262
+ return relative4(root, candidate) === "" || isStrictDescendant(root, candidate);
173
263
  }
174
264
  async function realpathOrNull(path) {
175
265
  try {
@@ -179,8 +269,8 @@ async function realpathOrNull(path) {
179
269
  }
180
270
  }
181
271
  async function resolveContained(root, ...segments) {
182
- const absoluteRoot = resolve(root);
183
- const resolved = resolve(absoluteRoot, ...segments);
272
+ const absoluteRoot = resolve3(root);
273
+ const resolved = resolve3(absoluteRoot, ...segments);
184
274
  if (!isStrictDescendant(absoluteRoot, resolved)) {
185
275
  throw new Error(`Refusing path outside ${absoluteRoot}: ${resolved}`);
186
276
  }
@@ -188,7 +278,7 @@ async function resolveContained(root, ...segments) {
188
278
  if (realRoot === null) {
189
279
  return resolved;
190
280
  }
191
- let ancestor = dirname(resolved);
281
+ let ancestor = dirname5(resolved);
192
282
  for (; ; ) {
193
283
  const realAncestor = await realpathOrNull(ancestor);
194
284
  if (realAncestor !== null) {
@@ -199,16 +289,16 @@ async function resolveContained(root, ...segments) {
199
289
  }
200
290
  return resolved;
201
291
  }
202
- const parent = dirname(ancestor);
203
- if (parent === ancestor || relative(absoluteRoot, ancestor) === "") {
292
+ const parent = dirname5(ancestor);
293
+ if (parent === ancestor || relative4(absoluteRoot, ancestor) === "") {
204
294
  return resolved;
205
295
  }
206
296
  ancestor = parent;
207
297
  }
208
298
  }
209
299
  async function assertDirectoryWithin(dir, scopeRoot, what) {
210
- const realRoot = await realpathOrNull(resolve(scopeRoot));
211
- const realDir = await realpathOrNull(resolve(dir));
300
+ const realRoot = await realpathOrNull(resolve3(scopeRoot));
301
+ const realDir = await realpathOrNull(resolve3(dir));
212
302
  if (realRoot === null || realDir === null) {
213
303
  throw new Error(`${what} ${dir} could not be resolved`);
214
304
  }
@@ -232,7 +322,7 @@ async function removePathEntry(path) {
232
322
  return true;
233
323
  }
234
324
  async function moveDirectory(source, destination) {
235
- await mkdir(dirname(destination), { recursive: true });
325
+ await mkdir(dirname5(destination), { recursive: true });
236
326
  try {
237
327
  await rename(source, destination);
238
328
  } catch (error2) {
@@ -242,7 +332,7 @@ async function moveDirectory(source, destination) {
242
332
  }
243
333
  }
244
334
  async function writeFileAtomic(path, data, options = {}) {
245
- const tempPath = join2(dirname(path), `${basename(path)}.${randomBytes(6).toString("hex")}.tmp`);
335
+ const tempPath = join12(dirname5(path), `${basename5(path)}.${randomBytes(6).toString("hex")}.tmp`);
246
336
  try {
247
337
  await writeFile(tempPath, data, options.mode === void 0 ? {} : { mode: options.mode });
248
338
  await rename(tempPath, path);
@@ -268,31 +358,31 @@ async function restoreFile(path, snapshot) {
268
358
  await writeFileAtomic(path, snapshot.content, { mode: snapshot.mode });
269
359
  }
270
360
  async function installFile(source, destination, method) {
271
- await ensureDir(dirname(destination));
361
+ await ensureDir(dirname5(destination));
272
362
  await removePathEntry(destination);
273
363
  if (method === "symlink") {
274
- const relPath = relative(dirname(destination), source);
364
+ const relPath = relative4(dirname5(destination), source);
275
365
  await symlink(relPath, destination);
276
366
  } else {
277
367
  await copyFile(source, destination);
278
368
  }
279
369
  }
280
370
  async function writeTextFile(path, content) {
281
- await ensureDir(dirname(path));
371
+ await ensureDir(dirname5(path));
282
372
  await writeFile(path, content, "utf-8");
283
373
  }
284
374
  function getAgentsPath(contentType, slug, scope, cwd) {
285
375
  const base = scope === "user" ? homedir() : cwd;
286
- return join2(base, ".agents", contentType + "s", slug);
376
+ return join12(base, ".agents", contentType + "s", slug);
287
377
  }
288
378
  async function copyDirectory(source, destination) {
289
379
  await cp(source, destination, { recursive: true });
290
380
  }
291
381
  async function installDirectory(source, destination, method) {
292
- await ensureDir(dirname(destination));
382
+ await ensureDir(dirname5(destination));
293
383
  await removePathEntry(destination);
294
384
  if (method === "symlink") {
295
- const relPath = relative(dirname(destination), source);
385
+ const relPath = relative4(dirname5(destination), source);
296
386
  await symlink(relPath, destination);
297
387
  } else {
298
388
  await copyDirectory(source, destination);
@@ -403,13 +493,13 @@ function resolveItemSource(item) {
403
493
  }
404
494
 
405
495
  // src/config/registry.ts
406
- var __dirname2 = dirname2(fileURLToPath(import.meta.url));
496
+ var __dirname2 = dirname6(fileURLToPath(import.meta.url));
407
497
  var FETCH_TIMEOUT_MS = 15e3;
408
498
  function findPackageRoot(startDir) {
409
499
  let dir = startDir;
410
500
  for (; ; ) {
411
- if (existsSync(join3(dir, "package.json"))) return dir;
412
- const parent = dirname2(dir);
501
+ if (existsSync11(join13(dir, "package.json"))) return dir;
502
+ const parent = dirname6(dir);
413
503
  if (parent === dir) return null;
414
504
  dir = parent;
415
505
  }
@@ -417,7 +507,7 @@ function findPackageRoot(startDir) {
417
507
  function resolveLocalRegistryPath() {
418
508
  const packageRoot = findPackageRoot(__dirname2);
419
509
  if (!packageRoot) return null;
420
- return join3(packageRoot, "..", "..", "registry");
510
+ return resolveRegistryDir(join13(packageRoot, "..", ".."));
421
511
  }
422
512
  var REGISTRY_PATH = process.env.SEEDR_REGISTRY_DIR || resolveLocalRegistryPath();
423
513
  var DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/danieldeusing/seedr/main/registry";
@@ -439,7 +529,7 @@ function isValidManifestIndex(value) {
439
529
  async function loadFile(filename) {
440
530
  if (REGISTRY_PATH) {
441
531
  try {
442
- return await readFile3(join3(REGISTRY_PATH, filename), "utf-8");
532
+ return await readFile3(join13(REGISTRY_PATH, filename), "utf-8");
443
533
  } catch {
444
534
  }
445
535
  }
@@ -472,7 +562,7 @@ async function loadIndex() {
472
562
  if (cache.index) return cache.index;
473
563
  if (REGISTRY_PATH) {
474
564
  try {
475
- const localContent = await readFile3(join3(REGISTRY_PATH, "manifest.json"), "utf-8");
565
+ const localContent = await readFile3(join13(REGISTRY_PATH, "manifest.json"), "utf-8");
476
566
  const parsed = JSON.parse(localContent);
477
567
  if (isValidManifestIndex(parsed)) {
478
568
  cache.index = parsed;
@@ -517,7 +607,7 @@ async function getItemsBySlug(slug) {
517
607
  const manifest = await loadManifest();
518
608
  return manifest.items.filter((item) => item.slug === slug);
519
609
  }
520
- async function listItems(type) {
610
+ async function listItems2(type) {
521
611
  if (type) {
522
612
  return loadTypeItems(type);
523
613
  }
@@ -533,18 +623,18 @@ async function searchItems(query) {
533
623
  }
534
624
  async function getItemFull(item) {
535
625
  assertValidSlug(item.slug);
536
- const typeDir = typeDirName(item.type);
537
- const itemJsonPath = `${typeDir}/${item.slug}/item.json`;
538
- const content = await loadFile(itemJsonPath);
626
+ const typeDir2 = typeDirName(item.type);
627
+ const itemJsonPath2 = `${typeDir2}/${item.slug}/item.json`;
628
+ const content = await loadFile(itemJsonPath2);
539
629
  return JSON.parse(content);
540
630
  }
541
631
  function getItemBaseUrl(item) {
542
632
  if (isFirstParty(item.sourceType)) {
543
633
  assertValidSlug(item.slug);
544
- const typeDir = typeDirName(item.type);
634
+ const typeDir2 = typeDirName(item.type);
545
635
  return {
546
- local: REGISTRY_PATH ? join3(REGISTRY_PATH, typeDir, item.slug) : null,
547
- remote: `${REGISTRY_URL}/${typeDir}/${item.slug}`,
636
+ local: REGISTRY_PATH ? join13(REGISTRY_PATH, typeDir2, item.slug) : null,
637
+ remote: `${REGISTRY_URL}/${typeDir2}/${item.slug}`,
548
638
  rootUrl: REGISTRY_ROOT_URL,
549
639
  revision: null
550
640
  };
@@ -552,23 +642,20 @@ function getItemBaseUrl(item) {
552
642
  const source = resolveItemSource(item);
553
643
  return { local: null, remote: source.baseUrl, rootUrl: source.rootUrl, revision: source.revision };
554
644
  }
555
- function mainFileName(type) {
556
- return type === "skill" ? "SKILL.md" : `${type}.md`;
557
- }
558
645
  async function getItemContent(item) {
559
646
  const { local } = getItemBaseUrl(item);
560
647
  const mainFile = mainFileName(item.type);
561
648
  if (local) {
562
649
  try {
563
- return await readFile3(join3(local, mainFile), "utf-8");
650
+ return await readFile3(join13(local, mainFile), "utf-8");
564
651
  } catch {
565
652
  }
566
653
  }
567
- const tempRoot = await mkdtemp(join3(tmpdir(), "seedr-content-"));
654
+ const tempRoot = await mkdtemp(join13(tmpdir(), "seedr-content-"));
568
655
  try {
569
- const destination = join3(tempRoot, "item");
656
+ const destination = join13(tempRoot, "item");
570
657
  await fetchItemToDestination(item, destination);
571
- return await readFile3(join3(destination, mainFile), "utf-8");
658
+ return await readFile3(join13(destination, mainFile), "utf-8");
572
659
  } finally {
573
660
  await rm2(tempRoot, { recursive: true, force: true });
574
661
  }
@@ -579,7 +666,7 @@ async function fetchItemFile(item, relativePath) {
579
666
  const { local, remote } = getItemBaseUrl(item);
580
667
  if (local) {
581
668
  try {
582
- return await readFile3(join3(local, ...segments), "utf-8");
669
+ return await readFile3(join13(local, ...segments), "utf-8");
583
670
  } catch {
584
671
  }
585
672
  }
@@ -593,8 +680,8 @@ function getItemSourcePath(item) {
593
680
  return null;
594
681
  }
595
682
  assertValidSlug(item.slug);
596
- const typeDir = typeDirName(item.type);
597
- return join3(REGISTRY_PATH, typeDir, item.slug);
683
+ const typeDir2 = typeDirName(item.type);
684
+ return join13(REGISTRY_PATH, typeDir2, item.slug);
598
685
  }
599
686
  function integrityError(item, detail) {
600
687
  return new Error(`Registry integrity error: ${item.type} "${item.slug}" \u2014 ${detail}`);
@@ -639,8 +726,8 @@ async function downloadFileSet(location, fileSet, stagingDir) {
639
726
  for (const segment of segments) assertSafeNodeName(segment);
640
727
  const url = fileSet.licenseExtra && relativePath === fileSet.licenseExtra.installAs ? `${location.rootUrl}/${fileSet.licenseExtra.file}` : `${location.remote}/${relativePath}`;
641
728
  const content = await fetchRemoteBuffer(url);
642
- const filePath = join3(stagingDir, ...segments);
643
- await mkdir2(dirname2(filePath), { recursive: true });
729
+ const filePath = join13(stagingDir, ...segments);
730
+ await mkdir2(dirname6(filePath), { recursive: true });
644
731
  await writeFile2(filePath, content);
645
732
  }));
646
733
  }
@@ -650,8 +737,8 @@ async function fetchItemToDestination(item, destPath) {
650
737
  if (fileSet.digest === null && !isFirstParty(item.sourceType)) {
651
738
  throw integrityError(item, "the registry entry carries no contentDigest; refusing to install unverifiable content");
652
739
  }
653
- await mkdir2(dirname2(destPath), { recursive: true });
654
- const stagingDir = await mkdtemp(join3(dirname2(destPath), ".seedr-staging-"));
740
+ await mkdir2(dirname6(destPath), { recursive: true });
741
+ const stagingDir = await mkdtemp(join13(dirname6(destPath), ".seedr-staging-"));
655
742
  try {
656
743
  await downloadFileSet(location, fileSet, stagingDir);
657
744
  if (fileSet.digest !== null) {
@@ -670,7 +757,7 @@ async function fetchItemToDestination(item, destPath) {
670
757
 
671
758
  // src/config/agents.ts
672
759
  import { homedir as homedir2 } from "os";
673
- import { join as join4 } from "path";
760
+ import { join as join14 } from "path";
674
761
  var home = homedir2();
675
762
  var SKILL_DIRECTORY = {
676
763
  path: "skills"
@@ -679,7 +766,7 @@ var ANTIGRAVITY = {
679
766
  name: "Google Antigravity",
680
767
  shortName: "antigravity",
681
768
  projectRoot: ".agents",
682
- userRoot: join4(home, ".agents"),
769
+ userRoot: join14(home, ".agents"),
683
770
  contentTypes: { skill: SKILL_DIRECTORY }
684
771
  };
685
772
  var CODING_AGENTS = {
@@ -687,7 +774,7 @@ var CODING_AGENTS = {
687
774
  name: "Claude Code",
688
775
  shortName: "claude",
689
776
  projectRoot: ".claude",
690
- userRoot: join4(home, ".claude"),
777
+ userRoot: join14(home, ".claude"),
691
778
  contentTypes: {
692
779
  skill: SKILL_DIRECTORY,
693
780
  command: {
@@ -714,7 +801,7 @@ var CODING_AGENTS = {
714
801
  name: "GitHub Copilot",
715
802
  shortName: "copilot",
716
803
  projectRoot: ".github",
717
- userRoot: join4(home, ".github"),
804
+ userRoot: join14(home, ".github"),
718
805
  contentTypes: { skill: SKILL_DIRECTORY }
719
806
  },
720
807
  antigravity: ANTIGRAVITY,
@@ -723,14 +810,14 @@ var CODING_AGENTS = {
723
810
  name: "OpenAI Codex CLI",
724
811
  shortName: "codex",
725
812
  projectRoot: ".codex",
726
- userRoot: join4(home, ".codex"),
813
+ userRoot: join14(home, ".codex"),
727
814
  contentTypes: { skill: SKILL_DIRECTORY }
728
815
  },
729
816
  opencode: {
730
817
  name: "OpenCode",
731
818
  shortName: "opencode",
732
819
  projectRoot: ".opencode",
733
- userRoot: join4(home, ".opencode"),
820
+ userRoot: join14(home, ".opencode"),
734
821
  contentTypes: { skill: SKILL_DIRECTORY }
735
822
  }
736
823
  };
@@ -746,7 +833,7 @@ function getAgentRoot(agent, scope, cwd = process.cwd()) {
746
833
  switch (scope) {
747
834
  case "project":
748
835
  case "local":
749
- return join4(cwd, config.projectRoot);
836
+ return join14(cwd, config.projectRoot);
750
837
  case "user":
751
838
  return config.userRoot;
752
839
  }
@@ -755,27 +842,27 @@ function getContentPath(agent, type, scope, cwd = process.cwd()) {
755
842
  const typeConfig = getContentTypeConfig(agent, type);
756
843
  if (!typeConfig) return void 0;
757
844
  const root = getAgentRoot(agent, scope, cwd);
758
- return typeConfig.path ? join4(root, typeConfig.path) : root;
845
+ return typeConfig.path ? join14(root, typeConfig.path) : root;
759
846
  }
760
847
  function getSettingsPath(scope, cwd = process.cwd()) {
761
848
  switch (scope) {
762
849
  case "project":
763
- return join4(cwd, ".claude/settings.json");
850
+ return join14(cwd, ".claude/settings.json");
764
851
  case "user":
765
- return join4(home, ".claude/settings.json");
852
+ return join14(home, ".claude/settings.json");
766
853
  case "local":
767
- return join4(cwd, ".claude/settings.local.json");
854
+ return join14(cwd, ".claude/settings.local.json");
768
855
  }
769
856
  }
770
857
  function getMcpConfigPath(agent, scope, cwd = process.cwd()) {
771
858
  const isUser = scope === "user";
772
859
  switch (canonicalAgent(agent) ?? agent) {
773
860
  case "claude":
774
- return isUser ? join4(home, ".claude.json") : join4(cwd, ".mcp.json");
861
+ return isUser ? join14(home, ".claude.json") : join14(cwd, ".mcp.json");
775
862
  case "codex":
776
- return isUser ? join4(home, ".codex", "config.toml") : join4(cwd, ".codex", "config.toml");
863
+ return isUser ? join14(home, ".codex", "config.toml") : join14(cwd, ".codex", "config.toml");
777
864
  case "opencode":
778
- return isUser ? join4(home, ".config", "opencode", "opencode.json") : join4(cwd, "opencode.json");
865
+ return isUser ? join14(home, ".config", "opencode", "opencode.json") : join14(cwd, "opencode.json");
779
866
  default:
780
867
  throw new Error(`${agent} has no verified MCP configuration format`);
781
868
  }
@@ -954,7 +1041,7 @@ function error(message) {
954
1041
  }
955
1042
 
956
1043
  // src/handlers/skill.ts
957
- import { relative as relative2, dirname as dirname3 } from "path";
1044
+ import { relative as relative5, dirname as dirname7 } from "path";
958
1045
  import { homedir as homedir3 } from "os";
959
1046
  import { readdir as readdir2, symlink as symlink2 } from "fs/promises";
960
1047
  import chalk2 from "chalk";
@@ -965,18 +1052,18 @@ function getScopeRoot(scope, cwd) {
965
1052
  return scope === "user" ? homedir3() : cwd;
966
1053
  }
967
1054
  function centralSkillsDir(scope, cwd) {
968
- return dirname3(getAgentsPath("skill", "any-slug", scope, cwd));
1055
+ return dirname7(getAgentsPath("skill", "any-slug", scope, cwd));
969
1056
  }
970
1057
  async function resolveCentralPath(slug, scope, cwd) {
971
1058
  const scopeRoot = getScopeRoot(scope, cwd);
972
1059
  const centralDir = centralSkillsDir(scope, cwd);
973
- return resolveContained(scopeRoot, relative2(scopeRoot, centralDir), slug);
1060
+ return resolveContained(scopeRoot, relative5(scopeRoot, centralDir), slug);
974
1061
  }
975
1062
  async function resolveAgentSkillPath(agent, slug, scope, cwd) {
976
1063
  const destDir = getContentPath(agent, "skill", scope, cwd);
977
1064
  if (!destDir) return null;
978
1065
  const scopeRoot = getScopeRoot(scope, cwd);
979
- return resolveContained(scopeRoot, relative2(scopeRoot, destDir), slug);
1066
+ return resolveContained(scopeRoot, relative5(scopeRoot, destDir), slug);
980
1067
  }
981
1068
  async function installToCentralLocation(item, sourcePath, scope, force, cwd) {
982
1069
  const centralPath = await resolveCentralPath(item.slug, scope, cwd);
@@ -990,9 +1077,9 @@ async function installToCentralLocation(item, sourcePath, scope, force, cwd) {
990
1077
  return { centralPath, created: !existed };
991
1078
  }
992
1079
  async function createAgentSymlink(centralPath, destPath) {
993
- await ensureDir(dirname3(destPath));
1080
+ await ensureDir(dirname7(destPath));
994
1081
  await removePathEntry(destPath);
995
- const relPath = relative2(dirname3(destPath), centralPath);
1082
+ const relPath = relative5(dirname7(destPath), centralPath);
996
1083
  await symlink2(relPath, destPath);
997
1084
  }
998
1085
  async function installSkillForAgent(item, agent, scope, method, force, cwd, centralPath) {
@@ -1121,6 +1208,7 @@ var skillHandler = {
1121
1208
  };
1122
1209
 
1123
1210
  export {
1211
+ mainFileName,
1124
1212
  isLegacyAgent,
1125
1213
  canonicalAgent,
1126
1214
  canonicalAgents,
@@ -1148,7 +1236,7 @@ export {
1148
1236
  loadManifest,
1149
1237
  getItem,
1150
1238
  getItemsBySlug,
1151
- listItems,
1239
+ listItems2 as listItems,
1152
1240
  searchItems,
1153
1241
  getItemContent,
1154
1242
  fetchItemFile,
package/dist/cli.js CHANGED
@@ -35,6 +35,7 @@ import {
35
35
  isLegacyAgent,
36
36
  isValidSlug,
37
37
  listItems,
38
+ mainFileName,
38
39
  moveDirectory,
39
40
  outro,
40
41
  p,
@@ -56,14 +57,14 @@ import {
56
57
  warn,
57
58
  writeFileAtomic,
58
59
  writeTextFile
59
- } from "./chunk-JTCNXHYF.js";
60
+ } from "./chunk-PEGEA2KN.js";
60
61
 
61
62
  // src/cli.ts
62
63
  import { Command as Command5 } from "commander";
63
64
 
64
65
  // src/commands/add.ts
65
66
  import { Command } from "commander";
66
- import chalk7 from "chalk";
67
+ import chalk8 from "chalk";
67
68
 
68
69
  // src/handlers/registry.ts
69
70
  var handlers = /* @__PURE__ */ new Map();
@@ -143,7 +144,7 @@ function isTelemetryDisabled(env = process.env) {
143
144
  return env[TELEMETRY_OPT_OUT_VARIABLE] !== void 0;
144
145
  }
145
146
  function cliVersion() {
146
- return true ? "0.1.91" : "dev";
147
+ return true ? "0.1.93" : "dev";
147
148
  }
148
149
  async function sendEvent(event) {
149
150
  try {
@@ -218,7 +219,7 @@ async function installAgentForCodingAgent(item, agent, scope, method, force, cwd
218
219
  }
219
220
  await assertOverwritable(destPath, force);
220
221
  const sourcePath = getItemSourcePath(item);
221
- const sourceFile = sourcePath ? join(sourcePath, "AGENT.md") : null;
222
+ const sourceFile = sourcePath ? join(sourcePath, mainFileName("agent")) : null;
222
223
  if (method === "symlink" && sourceFile && await exists(sourceFile)) {
223
224
  await installFile(sourceFile, destPath, "symlink");
224
225
  } else {
@@ -278,12 +279,12 @@ async function planAgent(item, agents, scope, method, cwd) {
278
279
  const destPath = await resolveAgentFilePath(agent, item.slug, scope, cwd);
279
280
  if (!destPath) throw new Error(`${CODING_AGENTS[agent].name} does not support agents`);
280
281
  const sourcePath = getItemSourcePath(item);
281
- const linked = method === "symlink" && sourcePath !== null && await exists(join(sourcePath, "AGENT.md"));
282
+ const linked = method === "symlink" && sourcePath !== null && await exists(join(sourcePath, mainFileName("agent")));
282
283
  changes.push({
283
284
  agent,
284
285
  kind: await exists(destPath) ? "modify" : "create",
285
286
  path: destPath,
286
- detail: linked ? `symlink \u2192 ${join(sourcePath, "AGENT.md")}` : "agent definition file"
287
+ detail: linked ? `symlink \u2192 ${join(sourcePath, mainFileName("agent"))}` : "agent definition file"
287
288
  });
288
289
  }
289
290
  return changes;
@@ -302,12 +303,121 @@ var agentHandler = {
302
303
  plan: planAgent
303
304
  };
304
305
 
305
- // src/handlers/hook.ts
306
- import { join as join2, basename, dirname as dirname2 } from "path";
306
+ // src/handlers/command.ts
307
+ import { join as join2, relative as relative2 } from "path";
307
308
  import { homedir as homedir2 } from "os";
308
- import { lstat as lstat2, mkdir, mkdtemp, readFile as readFile2, realpath, rm, unlink as unlink2 } from "fs/promises";
309
+ import { lstat as lstat2, readdir as readdir2, unlink as unlink2 } from "fs/promises";
309
310
  import chalk3 from "chalk";
310
311
  import ora2 from "ora";
312
+ var SLUG_LABEL2 = "command slug";
313
+ async function resolveCommandFilePath(agent, slug, scope, cwd) {
314
+ const destDir = getContentPath(agent, "command", scope, cwd);
315
+ if (!destDir) return null;
316
+ const scopeRoot = scope === "user" ? homedir2() : cwd;
317
+ return resolveContained(scopeRoot, relative2(scopeRoot, destDir), `${slug}.md`);
318
+ }
319
+ async function installCommandForCodingAgent(item, agent, scope, method, force, cwd) {
320
+ const spinner = ora2(
321
+ `Installing ${item.name} for ${CODING_AGENTS[agent].name}...`
322
+ ).start();
323
+ try {
324
+ assertValidSlug(item.slug, SLUG_LABEL2);
325
+ const destPath = await resolveCommandFilePath(agent, item.slug, scope, cwd);
326
+ if (!destPath) {
327
+ throw new Error(`${CODING_AGENTS[agent].name} does not support commands`);
328
+ }
329
+ await assertOverwritable(destPath, force);
330
+ const sourcePath = getItemSourcePath(item);
331
+ const sourceFile = sourcePath ? join2(sourcePath, mainFileName("command")) : null;
332
+ if (method === "symlink" && sourceFile && await exists(sourceFile)) {
333
+ await installFile(sourceFile, destPath, "symlink");
334
+ } else {
335
+ const content = await getItemContent(item);
336
+ await ensureDir(getContentPath(agent, "command", scope, cwd));
337
+ await writeTextFile(destPath, content);
338
+ }
339
+ spinner.succeed(
340
+ brand(`Installed ${item.name} for ${CODING_AGENTS[agent].name}`)
341
+ );
342
+ return { agent, success: true, path: destPath };
343
+ } catch (error2) {
344
+ const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
345
+ spinner.fail(
346
+ chalk3.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
347
+ );
348
+ return { agent, success: false, path: "", error: errorMsg };
349
+ }
350
+ }
351
+ async function installCommand(item, agents, scope, method, force, cwd = process.cwd()) {
352
+ const results = [];
353
+ for (const agent of agents) {
354
+ const result = await installCommandForCodingAgent(item, agent, scope, method, force, cwd);
355
+ results.push(result);
356
+ }
357
+ return results;
358
+ }
359
+ async function uninstallCommand(slug, agent, scope, cwd = process.cwd()) {
360
+ assertValidSlug(slug, SLUG_LABEL2);
361
+ const destPath = await resolveCommandFilePath(agent, slug, scope, cwd);
362
+ if (!destPath) return false;
363
+ let stats;
364
+ try {
365
+ stats = await lstat2(destPath);
366
+ } catch (error2) {
367
+ if (error2.code === "ENOENT") return false;
368
+ throw error2;
369
+ }
370
+ if (stats.isDirectory()) {
371
+ throw new Error(`${destPath} is a directory; refusing to remove it`);
372
+ }
373
+ await unlink2(destPath);
374
+ return true;
375
+ }
376
+ async function getInstalledCommands(agent, scope, cwd = process.cwd()) {
377
+ const destDir = getContentPath(agent, "command", scope, cwd);
378
+ if (!destDir || !await exists(destDir)) {
379
+ return [];
380
+ }
381
+ const files = await readdir2(destDir);
382
+ return files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
383
+ }
384
+ async function planCommand(item, agents, scope, method, cwd) {
385
+ assertValidSlug(item.slug, SLUG_LABEL2);
386
+ const changes = [];
387
+ for (const agent of agents) {
388
+ const destPath = await resolveCommandFilePath(agent, item.slug, scope, cwd);
389
+ if (!destPath) throw new Error(`${CODING_AGENTS[agent].name} does not support commands`);
390
+ const sourcePath = getItemSourcePath(item);
391
+ const linked = method === "symlink" && sourcePath !== null && await exists(join2(sourcePath, mainFileName("command")));
392
+ changes.push({
393
+ agent,
394
+ kind: await exists(destPath) ? "modify" : "create",
395
+ path: destPath,
396
+ detail: linked ? `symlink \u2192 ${join2(sourcePath, mainFileName("command"))}` : "slash command file"
397
+ });
398
+ }
399
+ return changes;
400
+ }
401
+ var commandHandler = {
402
+ type: "command",
403
+ async install(item, agents, scope, method, force, cwd) {
404
+ return installCommand(item, agents, scope, method, force, cwd);
405
+ },
406
+ async uninstall(slug, agent, scope, cwd) {
407
+ return uninstallCommand(slug, agent, scope, cwd);
408
+ },
409
+ async listInstalled(agent, scope, cwd) {
410
+ return getInstalledCommands(agent, scope, cwd);
411
+ },
412
+ plan: planCommand
413
+ };
414
+
415
+ // src/handlers/hook.ts
416
+ import { join as join3, basename, dirname as dirname2 } from "path";
417
+ import { homedir as homedir3 } from "os";
418
+ import { lstat as lstat3, mkdir, mkdtemp, readFile as readFile2, realpath, rm, unlink as unlink3 } from "fs/promises";
419
+ import chalk4 from "chalk";
420
+ import ora3 from "ora";
311
421
 
312
422
  // src/utils/json.ts
313
423
  import { readFile, stat } from "fs/promises";
@@ -361,10 +471,10 @@ var CLAUDE_ONLY_ERROR = "Hooks are only supported for Claude Code";
361
471
  var SCRIPT_NAME_LABEL = "hook script name";
362
472
  var SCRIPT_MODE = 493;
363
473
  function getScopeRoot(scope, cwd) {
364
- return scope === "user" ? homedir2() : cwd;
474
+ return scope === "user" ? homedir3() : cwd;
365
475
  }
366
476
  function getHooksDir(scope, cwd) {
367
- return join2(getScopeRoot(scope, cwd), ".claude", "hooks");
477
+ return join3(getScopeRoot(scope, cwd), ".claude", "hooks");
368
478
  }
369
479
  function getScriptPath(scope, scriptName) {
370
480
  switch (scope) {
@@ -395,7 +505,7 @@ async function prepareHooksDir(scope, cwd) {
395
505
  async function assertRegularFileOrMissing(path) {
396
506
  let stats;
397
507
  try {
398
- stats = await lstat2(path);
508
+ stats = await lstat3(path);
399
509
  } catch (error2) {
400
510
  if (error2.code === "ENOENT") return;
401
511
  throw error2;
@@ -410,13 +520,13 @@ async function assertRegularFileOrMissing(path) {
410
520
  async function loadScriptBytes(item, scriptFile, hooksDir) {
411
521
  const sourcePath = getItemSourcePath(item);
412
522
  if (sourcePath && await exists(sourcePath)) {
413
- return readFile2(join2(sourcePath, scriptFile));
523
+ return readFile2(join3(sourcePath, scriptFile));
414
524
  }
415
- const fetchDir = await mkdtemp(join2(dirname2(hooksDir), ".seedr-hook-"));
525
+ const fetchDir = await mkdtemp(join3(dirname2(hooksDir), ".seedr-hook-"));
416
526
  try {
417
- const contentDir = join2(fetchDir, "content");
527
+ const contentDir = join3(fetchDir, "content");
418
528
  await fetchItemToDestination(item, contentDir);
419
- return await readFile2(join2(contentDir, scriptFile));
529
+ return await readFile2(join3(contentDir, scriptFile));
420
530
  } finally {
421
531
  await rm(fetchDir, { recursive: true, force: true });
422
532
  }
@@ -438,7 +548,7 @@ function mergeTriggers(hooks, triggers, command) {
438
548
  }
439
549
  }
440
550
  async function installHookForAgent(item, agent, scope, _method, force, cwd) {
441
- const spinner = ora2(
551
+ const spinner = ora3(
442
552
  `Installing ${item.name} for ${CODING_AGENTS[agent].name}...`
443
553
  ).start();
444
554
  try {
@@ -478,7 +588,7 @@ async function installHookForAgent(item, agent, scope, _method, force, cwd) {
478
588
  } catch (error2) {
479
589
  const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
480
590
  spinner.fail(
481
- chalk3.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
591
+ chalk4.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
482
592
  );
483
593
  return { agent, success: false, path: "", error: errorMsg };
484
594
  }
@@ -519,7 +629,7 @@ async function removeScriptFile(scope, cwd, scriptFileName) {
519
629
  const scriptFilePath = await resolveContained(hooksDir, scriptFileName);
520
630
  let stats;
521
631
  try {
522
- stats = await lstat2(scriptFilePath);
632
+ stats = await lstat3(scriptFilePath);
523
633
  } catch (error2) {
524
634
  if (error2.code === "ENOENT") return false;
525
635
  throw error2;
@@ -527,7 +637,7 @@ async function removeScriptFile(scope, cwd, scriptFileName) {
527
637
  if (stats.isDirectory()) {
528
638
  throw new Error(`${scriptFilePath} is a directory; refusing to remove it`);
529
639
  }
530
- await unlink2(scriptFilePath);
640
+ await unlink3(scriptFilePath);
531
641
  return true;
532
642
  }
533
643
  async function uninstallHook(slug, agent, scope, cwd = process.cwd()) {
@@ -608,8 +718,8 @@ var hookHandler = {
608
718
  // src/handlers/mcp.ts
609
719
  import { readFile as readFile3 } from "fs/promises";
610
720
  import { dirname as dirname3 } from "path";
611
- import chalk4 from "chalk";
612
- import ora3 from "ora";
721
+ import chalk5 from "chalk";
722
+ import ora4 from "ora";
613
723
 
614
724
  // src/utils/toml.ts
615
725
  var BARE_KEY_PATTERN = /^[A-Za-z0-9_-]+$/;
@@ -944,7 +1054,7 @@ function adapterFor(agent) {
944
1054
  return adapter;
945
1055
  }
946
1056
  async function installMcpForAgent(item, agent, scope, _method, force, cwd) {
947
- const spinner = ora3(
1057
+ const spinner = ora4(
948
1058
  `Installing ${item.name} for ${CODING_AGENTS[agent].name}...`
949
1059
  ).start();
950
1060
  try {
@@ -964,7 +1074,7 @@ async function installMcpForAgent(item, agent, scope, _method, force, cwd) {
964
1074
  } catch (error2) {
965
1075
  const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
966
1076
  spinner.fail(
967
- chalk4.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
1077
+ chalk5.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
968
1078
  );
969
1079
  return { agent, success: false, path: "", error: errorMsg };
970
1080
  }
@@ -1032,8 +1142,8 @@ var mcpHandler = {
1032
1142
  };
1033
1143
 
1034
1144
  // src/handlers/settings.ts
1035
- import chalk5 from "chalk";
1036
- import ora4 from "ora";
1145
+ import chalk6 from "chalk";
1146
+ import ora5 from "ora";
1037
1147
  var SETTINGS_NOT_DISCOVERABLE = "settings items cannot be discovered (they are merged into settings.json)";
1038
1148
  var CLAUDE_ONLY_ERROR2 = "Settings are only supported for Claude Code";
1039
1149
  function parseSettings(content) {
@@ -1044,7 +1154,7 @@ function parseSettings(content) {
1044
1154
  }
1045
1155
  }
1046
1156
  async function installSettingsForAgent(item, agent, scope, _method, _force, cwd) {
1047
- const spinner = ora4(
1157
+ const spinner = ora5(
1048
1158
  `Installing ${item.name} for ${CODING_AGENTS[agent].name}...`
1049
1159
  ).start();
1050
1160
  try {
@@ -1064,7 +1174,7 @@ async function installSettingsForAgent(item, agent, scope, _method, _force, cwd)
1064
1174
  } catch (error2) {
1065
1175
  const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
1066
1176
  spinner.fail(
1067
- chalk5.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
1177
+ chalk6.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
1068
1178
  );
1069
1179
  return { agent, success: false, path: "", error: errorMsg };
1070
1180
  }
@@ -1158,22 +1268,22 @@ var settingsHandler = {
1158
1268
  };
1159
1269
 
1160
1270
  // src/handlers/plugin.ts
1161
- import { homedir as homedir3 } from "os";
1162
- import { join as join3, relative as relative2 } from "path";
1271
+ import { homedir as homedir4 } from "os";
1272
+ import { join as join4, relative as relative3 } from "path";
1163
1273
  import { mkdir as mkdir2, mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
1164
1274
  import { execFile } from "child_process";
1165
1275
  import { promisify } from "util";
1166
- import chalk6 from "chalk";
1167
- import ora5 from "ora";
1168
- var home = homedir3();
1169
- var PLUGINS_DIR = join3(home, ".claude", "plugins");
1170
- var PLUGINS_CACHE_DIR = join3(PLUGINS_DIR, "cache");
1171
- var INSTALLED_PLUGINS_PATH = join3(PLUGINS_DIR, "installed_plugins.json");
1172
- var KNOWN_MARKETPLACES_PATH = join3(PLUGINS_DIR, "known_marketplaces.json");
1173
- var MARKETPLACES_DIR = join3(PLUGINS_DIR, "marketplaces");
1276
+ import chalk7 from "chalk";
1277
+ import ora6 from "ora";
1278
+ var home = homedir4();
1279
+ var PLUGINS_DIR = join4(home, ".claude", "plugins");
1280
+ var PLUGINS_CACHE_DIR = join4(PLUGINS_DIR, "cache");
1281
+ var INSTALLED_PLUGINS_PATH = join4(PLUGINS_DIR, "installed_plugins.json");
1282
+ var KNOWN_MARKETPLACES_PATH = join4(PLUGINS_DIR, "known_marketplaces.json");
1283
+ var MARKETPLACES_DIR = join4(PLUGINS_DIR, "marketplaces");
1174
1284
  var PLUGIN_JSON_PATH = ".claude-plugin/plugin.json";
1175
1285
  var CLAUDE_ONLY_ERROR3 = "Plugins are only supported for Claude Code";
1176
- var SLUG_LABEL2 = "plugin slug";
1286
+ var SLUG_LABEL3 = "plugin slug";
1177
1287
  var GITHUB_REPO_SLUG_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
1178
1288
  function getPluginId(name, marketplace) {
1179
1289
  return `${name}@${marketplace}`;
@@ -1235,8 +1345,8 @@ async function ensureMarketplaceRegistered(marketplace, item) {
1235
1345
  async function createStagingDir(slug) {
1236
1346
  const tmpRoot = await resolveContained(PLUGINS_CACHE_DIR, ".tmp");
1237
1347
  await mkdir2(tmpRoot, { recursive: true });
1238
- const staging = await mkdtemp2(join3(tmpRoot, `${slug}-`));
1239
- return resolveContained(PLUGINS_CACHE_DIR, relative2(PLUGINS_CACHE_DIR, staging));
1348
+ const staging = await mkdtemp2(join4(tmpRoot, `${slug}-`));
1349
+ return resolveContained(PLUGINS_CACHE_DIR, relative3(PLUGINS_CACHE_DIR, staging));
1240
1350
  }
1241
1351
  async function stageContent(item, contentPath) {
1242
1352
  const sourcePath = getItemSourcePath(item);
@@ -1320,20 +1430,20 @@ async function commitInstall(params) {
1320
1430
  }
1321
1431
  }
1322
1432
  async function installPluginForAgent(item, agent, scope, _method, force, cwd) {
1323
- const spinner = ora5(
1433
+ const spinner = ora6(
1324
1434
  `Installing ${item.name} for ${CODING_AGENTS[agent].name}...`
1325
1435
  ).start();
1326
1436
  try {
1327
1437
  if (agent !== "claude") {
1328
1438
  throw new Error(CLAUDE_ONLY_ERROR3);
1329
1439
  }
1330
- assertValidSlug(item.slug, SLUG_LABEL2);
1440
+ assertValidSlug(item.slug, SLUG_LABEL3);
1331
1441
  const marketplace = resolveMarketplaceName(item);
1332
1442
  const staging = await createStagingDir(item.slug);
1333
1443
  try {
1334
- const contentPath = join3(staging, "content");
1444
+ const contentPath = join4(staging, "content");
1335
1445
  const fetched = await stageContent(item, contentPath);
1336
- const pluginJson = await readJson(join3(contentPath, ...PLUGIN_JSON_PATH.split("/")));
1446
+ const pluginJson = await readJson(join4(contentPath, ...PLUGIN_JSON_PATH.split("/")));
1337
1447
  const { name, version } = resolvePluginIdentity(item, pluginJson);
1338
1448
  const gitCommitSha = resolveGitCommitSha(item, fetched);
1339
1449
  const pluginId = getPluginId(name, marketplace);
@@ -1351,7 +1461,7 @@ async function installPluginForAgent(item, agent, scope, _method, force, cwd) {
1351
1461
  } catch (error2) {
1352
1462
  const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
1353
1463
  spinner.fail(
1354
- chalk6.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
1464
+ chalk7.red(`Failed to install for ${CODING_AGENTS[agent].name}: ${errorMsg}`)
1355
1465
  );
1356
1466
  return { agent, success: false, path: "", error: errorMsg };
1357
1467
  }
@@ -1393,7 +1503,7 @@ async function removeOrphanedCache(installPath, registry) {
1393
1503
  await removePathEntry(contained);
1394
1504
  }
1395
1505
  async function uninstallPlugin(slug, agent, scope, cwd = process.cwd()) {
1396
- assertValidSlug(slug, SLUG_LABEL2);
1506
+ assertValidSlug(slug, SLUG_LABEL3);
1397
1507
  if (agent !== "claude") return false;
1398
1508
  const registry = await readJson(INSTALLED_PLUGINS_PATH);
1399
1509
  if (!registry.plugins) return false;
@@ -1435,7 +1545,7 @@ async function getInstalledPlugins(agent, scope, cwd = process.cwd()) {
1435
1545
  async function readPluginJsonForPlan(item) {
1436
1546
  const sourcePath = getItemSourcePath(item);
1437
1547
  if (sourcePath) {
1438
- return readJson(join3(sourcePath, ...PLUGIN_JSON_PATH.split("/")));
1548
+ return readJson(join4(sourcePath, ...PLUGIN_JSON_PATH.split("/")));
1439
1549
  }
1440
1550
  return JSON.parse(await fetchItemFile(item, PLUGIN_JSON_PATH));
1441
1551
  }
@@ -1446,7 +1556,7 @@ async function planPlugin(item, agents, scope, _method, cwd) {
1446
1556
  const changes = [];
1447
1557
  for (const agent of agents) {
1448
1558
  if (agent !== "claude") throw new Error(CLAUDE_ONLY_ERROR3);
1449
- assertValidSlug(item.slug, SLUG_LABEL2);
1559
+ assertValidSlug(item.slug, SLUG_LABEL3);
1450
1560
  const marketplace = resolveMarketplaceName(item);
1451
1561
  const { name, version } = resolvePluginIdentity(item, await readPluginJsonForPlan(item));
1452
1562
  const pluginId = getPluginId(name, marketplace);
@@ -1494,6 +1604,7 @@ var pluginHandler = {
1494
1604
  // src/handlers/index.ts
1495
1605
  registerHandler(skillHandler);
1496
1606
  registerHandler(agentHandler);
1607
+ registerHandler(commandHandler);
1497
1608
  registerHandler(hookHandler);
1498
1609
  registerHandler(mcpHandler);
1499
1610
  registerHandler(settingsHandler);
@@ -1578,8 +1689,8 @@ function formatPlan(changes) {
1578
1689
  for (const [label, group] of groups) {
1579
1690
  lines.push(` ${label}:`);
1580
1691
  for (const change of group) {
1581
- const detail = change.detail ? ` ${chalk7.gray(`\u2014 ${change.detail}`)}` : "";
1582
- lines.push(` ${chalk7.gray(`[${KIND_LABEL[change.kind]}]`)} ${change.path}${detail}`);
1692
+ const detail = change.detail ? ` ${chalk8.gray(`\u2014 ${change.detail}`)}` : "";
1693
+ lines.push(` ${chalk8.gray(`[${KIND_LABEL[change.kind]}]`)} ${change.path}${detail}`);
1583
1694
  }
1584
1695
  }
1585
1696
  return lines;
@@ -1689,13 +1800,13 @@ function printInstallSummary(results) {
1689
1800
  if (successful.length > 0) {
1690
1801
  success(`Installed for ${successful.length} agent(s)`);
1691
1802
  for (const r of successful) {
1692
- console.log(chalk7.gray(` \u2192 ${r.path}`));
1803
+ console.log(chalk8.gray(` \u2192 ${r.path}`));
1693
1804
  }
1694
1805
  }
1695
1806
  if (failed.length > 0) {
1696
1807
  error(`Failed for ${failed.length} agent(s)`);
1697
1808
  for (const r of failed) {
1698
- console.log(chalk7.red(` \xD7 ${r.agent}: ${r.error}`));
1809
+ console.log(chalk8.red(` \xD7 ${r.agent}: ${r.error}`));
1699
1810
  }
1700
1811
  }
1701
1812
  return exitCode;
@@ -1709,7 +1820,7 @@ async function runAdd(name, options, cwd = process.cwd()) {
1709
1820
  const item = await resolveItem(name, options.type);
1710
1821
  if (item === CANCELLED) return 0;
1711
1822
  if (!item) return 1;
1712
- step(`Selected: ${brand(item.name)} ${chalk7.gray(`(${item.type})`)} ${chalk7.gray(`- ${item.description}`)}`);
1823
+ step(`Selected: ${brand(item.name)} ${chalk8.gray(`(${item.type})`)} ${chalk8.gray(`- ${item.description}`)}`);
1713
1824
  const handler = getHandler(item.type);
1714
1825
  if (!handler) {
1715
1826
  error(`No handler found for type "${item.type}"`);
@@ -1763,17 +1874,17 @@ Telemetry: ${TELEMETRY_HELP_TEXT}.`).action(async (name, options) => {
1763
1874
 
1764
1875
  // src/commands/list.ts
1765
1876
  import { Command as Command2 } from "commander";
1766
- import chalk8 from "chalk";
1877
+ import chalk9 from "chalk";
1767
1878
  var SEPARATOR_WIDTH = 40;
1768
1879
  var SLUG_COLUMN_WIDTH = 24;
1769
1880
  var TYPE_COLORS = {
1770
- skill: chalk8.magenta,
1771
- hook: chalk8.hex("#a855f7"),
1772
- agent: chalk8.blue,
1773
- plugin: chalk8.hex("#6366f1"),
1774
- command: chalk8.hex("#f59e0b"),
1775
- settings: chalk8.hex("#f97316"),
1776
- mcp: chalk8.hex("#2dd4bf")
1881
+ skill: chalk9.magenta,
1882
+ hook: chalk9.hex("#a855f7"),
1883
+ agent: chalk9.blue,
1884
+ plugin: chalk9.hex("#6366f1"),
1885
+ command: chalk9.hex("#f59e0b"),
1886
+ settings: chalk9.hex("#f97316"),
1887
+ mcp: chalk9.hex("#2dd4bf")
1777
1888
  };
1778
1889
  async function collectInstalledItems(params) {
1779
1890
  const types = params.types ?? getRegisteredTypes();
@@ -1802,7 +1913,7 @@ function resolveListAgents(agentsArg) {
1802
1913
  async function runList(options, cwd = process.cwd()) {
1803
1914
  const optionError = validateType(options.type) || validateScope(options.scope);
1804
1915
  if (optionError) {
1805
- console.log(chalk8.red(optionError));
1916
+ console.log(chalk9.red(optionError));
1806
1917
  return 1;
1807
1918
  }
1808
1919
  const type = options.type;
@@ -1811,7 +1922,7 @@ async function runList(options, cwd = process.cwd()) {
1811
1922
  }
1812
1923
  const agents = resolveListAgents(options.agents);
1813
1924
  if (typeof agents === "string") {
1814
- console.log(chalk8.red(agents));
1925
+ console.log(chalk9.red(agents));
1815
1926
  return 1;
1816
1927
  }
1817
1928
  const scope = options.scope ?? "project";
@@ -1831,32 +1942,32 @@ async function listAvailable(type, label) {
1831
1942
  const items = label ? all.filter((item) => item.label === label) : all;
1832
1943
  if (items.length === 0 && label) {
1833
1944
  const known = [...new Set(all.map((item) => item.label).filter(Boolean))].sort();
1834
- console.log(chalk8.red(`No item carries the label "${label}".`));
1835
- if (known.length > 0) console.log(chalk8.gray(`Labels in use: ${known.join(", ")}`));
1945
+ console.log(chalk9.red(`No item carries the label "${label}".`));
1946
+ if (known.length > 0) console.log(chalk9.gray(`Labels in use: ${known.join(", ")}`));
1836
1947
  return 1;
1837
1948
  }
1838
1949
  if (items.length === 0) {
1839
- console.log(chalk8.yellow("No items found in registry"));
1950
+ console.log(chalk9.yellow("No items found in registry"));
1840
1951
  return 0;
1841
1952
  }
1842
1953
  const grouped = groupByType(items);
1843
1954
  for (const [itemType, typeItems] of Object.entries(grouped)) {
1844
- const colorFn = TYPE_COLORS[itemType] ?? chalk8.white;
1955
+ const colorFn = TYPE_COLORS[itemType] ?? chalk9.white;
1845
1956
  console.log(colorFn(`
1846
1957
  ${itemType.toUpperCase()}S`));
1847
- console.log(chalk8.gray("\u2500".repeat(SEPARATOR_WIDTH)));
1958
+ console.log(chalk9.gray("\u2500".repeat(SEPARATOR_WIDTH)));
1848
1959
  for (const item of typeItems) {
1849
1960
  const compatIcons = [...new Set(item.compatibility.map((a) => CODING_AGENTS[a]?.shortName ?? a))].join(" ");
1850
- const featured = item.featured ? chalk8.yellow("\u2605 ") : " ";
1961
+ const featured = item.featured ? chalk9.yellow("\u2605 ") : " ";
1851
1962
  console.log(
1852
- `${featured}${chalk8.white(item.slug.padEnd(SLUG_COLUMN_WIDTH))} ${chalk8.gray(compatIcons)}`
1963
+ `${featured}${chalk9.white(item.slug.padEnd(SLUG_COLUMN_WIDTH))} ${chalk9.gray(compatIcons)}`
1853
1964
  );
1854
- console.log(` ${chalk8.gray(item.description)}`);
1965
+ console.log(` ${chalk9.gray(item.description)}`);
1855
1966
  }
1856
1967
  }
1857
1968
  console.log("");
1858
1969
  console.log(
1859
- chalk8.gray(`Total: ${items.length} items. Use 'npx @danieldeusing/seedr add <name>' to install.`)
1970
+ chalk9.gray(`Total: ${items.length} items. Use 'npx @danieldeusing/seedr add <name>' to install.`)
1860
1971
  );
1861
1972
  return 0;
1862
1973
  }
@@ -1870,23 +1981,23 @@ Installed items (${params.scope} scope):
1870
1981
  for (const group of groups) {
1871
1982
  if (group.type !== currentType) {
1872
1983
  currentType = group.type;
1873
- const colorFn = TYPE_COLORS[group.type] ?? chalk8.white;
1984
+ const colorFn = TYPE_COLORS[group.type] ?? chalk9.white;
1874
1985
  console.log(colorFn(`${group.type.toUpperCase()}S`));
1875
1986
  }
1876
- console.log(chalk8.blue(` ${CODING_AGENTS[group.agent].name}`));
1987
+ console.log(chalk9.blue(` ${CODING_AGENTS[group.agent].name}`));
1877
1988
  for (const slug of group.slugs) {
1878
- console.log(` ${chalk8.white(slug)}`);
1989
+ console.log(` ${chalk9.white(slug)}`);
1879
1990
  total++;
1880
1991
  }
1881
1992
  console.log("");
1882
1993
  }
1883
1994
  if (!params.types || params.types.includes("settings")) {
1884
- console.log(chalk8.gray(`Note: ${SETTINGS_NOT_DISCOVERABLE}`));
1995
+ console.log(chalk9.gray(`Note: ${SETTINGS_NOT_DISCOVERABLE}`));
1885
1996
  }
1886
1997
  if (total === 0) {
1887
- console.log(chalk8.yellow("No items installed"));
1998
+ console.log(chalk9.yellow("No items installed"));
1888
1999
  } else {
1889
- console.log(chalk8.gray(`Total: ${total} installed`));
2000
+ console.log(chalk9.gray(`Total: ${total} installed`));
1890
2001
  }
1891
2002
  }
1892
2003
  function groupByType(items) {
@@ -1904,8 +2015,8 @@ function groupByType(items) {
1904
2015
 
1905
2016
  // src/commands/remove.ts
1906
2017
  import { Command as Command3 } from "commander";
1907
- import chalk9 from "chalk";
1908
- import ora6 from "ora";
2018
+ import chalk10 from "chalk";
2019
+ import ora7 from "ora";
1909
2020
  async function findInstalledAgents(slug, type, scope, cwd) {
1910
2021
  const handler = getHandler(type);
1911
2022
  if (!handler) return [];
@@ -1923,13 +2034,13 @@ async function removeFromAgents(slug, type, agents, scope, cwd) {
1923
2034
  if (!handler) return 0;
1924
2035
  let successCount = 0;
1925
2036
  for (const agent of agents) {
1926
- const spinner = ora6(`Removing from ${CODING_AGENTS[agent].name}...`).start();
2037
+ const spinner = ora7(`Removing from ${CODING_AGENTS[agent].name}...`).start();
1927
2038
  const removed = await handler.uninstall(slug, agent, scope, cwd);
1928
2039
  if (removed) {
1929
2040
  spinner.succeed(brand(`Removed from ${CODING_AGENTS[agent].name}`));
1930
2041
  successCount++;
1931
2042
  } else {
1932
- spinner.info(chalk9.gray(`Not found in ${CODING_AGENTS[agent].name}`));
2043
+ spinner.info(chalk10.gray(`Not found in ${CODING_AGENTS[agent].name}`));
1933
2044
  }
1934
2045
  }
1935
2046
  return successCount;
@@ -1954,14 +2065,14 @@ function validateRemoveRequest(name, options) {
1954
2065
  async function runRemove(name, options, cwd = process.cwd()) {
1955
2066
  const requestError = validateRemoveRequest(name, options);
1956
2067
  if (requestError) {
1957
- console.log(chalk9.red(requestError));
2068
+ console.log(chalk10.red(requestError));
1958
2069
  return 1;
1959
2070
  }
1960
2071
  const scope = options.scope ?? "project";
1961
2072
  const type = options.type;
1962
2073
  const handler = getHandler(type);
1963
2074
  if (!handler) {
1964
- console.log(chalk9.red(`No handler found for type "${type}"`));
2075
+ console.log(chalk10.red(`No handler found for type "${type}"`));
1965
2076
  return 1;
1966
2077
  }
1967
2078
  let agents;
@@ -1974,11 +2085,11 @@ async function runRemove(name, options, cwd = process.cwd()) {
1974
2085
  }
1975
2086
  if (agents.length === 0) {
1976
2087
  if (type === "settings") {
1977
- console.log(chalk9.yellow(`Cannot detect where "${name}" is installed: ${SETTINGS_NOT_DISCOVERABLE}`));
1978
- console.log(chalk9.gray("Name the agents explicitly, e.g. --agents claude"));
2088
+ console.log(chalk10.yellow(`Cannot detect where "${name}" is installed: ${SETTINGS_NOT_DISCOVERABLE}`));
2089
+ console.log(chalk10.gray("Name the agents explicitly, e.g. --agents claude"));
1979
2090
  return 1;
1980
2091
  }
1981
- console.log(chalk9.yellow(`${type} "${name}" is not installed in ${scope} scope`));
2092
+ console.log(chalk10.yellow(`${type} "${name}" is not installed in ${scope} scope`));
1982
2093
  return 0;
1983
2094
  }
1984
2095
  if (!options.yes) {
@@ -1991,7 +2102,7 @@ Will remove ${type} "${name}" from:`));
1991
2102
  const answer = await confirm("Proceed with removal?");
1992
2103
  const confirmed = !p.isCancel(answer) && answer;
1993
2104
  if (!confirmed) {
1994
- console.log(chalk9.yellow("Removal cancelled"));
2105
+ console.log(chalk10.yellow("Removal cancelled"));
1995
2106
  return 0;
1996
2107
  }
1997
2108
  }
@@ -2001,7 +2112,7 @@ Will remove ${type} "${name}" from:`));
2001
2112
  console.log(brand(`Successfully removed from ${successCount} agent(s)`));
2002
2113
  return 0;
2003
2114
  }
2004
- console.log(chalk9.yellow("Nothing to remove"));
2115
+ console.log(chalk10.yellow("Nothing to remove"));
2005
2116
  return 0;
2006
2117
  }
2007
2118
  var removeCommand = new Command3("remove").alias("rm").description("Remove an installed item (skill, plugin, agent, hook, mcp)").argument("<name>", "Name/slug of the item to remove").option("-t, --type <type>", "Content type: skill, agent, hook, mcp, plugin, settings").option(
@@ -2022,9 +2133,9 @@ var removeCommand = new Command3("remove").alias("rm").description("Remove an in
2022
2133
 
2023
2134
  // src/commands/init.ts
2024
2135
  import { Command as Command4 } from "commander";
2025
- import chalk10 from "chalk";
2026
- import ora7 from "ora";
2027
- import { join as join4 } from "path";
2136
+ import chalk11 from "chalk";
2137
+ import ora8 from "ora";
2138
+ import { join as join5 } from "path";
2028
2139
  function readmeFor(agent) {
2029
2140
  return `# ${CODING_AGENTS[agent].name} Configuration
2030
2141
 
@@ -2042,7 +2153,7 @@ async function initializeAgent(agent, cwd) {
2042
2153
  const path = getAgentPath(agent, "project", cwd);
2043
2154
  if (await exists(path)) return false;
2044
2155
  await ensureDir(path);
2045
- await writeTextFile(join4(path, "README.md"), readmeFor(agent));
2156
+ await writeTextFile(join5(path, "README.md"), readmeFor(agent));
2046
2157
  return true;
2047
2158
  }
2048
2159
  async function runInit(options, cwd = process.cwd()) {
@@ -2053,13 +2164,13 @@ async function runInit(options, cwd = process.cwd()) {
2053
2164
  } else {
2054
2165
  const parsed = parseAgentsArgStrict(agentsArg);
2055
2166
  if (parsed.unknown.length > 0) {
2056
- console.error(chalk10.red(`Unknown agent(s): ${parsed.unknown.join(", ")}. Valid agents: ${ALL_AGENTS.join(", ")} or "all"`));
2167
+ console.error(chalk11.red(`Unknown agent(s): ${parsed.unknown.join(", ")}. Valid agents: ${ALL_AGENTS.join(", ")} or "all"`));
2057
2168
  return 1;
2058
2169
  }
2059
2170
  agents = parsed.agents;
2060
2171
  }
2061
2172
  if (agents.length === 0) {
2062
- console.error(chalk10.red("No valid agents specified"));
2173
+ console.error(chalk11.red("No valid agents specified"));
2063
2174
  return 1;
2064
2175
  }
2065
2176
  console.log(brand("\nWill initialize configuration for:"));
@@ -2071,16 +2182,16 @@ async function runInit(options, cwd = process.cwd()) {
2071
2182
  const answer = await confirm("Proceed?");
2072
2183
  const confirmed = !p.isCancel(answer) && answer;
2073
2184
  if (!confirmed) {
2074
- console.log(chalk10.yellow("Cancelled"));
2185
+ console.log(chalk11.yellow("Cancelled"));
2075
2186
  return 0;
2076
2187
  }
2077
2188
  }
2078
2189
  for (const agent of agents) {
2079
- const spinner = ora7(`Initializing ${CODING_AGENTS[agent].name}...`).start();
2190
+ const spinner = ora8(`Initializing ${CODING_AGENTS[agent].name}...`).start();
2080
2191
  if (await initializeAgent(agent, cwd)) {
2081
2192
  spinner.succeed(brand(`Initialized ${CODING_AGENTS[agent].name}`));
2082
2193
  } else {
2083
- spinner.info(chalk10.gray(`${CODING_AGENTS[agent].name} already initialized`));
2194
+ spinner.info(chalk11.gray(`${CODING_AGENTS[agent].name} already initialized`));
2084
2195
  }
2085
2196
  }
2086
2197
  console.log("");
@@ -2103,7 +2214,7 @@ var initCommand = new Command4("init").description("Initialize coding agent conf
2103
2214
  // package.json
2104
2215
  var package_default = {
2105
2216
  name: "@danieldeusing/seedr",
2106
- version: "0.1.91",
2217
+ version: "0.1.93",
2107
2218
  description: "Seed your projects with AI configurations",
2108
2219
  type: "module",
2109
2220
  bin: {
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  loadManifest,
16
16
  searchItems,
17
17
  uninstallSkill
18
- } from "./chunk-JTCNXHYF.js";
18
+ } from "./chunk-PEGEA2KN.js";
19
19
  export {
20
20
  ALL_AGENTS,
21
21
  CODING_AGENTS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danieldeusing/seedr",
3
- "version": "0.1.91",
3
+ "version": "0.1.93",
4
4
  "description": "Seed your projects with AI configurations",
5
5
  "type": "module",
6
6
  "bin": {