@danieldeusing/seedr 0.1.90 → 0.1.92
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-JTCNXHYF.js → chunk-XNSAC6CK.js} +141 -78
- package/dist/cli.js +211 -100
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -2,12 +2,22 @@
|
|
|
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 existsSync7 } from "fs";
|
|
6
6
|
import { tmpdir } from "os";
|
|
7
|
-
import { join as
|
|
7
|
+
import { join as join8, dirname as dirname4 } 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) {
|
|
@@ -36,23 +46,75 @@ function canonicalAgents(values) {
|
|
|
36
46
|
|
|
37
47
|
// ../registry-ops/src/sourceTypes.ts
|
|
38
48
|
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
49
|
function isCanonicalSourceType(value) {
|
|
42
50
|
return typeof value === "string" && CANONICAL_SOURCE_TYPES.includes(value);
|
|
43
51
|
}
|
|
44
|
-
function isLegacySourceType(value) {
|
|
45
|
-
return typeof value === "string" && Object.hasOwn(SOURCE_TYPE_ALIASES, value);
|
|
46
|
-
}
|
|
47
52
|
function canonicalSourceType(value) {
|
|
48
|
-
|
|
49
|
-
if (isLegacySourceType(value)) return SOURCE_TYPE_ALIASES[value];
|
|
50
|
-
return null;
|
|
53
|
+
return isCanonicalSourceType(value) ? value : null;
|
|
51
54
|
}
|
|
52
55
|
function isFirstParty(sourceType) {
|
|
53
56
|
return canonicalSourceType(sourceType) === "seedr";
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
// ../registry-ops/src/fsPaths.ts
|
|
60
|
+
import { existsSync, readFileSync } from "fs";
|
|
61
|
+
import { join } from "path";
|
|
62
|
+
var REPO_CONFIG_FILE = "seedr.config.json";
|
|
63
|
+
function resolveRegistryDir(repoRoot) {
|
|
64
|
+
const config = join(repoRoot, REPO_CONFIG_FILE);
|
|
65
|
+
if (!existsSync(config)) return join(repoRoot, DEFAULT_REGISTRY_DIR);
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(readFileSync(config, "utf8"));
|
|
69
|
+
} catch (error2) {
|
|
70
|
+
throw new Error(`${REPO_CONFIG_FILE} is not readable JSON: ${error2.message}`, { cause: error2 });
|
|
71
|
+
}
|
|
72
|
+
return join(repoRoot, registryDirName(parsed));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ../registry-ops/src/hash.ts
|
|
76
|
+
import { createHash } from "crypto";
|
|
77
|
+
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "fs";
|
|
78
|
+
import { join as join2, relative } from "path";
|
|
79
|
+
|
|
80
|
+
// ../registry-ops/src/read.ts
|
|
81
|
+
import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
82
|
+
import { join as join3 } from "path";
|
|
83
|
+
|
|
84
|
+
// ../registry-ops/src/compile.ts
|
|
85
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
86
|
+
|
|
87
|
+
// ../registry-ops/src/identity.ts
|
|
88
|
+
import { execFile } from "child_process";
|
|
89
|
+
import { promisify } from "util";
|
|
90
|
+
var execFileAsync = promisify(execFile);
|
|
91
|
+
|
|
92
|
+
// ../registry-ops/src/ops/addLocal.ts
|
|
93
|
+
import { spawnSync } from "child_process";
|
|
94
|
+
import { copyFileSync, existsSync as existsSync4, mkdirSync as mkdirSync2, realpathSync, rmdirSync, rmSync, readdirSync as readdirSync3, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
95
|
+
import { basename, join as join4 } from "path";
|
|
96
|
+
|
|
97
|
+
// ../registry-ops/src/ops/addRemote.ts
|
|
98
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
99
|
+
|
|
100
|
+
// ../registry-ops/src/ops/remove.ts
|
|
101
|
+
import { rmSync as rmSync2 } from "fs";
|
|
102
|
+
|
|
103
|
+
// ../registry-ops/src/ops/setLabels.ts
|
|
104
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
105
|
+
|
|
106
|
+
// ../registry-ops/src/ops/update.ts
|
|
107
|
+
import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
108
|
+
import { dirname, resolve, sep } from "path";
|
|
109
|
+
|
|
110
|
+
// ../registry-ops/src/tx.ts
|
|
111
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync4, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
112
|
+
import { dirname as dirname2, join as join5, relative as relative2, resolve as resolve2 } from "path";
|
|
113
|
+
var DEFAULT_LOCK_STALE_MS = 10 * 60 * 1e3;
|
|
114
|
+
|
|
115
|
+
// ../registry-ops/src/migrate.ts
|
|
116
|
+
import { writeFileSync as writeFileSync7 } from "fs";
|
|
117
|
+
|
|
56
118
|
// src/utils/slug.ts
|
|
57
119
|
var SLUG_PATTERN2 = /^[a-z0-9][a-z0-9-]*$/;
|
|
58
120
|
var MAX_SLUG_LENGTH2 = 100;
|
|
@@ -68,11 +130,11 @@ function assertValidSlug(value, what = "item slug") {
|
|
|
68
130
|
}
|
|
69
131
|
|
|
70
132
|
// src/utils/digest.ts
|
|
71
|
-
import { createHash } from "crypto";
|
|
133
|
+
import { createHash as createHash2 } from "crypto";
|
|
72
134
|
import { readFile } from "fs/promises";
|
|
73
|
-
import { join } from "path";
|
|
135
|
+
import { join as join6 } from "path";
|
|
74
136
|
function sha256Hex(bytes) {
|
|
75
|
-
return
|
|
137
|
+
return createHash2("sha256").update(bytes).digest("hex");
|
|
76
138
|
}
|
|
77
139
|
function digestFromFileHashes(entries) {
|
|
78
140
|
const sorted = [...entries].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -88,7 +150,7 @@ async function computeContentDigest(root, relativePaths) {
|
|
|
88
150
|
const entries = await Promise.all(
|
|
89
151
|
relativePaths.map(async (relativePath) => ({
|
|
90
152
|
path: relativePath,
|
|
91
|
-
sha256: sha256Hex(await readFile(
|
|
153
|
+
sha256: sha256Hex(await readFile(join6(root, ...relativePath.split("/"))))
|
|
92
154
|
}))
|
|
93
155
|
);
|
|
94
156
|
return digestFromFileHashes(entries);
|
|
@@ -132,7 +194,7 @@ import {
|
|
|
132
194
|
} from "fs/promises";
|
|
133
195
|
import { randomBytes } from "crypto";
|
|
134
196
|
import { homedir } from "os";
|
|
135
|
-
import { basename, dirname, join as
|
|
197
|
+
import { basename as basename2, dirname as dirname3, join as join7, relative as relative3, resolve as resolve3, isAbsolute, sep as sep2 } from "path";
|
|
136
198
|
async function exists(path) {
|
|
137
199
|
try {
|
|
138
200
|
await access(path);
|
|
@@ -165,11 +227,11 @@ function assertSafePathSegment(value, what) {
|
|
|
165
227
|
}
|
|
166
228
|
}
|
|
167
229
|
function isStrictDescendant(root, candidate) {
|
|
168
|
-
const rel =
|
|
169
|
-
return rel !== "" && !isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${
|
|
230
|
+
const rel = relative3(root, candidate);
|
|
231
|
+
return rel !== "" && !isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${sep2}`);
|
|
170
232
|
}
|
|
171
233
|
function isSameOrDescendant(root, candidate) {
|
|
172
|
-
return
|
|
234
|
+
return relative3(root, candidate) === "" || isStrictDescendant(root, candidate);
|
|
173
235
|
}
|
|
174
236
|
async function realpathOrNull(path) {
|
|
175
237
|
try {
|
|
@@ -179,8 +241,8 @@ async function realpathOrNull(path) {
|
|
|
179
241
|
}
|
|
180
242
|
}
|
|
181
243
|
async function resolveContained(root, ...segments) {
|
|
182
|
-
const absoluteRoot =
|
|
183
|
-
const resolved =
|
|
244
|
+
const absoluteRoot = resolve3(root);
|
|
245
|
+
const resolved = resolve3(absoluteRoot, ...segments);
|
|
184
246
|
if (!isStrictDescendant(absoluteRoot, resolved)) {
|
|
185
247
|
throw new Error(`Refusing path outside ${absoluteRoot}: ${resolved}`);
|
|
186
248
|
}
|
|
@@ -188,7 +250,7 @@ async function resolveContained(root, ...segments) {
|
|
|
188
250
|
if (realRoot === null) {
|
|
189
251
|
return resolved;
|
|
190
252
|
}
|
|
191
|
-
let ancestor =
|
|
253
|
+
let ancestor = dirname3(resolved);
|
|
192
254
|
for (; ; ) {
|
|
193
255
|
const realAncestor = await realpathOrNull(ancestor);
|
|
194
256
|
if (realAncestor !== null) {
|
|
@@ -199,16 +261,16 @@ async function resolveContained(root, ...segments) {
|
|
|
199
261
|
}
|
|
200
262
|
return resolved;
|
|
201
263
|
}
|
|
202
|
-
const parent =
|
|
203
|
-
if (parent === ancestor ||
|
|
264
|
+
const parent = dirname3(ancestor);
|
|
265
|
+
if (parent === ancestor || relative3(absoluteRoot, ancestor) === "") {
|
|
204
266
|
return resolved;
|
|
205
267
|
}
|
|
206
268
|
ancestor = parent;
|
|
207
269
|
}
|
|
208
270
|
}
|
|
209
271
|
async function assertDirectoryWithin(dir, scopeRoot, what) {
|
|
210
|
-
const realRoot = await realpathOrNull(
|
|
211
|
-
const realDir = await realpathOrNull(
|
|
272
|
+
const realRoot = await realpathOrNull(resolve3(scopeRoot));
|
|
273
|
+
const realDir = await realpathOrNull(resolve3(dir));
|
|
212
274
|
if (realRoot === null || realDir === null) {
|
|
213
275
|
throw new Error(`${what} ${dir} could not be resolved`);
|
|
214
276
|
}
|
|
@@ -232,7 +294,7 @@ async function removePathEntry(path) {
|
|
|
232
294
|
return true;
|
|
233
295
|
}
|
|
234
296
|
async function moveDirectory(source, destination) {
|
|
235
|
-
await mkdir(
|
|
297
|
+
await mkdir(dirname3(destination), { recursive: true });
|
|
236
298
|
try {
|
|
237
299
|
await rename(source, destination);
|
|
238
300
|
} catch (error2) {
|
|
@@ -242,7 +304,7 @@ async function moveDirectory(source, destination) {
|
|
|
242
304
|
}
|
|
243
305
|
}
|
|
244
306
|
async function writeFileAtomic(path, data, options = {}) {
|
|
245
|
-
const tempPath =
|
|
307
|
+
const tempPath = join7(dirname3(path), `${basename2(path)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
246
308
|
try {
|
|
247
309
|
await writeFile(tempPath, data, options.mode === void 0 ? {} : { mode: options.mode });
|
|
248
310
|
await rename(tempPath, path);
|
|
@@ -268,31 +330,31 @@ async function restoreFile(path, snapshot) {
|
|
|
268
330
|
await writeFileAtomic(path, snapshot.content, { mode: snapshot.mode });
|
|
269
331
|
}
|
|
270
332
|
async function installFile(source, destination, method) {
|
|
271
|
-
await ensureDir(
|
|
333
|
+
await ensureDir(dirname3(destination));
|
|
272
334
|
await removePathEntry(destination);
|
|
273
335
|
if (method === "symlink") {
|
|
274
|
-
const relPath =
|
|
336
|
+
const relPath = relative3(dirname3(destination), source);
|
|
275
337
|
await symlink(relPath, destination);
|
|
276
338
|
} else {
|
|
277
339
|
await copyFile(source, destination);
|
|
278
340
|
}
|
|
279
341
|
}
|
|
280
342
|
async function writeTextFile(path, content) {
|
|
281
|
-
await ensureDir(
|
|
343
|
+
await ensureDir(dirname3(path));
|
|
282
344
|
await writeFile(path, content, "utf-8");
|
|
283
345
|
}
|
|
284
346
|
function getAgentsPath(contentType, slug, scope, cwd) {
|
|
285
347
|
const base = scope === "user" ? homedir() : cwd;
|
|
286
|
-
return
|
|
348
|
+
return join7(base, ".agents", contentType + "s", slug);
|
|
287
349
|
}
|
|
288
350
|
async function copyDirectory(source, destination) {
|
|
289
351
|
await cp(source, destination, { recursive: true });
|
|
290
352
|
}
|
|
291
353
|
async function installDirectory(source, destination, method) {
|
|
292
|
-
await ensureDir(
|
|
354
|
+
await ensureDir(dirname3(destination));
|
|
293
355
|
await removePathEntry(destination);
|
|
294
356
|
if (method === "symlink") {
|
|
295
|
-
const relPath =
|
|
357
|
+
const relPath = relative3(dirname3(destination), source);
|
|
296
358
|
await symlink(relPath, destination);
|
|
297
359
|
} else {
|
|
298
360
|
await copyDirectory(source, destination);
|
|
@@ -403,13 +465,13 @@ function resolveItemSource(item) {
|
|
|
403
465
|
}
|
|
404
466
|
|
|
405
467
|
// src/config/registry.ts
|
|
406
|
-
var __dirname2 =
|
|
468
|
+
var __dirname2 = dirname4(fileURLToPath(import.meta.url));
|
|
407
469
|
var FETCH_TIMEOUT_MS = 15e3;
|
|
408
470
|
function findPackageRoot(startDir) {
|
|
409
471
|
let dir = startDir;
|
|
410
472
|
for (; ; ) {
|
|
411
|
-
if (
|
|
412
|
-
const parent =
|
|
473
|
+
if (existsSync7(join8(dir, "package.json"))) return dir;
|
|
474
|
+
const parent = dirname4(dir);
|
|
413
475
|
if (parent === dir) return null;
|
|
414
476
|
dir = parent;
|
|
415
477
|
}
|
|
@@ -417,7 +479,7 @@ function findPackageRoot(startDir) {
|
|
|
417
479
|
function resolveLocalRegistryPath() {
|
|
418
480
|
const packageRoot = findPackageRoot(__dirname2);
|
|
419
481
|
if (!packageRoot) return null;
|
|
420
|
-
return
|
|
482
|
+
return resolveRegistryDir(join8(packageRoot, "..", ".."));
|
|
421
483
|
}
|
|
422
484
|
var REGISTRY_PATH = process.env.SEEDR_REGISTRY_DIR || resolveLocalRegistryPath();
|
|
423
485
|
var DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/danieldeusing/seedr/main/registry";
|
|
@@ -439,7 +501,7 @@ function isValidManifestIndex(value) {
|
|
|
439
501
|
async function loadFile(filename) {
|
|
440
502
|
if (REGISTRY_PATH) {
|
|
441
503
|
try {
|
|
442
|
-
return await readFile3(
|
|
504
|
+
return await readFile3(join8(REGISTRY_PATH, filename), "utf-8");
|
|
443
505
|
} catch {
|
|
444
506
|
}
|
|
445
507
|
}
|
|
@@ -472,7 +534,7 @@ async function loadIndex() {
|
|
|
472
534
|
if (cache.index) return cache.index;
|
|
473
535
|
if (REGISTRY_PATH) {
|
|
474
536
|
try {
|
|
475
|
-
const localContent = await readFile3(
|
|
537
|
+
const localContent = await readFile3(join8(REGISTRY_PATH, "manifest.json"), "utf-8");
|
|
476
538
|
const parsed = JSON.parse(localContent);
|
|
477
539
|
if (isValidManifestIndex(parsed)) {
|
|
478
540
|
cache.index = parsed;
|
|
@@ -517,7 +579,7 @@ async function getItemsBySlug(slug) {
|
|
|
517
579
|
const manifest = await loadManifest();
|
|
518
580
|
return manifest.items.filter((item) => item.slug === slug);
|
|
519
581
|
}
|
|
520
|
-
async function
|
|
582
|
+
async function listItems2(type) {
|
|
521
583
|
if (type) {
|
|
522
584
|
return loadTypeItems(type);
|
|
523
585
|
}
|
|
@@ -533,18 +595,18 @@ async function searchItems(query) {
|
|
|
533
595
|
}
|
|
534
596
|
async function getItemFull(item) {
|
|
535
597
|
assertValidSlug(item.slug);
|
|
536
|
-
const
|
|
537
|
-
const
|
|
538
|
-
const content = await loadFile(
|
|
598
|
+
const typeDir2 = typeDirName(item.type);
|
|
599
|
+
const itemJsonPath2 = `${typeDir2}/${item.slug}/item.json`;
|
|
600
|
+
const content = await loadFile(itemJsonPath2);
|
|
539
601
|
return JSON.parse(content);
|
|
540
602
|
}
|
|
541
603
|
function getItemBaseUrl(item) {
|
|
542
604
|
if (isFirstParty(item.sourceType)) {
|
|
543
605
|
assertValidSlug(item.slug);
|
|
544
|
-
const
|
|
606
|
+
const typeDir2 = typeDirName(item.type);
|
|
545
607
|
return {
|
|
546
|
-
local: REGISTRY_PATH ?
|
|
547
|
-
remote: `${REGISTRY_URL}/${
|
|
608
|
+
local: REGISTRY_PATH ? join8(REGISTRY_PATH, typeDir2, item.slug) : null,
|
|
609
|
+
remote: `${REGISTRY_URL}/${typeDir2}/${item.slug}`,
|
|
548
610
|
rootUrl: REGISTRY_ROOT_URL,
|
|
549
611
|
revision: null
|
|
550
612
|
};
|
|
@@ -560,15 +622,15 @@ async function getItemContent(item) {
|
|
|
560
622
|
const mainFile = mainFileName(item.type);
|
|
561
623
|
if (local) {
|
|
562
624
|
try {
|
|
563
|
-
return await readFile3(
|
|
625
|
+
return await readFile3(join8(local, mainFile), "utf-8");
|
|
564
626
|
} catch {
|
|
565
627
|
}
|
|
566
628
|
}
|
|
567
|
-
const tempRoot = await mkdtemp(
|
|
629
|
+
const tempRoot = await mkdtemp(join8(tmpdir(), "seedr-content-"));
|
|
568
630
|
try {
|
|
569
|
-
const destination =
|
|
631
|
+
const destination = join8(tempRoot, "item");
|
|
570
632
|
await fetchItemToDestination(item, destination);
|
|
571
|
-
return await readFile3(
|
|
633
|
+
return await readFile3(join8(destination, mainFile), "utf-8");
|
|
572
634
|
} finally {
|
|
573
635
|
await rm2(tempRoot, { recursive: true, force: true });
|
|
574
636
|
}
|
|
@@ -579,7 +641,7 @@ async function fetchItemFile(item, relativePath) {
|
|
|
579
641
|
const { local, remote } = getItemBaseUrl(item);
|
|
580
642
|
if (local) {
|
|
581
643
|
try {
|
|
582
|
-
return await readFile3(
|
|
644
|
+
return await readFile3(join8(local, ...segments), "utf-8");
|
|
583
645
|
} catch {
|
|
584
646
|
}
|
|
585
647
|
}
|
|
@@ -593,8 +655,8 @@ function getItemSourcePath(item) {
|
|
|
593
655
|
return null;
|
|
594
656
|
}
|
|
595
657
|
assertValidSlug(item.slug);
|
|
596
|
-
const
|
|
597
|
-
return
|
|
658
|
+
const typeDir2 = typeDirName(item.type);
|
|
659
|
+
return join8(REGISTRY_PATH, typeDir2, item.slug);
|
|
598
660
|
}
|
|
599
661
|
function integrityError(item, detail) {
|
|
600
662
|
return new Error(`Registry integrity error: ${item.type} "${item.slug}" \u2014 ${detail}`);
|
|
@@ -639,8 +701,8 @@ async function downloadFileSet(location, fileSet, stagingDir) {
|
|
|
639
701
|
for (const segment of segments) assertSafeNodeName(segment);
|
|
640
702
|
const url = fileSet.licenseExtra && relativePath === fileSet.licenseExtra.installAs ? `${location.rootUrl}/${fileSet.licenseExtra.file}` : `${location.remote}/${relativePath}`;
|
|
641
703
|
const content = await fetchRemoteBuffer(url);
|
|
642
|
-
const filePath =
|
|
643
|
-
await mkdir2(
|
|
704
|
+
const filePath = join8(stagingDir, ...segments);
|
|
705
|
+
await mkdir2(dirname4(filePath), { recursive: true });
|
|
644
706
|
await writeFile2(filePath, content);
|
|
645
707
|
}));
|
|
646
708
|
}
|
|
@@ -650,8 +712,8 @@ async function fetchItemToDestination(item, destPath) {
|
|
|
650
712
|
if (fileSet.digest === null && !isFirstParty(item.sourceType)) {
|
|
651
713
|
throw integrityError(item, "the registry entry carries no contentDigest; refusing to install unverifiable content");
|
|
652
714
|
}
|
|
653
|
-
await mkdir2(
|
|
654
|
-
const stagingDir = await mkdtemp(
|
|
715
|
+
await mkdir2(dirname4(destPath), { recursive: true });
|
|
716
|
+
const stagingDir = await mkdtemp(join8(dirname4(destPath), ".seedr-staging-"));
|
|
655
717
|
try {
|
|
656
718
|
await downloadFileSet(location, fileSet, stagingDir);
|
|
657
719
|
if (fileSet.digest !== null) {
|
|
@@ -670,7 +732,7 @@ async function fetchItemToDestination(item, destPath) {
|
|
|
670
732
|
|
|
671
733
|
// src/config/agents.ts
|
|
672
734
|
import { homedir as homedir2 } from "os";
|
|
673
|
-
import { join as
|
|
735
|
+
import { join as join9 } from "path";
|
|
674
736
|
var home = homedir2();
|
|
675
737
|
var SKILL_DIRECTORY = {
|
|
676
738
|
path: "skills"
|
|
@@ -679,7 +741,7 @@ var ANTIGRAVITY = {
|
|
|
679
741
|
name: "Google Antigravity",
|
|
680
742
|
shortName: "antigravity",
|
|
681
743
|
projectRoot: ".agents",
|
|
682
|
-
userRoot:
|
|
744
|
+
userRoot: join9(home, ".agents"),
|
|
683
745
|
contentTypes: { skill: SKILL_DIRECTORY }
|
|
684
746
|
};
|
|
685
747
|
var CODING_AGENTS = {
|
|
@@ -687,7 +749,7 @@ var CODING_AGENTS = {
|
|
|
687
749
|
name: "Claude Code",
|
|
688
750
|
shortName: "claude",
|
|
689
751
|
projectRoot: ".claude",
|
|
690
|
-
userRoot:
|
|
752
|
+
userRoot: join9(home, ".claude"),
|
|
691
753
|
contentTypes: {
|
|
692
754
|
skill: SKILL_DIRECTORY,
|
|
693
755
|
command: {
|
|
@@ -714,7 +776,7 @@ var CODING_AGENTS = {
|
|
|
714
776
|
name: "GitHub Copilot",
|
|
715
777
|
shortName: "copilot",
|
|
716
778
|
projectRoot: ".github",
|
|
717
|
-
userRoot:
|
|
779
|
+
userRoot: join9(home, ".github"),
|
|
718
780
|
contentTypes: { skill: SKILL_DIRECTORY }
|
|
719
781
|
},
|
|
720
782
|
antigravity: ANTIGRAVITY,
|
|
@@ -723,14 +785,14 @@ var CODING_AGENTS = {
|
|
|
723
785
|
name: "OpenAI Codex CLI",
|
|
724
786
|
shortName: "codex",
|
|
725
787
|
projectRoot: ".codex",
|
|
726
|
-
userRoot:
|
|
788
|
+
userRoot: join9(home, ".codex"),
|
|
727
789
|
contentTypes: { skill: SKILL_DIRECTORY }
|
|
728
790
|
},
|
|
729
791
|
opencode: {
|
|
730
792
|
name: "OpenCode",
|
|
731
793
|
shortName: "opencode",
|
|
732
794
|
projectRoot: ".opencode",
|
|
733
|
-
userRoot:
|
|
795
|
+
userRoot: join9(home, ".opencode"),
|
|
734
796
|
contentTypes: { skill: SKILL_DIRECTORY }
|
|
735
797
|
}
|
|
736
798
|
};
|
|
@@ -746,7 +808,7 @@ function getAgentRoot(agent, scope, cwd = process.cwd()) {
|
|
|
746
808
|
switch (scope) {
|
|
747
809
|
case "project":
|
|
748
810
|
case "local":
|
|
749
|
-
return
|
|
811
|
+
return join9(cwd, config.projectRoot);
|
|
750
812
|
case "user":
|
|
751
813
|
return config.userRoot;
|
|
752
814
|
}
|
|
@@ -755,27 +817,27 @@ function getContentPath(agent, type, scope, cwd = process.cwd()) {
|
|
|
755
817
|
const typeConfig = getContentTypeConfig(agent, type);
|
|
756
818
|
if (!typeConfig) return void 0;
|
|
757
819
|
const root = getAgentRoot(agent, scope, cwd);
|
|
758
|
-
return typeConfig.path ?
|
|
820
|
+
return typeConfig.path ? join9(root, typeConfig.path) : root;
|
|
759
821
|
}
|
|
760
822
|
function getSettingsPath(scope, cwd = process.cwd()) {
|
|
761
823
|
switch (scope) {
|
|
762
824
|
case "project":
|
|
763
|
-
return
|
|
825
|
+
return join9(cwd, ".claude/settings.json");
|
|
764
826
|
case "user":
|
|
765
|
-
return
|
|
827
|
+
return join9(home, ".claude/settings.json");
|
|
766
828
|
case "local":
|
|
767
|
-
return
|
|
829
|
+
return join9(cwd, ".claude/settings.local.json");
|
|
768
830
|
}
|
|
769
831
|
}
|
|
770
832
|
function getMcpConfigPath(agent, scope, cwd = process.cwd()) {
|
|
771
833
|
const isUser = scope === "user";
|
|
772
834
|
switch (canonicalAgent(agent) ?? agent) {
|
|
773
835
|
case "claude":
|
|
774
|
-
return isUser ?
|
|
836
|
+
return isUser ? join9(home, ".claude.json") : join9(cwd, ".mcp.json");
|
|
775
837
|
case "codex":
|
|
776
|
-
return isUser ?
|
|
838
|
+
return isUser ? join9(home, ".codex", "config.toml") : join9(cwd, ".codex", "config.toml");
|
|
777
839
|
case "opencode":
|
|
778
|
-
return isUser ?
|
|
840
|
+
return isUser ? join9(home, ".config", "opencode", "opencode.json") : join9(cwd, "opencode.json");
|
|
779
841
|
default:
|
|
780
842
|
throw new Error(`${agent} has no verified MCP configuration format`);
|
|
781
843
|
}
|
|
@@ -954,7 +1016,7 @@ function error(message) {
|
|
|
954
1016
|
}
|
|
955
1017
|
|
|
956
1018
|
// src/handlers/skill.ts
|
|
957
|
-
import { relative as
|
|
1019
|
+
import { relative as relative4, dirname as dirname5 } from "path";
|
|
958
1020
|
import { homedir as homedir3 } from "os";
|
|
959
1021
|
import { readdir as readdir2, symlink as symlink2 } from "fs/promises";
|
|
960
1022
|
import chalk2 from "chalk";
|
|
@@ -965,18 +1027,18 @@ function getScopeRoot(scope, cwd) {
|
|
|
965
1027
|
return scope === "user" ? homedir3() : cwd;
|
|
966
1028
|
}
|
|
967
1029
|
function centralSkillsDir(scope, cwd) {
|
|
968
|
-
return
|
|
1030
|
+
return dirname5(getAgentsPath("skill", "any-slug", scope, cwd));
|
|
969
1031
|
}
|
|
970
1032
|
async function resolveCentralPath(slug, scope, cwd) {
|
|
971
1033
|
const scopeRoot = getScopeRoot(scope, cwd);
|
|
972
1034
|
const centralDir = centralSkillsDir(scope, cwd);
|
|
973
|
-
return resolveContained(scopeRoot,
|
|
1035
|
+
return resolveContained(scopeRoot, relative4(scopeRoot, centralDir), slug);
|
|
974
1036
|
}
|
|
975
1037
|
async function resolveAgentSkillPath(agent, slug, scope, cwd) {
|
|
976
1038
|
const destDir = getContentPath(agent, "skill", scope, cwd);
|
|
977
1039
|
if (!destDir) return null;
|
|
978
1040
|
const scopeRoot = getScopeRoot(scope, cwd);
|
|
979
|
-
return resolveContained(scopeRoot,
|
|
1041
|
+
return resolveContained(scopeRoot, relative4(scopeRoot, destDir), slug);
|
|
980
1042
|
}
|
|
981
1043
|
async function installToCentralLocation(item, sourcePath, scope, force, cwd) {
|
|
982
1044
|
const centralPath = await resolveCentralPath(item.slug, scope, cwd);
|
|
@@ -990,9 +1052,9 @@ async function installToCentralLocation(item, sourcePath, scope, force, cwd) {
|
|
|
990
1052
|
return { centralPath, created: !existed };
|
|
991
1053
|
}
|
|
992
1054
|
async function createAgentSymlink(centralPath, destPath) {
|
|
993
|
-
await ensureDir(
|
|
1055
|
+
await ensureDir(dirname5(destPath));
|
|
994
1056
|
await removePathEntry(destPath);
|
|
995
|
-
const relPath =
|
|
1057
|
+
const relPath = relative4(dirname5(destPath), centralPath);
|
|
996
1058
|
await symlink2(relPath, destPath);
|
|
997
1059
|
}
|
|
998
1060
|
async function installSkillForAgent(item, agent, scope, method, force, cwd, centralPath) {
|
|
@@ -1148,8 +1210,9 @@ export {
|
|
|
1148
1210
|
loadManifest,
|
|
1149
1211
|
getItem,
|
|
1150
1212
|
getItemsBySlug,
|
|
1151
|
-
listItems,
|
|
1213
|
+
listItems2 as listItems,
|
|
1152
1214
|
searchItems,
|
|
1215
|
+
mainFileName,
|
|
1153
1216
|
getItemContent,
|
|
1154
1217
|
fetchItemFile,
|
|
1155
1218
|
getItemSourcePath,
|
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-
|
|
60
|
+
} from "./chunk-XNSAC6CK.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
|
|
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.
|
|
147
|
+
return true ? "0.1.92" : "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, "
|
|
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, "
|
|
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, "
|
|
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/
|
|
306
|
-
import { join as join2,
|
|
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,
|
|
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" ?
|
|
474
|
+
return scope === "user" ? homedir3() : cwd;
|
|
365
475
|
}
|
|
366
476
|
function getHooksDir(scope, cwd) {
|
|
367
|
-
return
|
|
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
|
|
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(
|
|
523
|
+
return readFile2(join3(sourcePath, scriptFile));
|
|
414
524
|
}
|
|
415
|
-
const fetchDir = await mkdtemp(
|
|
525
|
+
const fetchDir = await mkdtemp(join3(dirname2(hooksDir), ".seedr-hook-"));
|
|
416
526
|
try {
|
|
417
|
-
const contentDir =
|
|
527
|
+
const contentDir = join3(fetchDir, "content");
|
|
418
528
|
await fetchItemToDestination(item, contentDir);
|
|
419
|
-
return await readFile2(
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
612
|
-
import
|
|
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 =
|
|
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
|
-
|
|
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
|
|
1036
|
-
import
|
|
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 =
|
|
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
|
-
|
|
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
|
|
1162
|
-
import { join as
|
|
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
|
|
1167
|
-
import
|
|
1168
|
-
var home =
|
|
1169
|
-
var PLUGINS_DIR =
|
|
1170
|
-
var PLUGINS_CACHE_DIR =
|
|
1171
|
-
var INSTALLED_PLUGINS_PATH =
|
|
1172
|
-
var KNOWN_MARKETPLACES_PATH =
|
|
1173
|
-
var MARKETPLACES_DIR =
|
|
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
|
|
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(
|
|
1239
|
-
return resolveContained(PLUGINS_CACHE_DIR,
|
|
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 =
|
|
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,
|
|
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 =
|
|
1444
|
+
const contentPath = join4(staging, "content");
|
|
1335
1445
|
const fetched = await stageContent(item, contentPath);
|
|
1336
|
-
const pluginJson = await readJson(
|
|
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
|
-
|
|
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,
|
|
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(
|
|
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,
|
|
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 ? ` ${
|
|
1582
|
-
lines.push(` ${
|
|
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(
|
|
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(
|
|
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)} ${
|
|
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
|
|
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:
|
|
1771
|
-
hook:
|
|
1772
|
-
agent:
|
|
1773
|
-
plugin:
|
|
1774
|
-
command:
|
|
1775
|
-
settings:
|
|
1776
|
-
mcp:
|
|
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(
|
|
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(
|
|
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(
|
|
1835
|
-
if (known.length > 0) console.log(
|
|
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(
|
|
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] ??
|
|
1955
|
+
const colorFn = TYPE_COLORS[itemType] ?? chalk9.white;
|
|
1845
1956
|
console.log(colorFn(`
|
|
1846
1957
|
${itemType.toUpperCase()}S`));
|
|
1847
|
-
console.log(
|
|
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 ?
|
|
1961
|
+
const featured = item.featured ? chalk9.yellow("\u2605 ") : " ";
|
|
1851
1962
|
console.log(
|
|
1852
|
-
`${featured}${
|
|
1963
|
+
`${featured}${chalk9.white(item.slug.padEnd(SLUG_COLUMN_WIDTH))} ${chalk9.gray(compatIcons)}`
|
|
1853
1964
|
);
|
|
1854
|
-
console.log(` ${
|
|
1965
|
+
console.log(` ${chalk9.gray(item.description)}`);
|
|
1855
1966
|
}
|
|
1856
1967
|
}
|
|
1857
1968
|
console.log("");
|
|
1858
1969
|
console.log(
|
|
1859
|
-
|
|
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] ??
|
|
1984
|
+
const colorFn = TYPE_COLORS[group.type] ?? chalk9.white;
|
|
1874
1985
|
console.log(colorFn(`${group.type.toUpperCase()}S`));
|
|
1875
1986
|
}
|
|
1876
|
-
console.log(
|
|
1987
|
+
console.log(chalk9.blue(` ${CODING_AGENTS[group.agent].name}`));
|
|
1877
1988
|
for (const slug of group.slugs) {
|
|
1878
|
-
console.log(` ${
|
|
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(
|
|
1995
|
+
console.log(chalk9.gray(`Note: ${SETTINGS_NOT_DISCOVERABLE}`));
|
|
1885
1996
|
}
|
|
1886
1997
|
if (total === 0) {
|
|
1887
|
-
console.log(
|
|
1998
|
+
console.log(chalk9.yellow("No items installed"));
|
|
1888
1999
|
} else {
|
|
1889
|
-
console.log(
|
|
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
|
|
1908
|
-
import
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1978
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
2026
|
-
import
|
|
2027
|
-
import { join as
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
2185
|
+
console.log(chalk11.yellow("Cancelled"));
|
|
2075
2186
|
return 0;
|
|
2076
2187
|
}
|
|
2077
2188
|
}
|
|
2078
2189
|
for (const agent of agents) {
|
|
2079
|
-
const spinner =
|
|
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(
|
|
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.
|
|
2217
|
+
version: "0.1.92",
|
|
2107
2218
|
description: "Seed your projects with AI configurations",
|
|
2108
2219
|
type: "module",
|
|
2109
2220
|
bin: {
|
package/dist/index.js
CHANGED