@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.
- package/dist/{chunk-JTCNXHYF.js → chunk-PEGEA2KN.js} +169 -81
- package/dist/cli.js +211 -100
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
169
|
-
return rel !== "" && !isAbsolute(rel) && rel !== ".." && !rel.startsWith(`..${
|
|
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
|
|
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 =
|
|
183
|
-
const resolved =
|
|
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 =
|
|
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 =
|
|
203
|
-
if (parent === 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(
|
|
211
|
-
const realDir = await realpathOrNull(
|
|
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(
|
|
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 =
|
|
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(
|
|
361
|
+
await ensureDir(dirname5(destination));
|
|
272
362
|
await removePathEntry(destination);
|
|
273
363
|
if (method === "symlink") {
|
|
274
|
-
const relPath =
|
|
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(
|
|
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
|
|
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(
|
|
382
|
+
await ensureDir(dirname5(destination));
|
|
293
383
|
await removePathEntry(destination);
|
|
294
384
|
if (method === "symlink") {
|
|
295
|
-
const relPath =
|
|
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 =
|
|
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 (
|
|
412
|
-
const parent =
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
537
|
-
const
|
|
538
|
-
const content = await loadFile(
|
|
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
|
|
634
|
+
const typeDir2 = typeDirName(item.type);
|
|
545
635
|
return {
|
|
546
|
-
local: REGISTRY_PATH ?
|
|
547
|
-
remote: `${REGISTRY_URL}/${
|
|
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(
|
|
650
|
+
return await readFile3(join13(local, mainFile), "utf-8");
|
|
564
651
|
} catch {
|
|
565
652
|
}
|
|
566
653
|
}
|
|
567
|
-
const tempRoot = await mkdtemp(
|
|
654
|
+
const tempRoot = await mkdtemp(join13(tmpdir(), "seedr-content-"));
|
|
568
655
|
try {
|
|
569
|
-
const destination =
|
|
656
|
+
const destination = join13(tempRoot, "item");
|
|
570
657
|
await fetchItemToDestination(item, destination);
|
|
571
|
-
return await readFile3(
|
|
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(
|
|
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
|
|
597
|
-
return
|
|
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 =
|
|
643
|
-
await mkdir2(
|
|
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(
|
|
654
|
-
const stagingDir = await mkdtemp(
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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 ?
|
|
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
|
|
850
|
+
return join14(cwd, ".claude/settings.json");
|
|
764
851
|
case "user":
|
|
765
|
-
return
|
|
852
|
+
return join14(home, ".claude/settings.json");
|
|
766
853
|
case "local":
|
|
767
|
-
return
|
|
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 ?
|
|
861
|
+
return isUser ? join14(home, ".claude.json") : join14(cwd, ".mcp.json");
|
|
775
862
|
case "codex":
|
|
776
|
-
return isUser ?
|
|
863
|
+
return isUser ? join14(home, ".codex", "config.toml") : join14(cwd, ".codex", "config.toml");
|
|
777
864
|
case "opencode":
|
|
778
|
-
return isUser ?
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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(
|
|
1080
|
+
await ensureDir(dirname7(destPath));
|
|
994
1081
|
await removePathEntry(destPath);
|
|
995
|
-
const relPath =
|
|
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-
|
|
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
|
|
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.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, "
|
|
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.93",
|
|
2107
2218
|
description: "Seed your projects with AI configurations",
|
|
2108
2219
|
type: "module",
|
|
2109
2220
|
bin: {
|
package/dist/index.js
CHANGED