@rbbtsn0w/adg 0.2.1 → 0.3.0-beta.1
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/README.md +6 -0
- package/dist/bin/adg.js +103 -56
- package/dist/src/adapters/index.js +11 -0
- package/dist/src/agents/index.js +1 -1
- package/dist/src/agents/registry.js +12 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -361,6 +361,12 @@ Debugging tips:
|
|
|
361
361
|
- GitHub clone/sparse logic is injectable (`gitRunner`) and covered offline by
|
|
362
362
|
the test suite; live network clones are exercised by `import owner/repo`.
|
|
363
363
|
|
|
364
|
+
## Contributing
|
|
365
|
+
|
|
366
|
+
All feature/fix pull requests target the **`beta`** integration branch; `main`
|
|
367
|
+
is reserved for stable releases. See [CONTRIBUTING.md](CONTRIBUTING.md) and
|
|
368
|
+
[docs/branching-and-release.md](docs/branching-and-release.md).
|
|
369
|
+
|
|
364
370
|
## License
|
|
365
371
|
|
|
366
372
|
MIT
|
package/dist/bin/adg.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
|
+
import pc from "picocolors";
|
|
3
4
|
import { spawnSync } from "node:child_process";
|
|
4
5
|
import { readFileSync, realpathSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
5
7
|
import { dirname, join, resolve } from "node:path";
|
|
6
8
|
import { fileURLToPath } from "node:url";
|
|
7
9
|
import { checkForUpdate, formatUpdateNotice } from "../src/update-check.js";
|
|
@@ -21,9 +23,24 @@ import { selectTargetsInteractive } from "../src/commands/select-agents.js";
|
|
|
21
23
|
import { selectPluginsInteractive } from "../src/commands/select-plugins.js";
|
|
22
24
|
import { selectScopeInteractive } from "../src/commands/select-scope.js";
|
|
23
25
|
import { confirmFullInstall, selectComponentsInteractive } from "../src/commands/select-components.js";
|
|
24
|
-
import { globalPluginsDir, projectPluginsDir } from "../src/paths.js";
|
|
26
|
+
import { globalPluginsDir, installedPluginDir, projectPluginsDir } from "../src/paths.js";
|
|
25
27
|
import { COMPONENT_TYPES } from "../src/types.js";
|
|
26
|
-
import { getAgent } from "../src/agents/index.js";
|
|
28
|
+
import { agentsForComponents, getAgent } from "../src/agents/index.js";
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Semantic colors, mirroring `adg skills list` so output reads the same across
|
|
31
|
+
// commands: cyan = primary identifiers (plugins, agents, sources), dim =
|
|
32
|
+
// secondary metadata (paths, hashes, sub-details), green = success, yellow =
|
|
33
|
+
// notes/warnings, red = errors, bold = section titles. picocolors auto-disables
|
|
34
|
+
// on non-TTY / NO_COLOR, so piped output and tests stay plain.
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
const ui = {
|
|
37
|
+
title: (s) => pc.bold(s),
|
|
38
|
+
name: (s) => pc.cyan(s),
|
|
39
|
+
meta: (s) => pc.dim(s),
|
|
40
|
+
ok: (s) => pc.green(s),
|
|
41
|
+
warn: (s) => pc.yellow(s),
|
|
42
|
+
err: (s) => pc.red(s),
|
|
43
|
+
};
|
|
27
44
|
const FLAGS = {
|
|
28
45
|
// Short flags are first-letter aliases. Where several long flags share a
|
|
29
46
|
// first letter, the highest-frequency one wins the short and the rest stay
|
|
@@ -208,7 +225,7 @@ function wantsHelp(args) {
|
|
|
208
225
|
return args.includes("-h") || args.includes("--help");
|
|
209
226
|
}
|
|
210
227
|
function fail(msg) {
|
|
211
|
-
console.error(
|
|
228
|
+
console.error(`${ui.err("error:")} ${msg}\n`);
|
|
212
229
|
console.error(TOP_USAGE);
|
|
213
230
|
process.exit(1);
|
|
214
231
|
}
|
|
@@ -231,9 +248,9 @@ function reportAgents(agents, verb) {
|
|
|
231
248
|
for (const r of agents ?? []) {
|
|
232
249
|
const name = getAgent(r.agent)?.displayName ?? r.agent;
|
|
233
250
|
if (r.affected.length > 0)
|
|
234
|
-
console.log(`${verb} in ${name}: ${r.affected.join(", ")}`);
|
|
251
|
+
console.log(`${ui.ok(verb)} in ${ui.name(name)}: ${r.affected.join(", ")}`);
|
|
235
252
|
else if (r.skipped)
|
|
236
|
-
console.log(`note: \`${r.agent}\` CLI not found — run \`adg plugins link --target ${r.agent}\` after installing it.`);
|
|
253
|
+
console.log(ui.warn(`note: \`${r.agent}\` CLI not found — run \`adg plugins link --target ${r.agent}\` after installing it.`));
|
|
237
254
|
}
|
|
238
255
|
}
|
|
239
256
|
function resolveTargets(target) {
|
|
@@ -264,7 +281,7 @@ function parseVerb(name, flags, rest) {
|
|
|
264
281
|
return { values: values, positionals };
|
|
265
282
|
}
|
|
266
283
|
catch (err) {
|
|
267
|
-
console.error(
|
|
284
|
+
console.error(`${ui.err("error:")} ${err instanceof Error ? err.message : String(err)}\n`);
|
|
268
285
|
console.error(renderVerbHelp(name));
|
|
269
286
|
process.exit(1);
|
|
270
287
|
}
|
|
@@ -290,12 +307,21 @@ function formatColumns(items, opts = {}) {
|
|
|
290
307
|
}
|
|
291
308
|
return lines.join("\n");
|
|
292
309
|
}
|
|
310
|
+
/** Abbreviate the home-directory prefix of an absolute path to `~` (POSIX `/` or Windows `\`). */
|
|
311
|
+
function abbrevHome(p) {
|
|
312
|
+
const home = homedir();
|
|
313
|
+
if (p === home)
|
|
314
|
+
return "~";
|
|
315
|
+
if (p.startsWith(home + "/") || p.startsWith(home + "\\"))
|
|
316
|
+
return "~" + p.slice(home.length);
|
|
317
|
+
return p;
|
|
318
|
+
}
|
|
293
319
|
/** Print a plugin's components, each expanded to its member names (verbose view). */
|
|
294
320
|
function printContents(contents, headerIndent) {
|
|
295
321
|
const entries = Object.entries(contents ?? {}).filter(([, names]) => names.length > 0);
|
|
296
322
|
for (const [type, names] of entries) {
|
|
297
323
|
const maxColWidth = Math.max(1, ...names.map((n) => n.length));
|
|
298
|
-
console.log(`${" ".repeat(headerIndent)}${type} (${names.length}):`);
|
|
324
|
+
console.log(`${" ".repeat(headerIndent)}${ui.name(type)} ${ui.meta(`(${names.length}):`)}`);
|
|
299
325
|
console.log(formatColumns(names, { indent: headerIndent + 2, maxColWidth }));
|
|
300
326
|
}
|
|
301
327
|
}
|
|
@@ -308,7 +334,7 @@ async function runPlugins(rawVerb, rest) {
|
|
|
308
334
|
const verb = PLUGIN_ALIASES[rawVerb] ?? rawVerb;
|
|
309
335
|
const cmd = PLUGIN_COMMANDS[verb];
|
|
310
336
|
if (!cmd) {
|
|
311
|
-
console.error(
|
|
337
|
+
console.error(`${ui.err("error:")} unknown plugins subcommand: ${rawVerb}\n`);
|
|
312
338
|
console.error(renderPluginsHelp());
|
|
313
339
|
process.exit(1);
|
|
314
340
|
}
|
|
@@ -330,16 +356,16 @@ async function runPlugins(rawVerb, rest) {
|
|
|
330
356
|
fail(`invalid --type "${values.type}" (expected plugin|marketplace|all)`);
|
|
331
357
|
}
|
|
332
358
|
const res = initScaffold({ name, dir, type, description: values.description, author: values.author, skill: values.skill?.[0] });
|
|
333
|
-
console.log(`created ${type} at ${res.pluginDir}`);
|
|
359
|
+
console.log(`${ui.ok(`created ${type}`)} at ${ui.name(res.pluginDir)}`);
|
|
334
360
|
for (const f of res.created)
|
|
335
|
-
console.log(` + ${f}`);
|
|
361
|
+
console.log(ui.meta(` + ${f}`));
|
|
336
362
|
return;
|
|
337
363
|
}
|
|
338
364
|
case "adapt": {
|
|
339
365
|
const { values, positionals } = parseVerb(verb, cmd.flags, rest);
|
|
340
366
|
const pluginDir = resolve(positionals[0] ?? process.cwd());
|
|
341
367
|
for (const r of adaptPlugin(pluginDir, resolveTargets(values.target))) {
|
|
342
|
-
console.log(
|
|
368
|
+
console.log(`${ui.ok("adapted")} ${ui.name(r.target)} ${ui.meta(`-> ${r.file}`)}`);
|
|
343
369
|
}
|
|
344
370
|
return;
|
|
345
371
|
}
|
|
@@ -348,12 +374,12 @@ async function runPlugins(rawVerb, rest) {
|
|
|
348
374
|
const pluginDir = resolve(positionals[0] ?? process.cwd());
|
|
349
375
|
const res = validatePlugin(pluginDir);
|
|
350
376
|
if (res.ok) {
|
|
351
|
-
console.log(
|
|
377
|
+
console.log(`${ui.ok("ok:")} ${ui.name(pluginDir)} is a valid ADG plugin`);
|
|
352
378
|
}
|
|
353
379
|
else {
|
|
354
|
-
console.error(
|
|
380
|
+
console.error(`${ui.err("invalid:")} ${ui.name(pluginDir)}`);
|
|
355
381
|
for (const i of res.issues)
|
|
356
|
-
console.error(` - ${i}`);
|
|
382
|
+
console.error(ui.warn(` - ${i}`));
|
|
357
383
|
process.exit(1);
|
|
358
384
|
}
|
|
359
385
|
return;
|
|
@@ -404,14 +430,14 @@ async function runPlugins(rawVerb, rest) {
|
|
|
404
430
|
scope: global ? "user" : "project",
|
|
405
431
|
});
|
|
406
432
|
for (const name of converted)
|
|
407
|
-
console.log(`converted native manifest -> .agents/.plugin.json: ${name}`);
|
|
433
|
+
console.log(ui.meta(`converted native manifest -> .agents/.plugin.json: ${name}`));
|
|
408
434
|
if (order.length > 1)
|
|
409
|
-
console.log(`install order: ${order.join(" -> ")}`);
|
|
435
|
+
console.log(ui.meta(`install order: ${order.join(" -> ")}`));
|
|
410
436
|
for (const res of installed) {
|
|
411
|
-
console.log(
|
|
412
|
-
console.log(` folderHash: ${res.folderHash}`);
|
|
437
|
+
console.log(`${ui.ok("added")} ${ui.name(res.name)} ${ui.meta(`-> ${res.installedTo}`)}`);
|
|
438
|
+
console.log(ui.meta(` folderHash: ${res.folderHash}`));
|
|
413
439
|
for (const f of res.adapted)
|
|
414
|
-
console.log(` adapted: ${f}`);
|
|
440
|
+
console.log(ui.meta(` adapted: ${f}`));
|
|
415
441
|
}
|
|
416
442
|
reportAgents(agents, "enabled");
|
|
417
443
|
return;
|
|
@@ -430,7 +456,7 @@ async function runPlugins(rawVerb, rest) {
|
|
|
430
456
|
pluginsDir: resolveScopeDir(values),
|
|
431
457
|
description: values.description,
|
|
432
458
|
});
|
|
433
|
-
console.log(
|
|
459
|
+
console.log(`${ui.ok("imported skills into")} ${ui.name(res.name)} ${ui.meta(`-> ${res.installedTo}`)}`);
|
|
434
460
|
return;
|
|
435
461
|
}
|
|
436
462
|
case "link": {
|
|
@@ -440,12 +466,12 @@ async function runPlugins(rawVerb, rest) {
|
|
|
440
466
|
fail("plugins link requires --target claude|codex");
|
|
441
467
|
const res = linkPlugins({ pluginsDir: resolveScopeDir(values), target, global: Boolean(values.global) });
|
|
442
468
|
for (const a of res.actions) {
|
|
443
|
-
console.log(
|
|
469
|
+
console.log(`${ui.ok("linked")} ${ui.name(a.name)} ${ui.meta(`[${res.target}]`)}${a.linkedTo ? ui.meta(` -> ${a.linkedTo}`) : ""}`);
|
|
444
470
|
for (const f of a.adapted)
|
|
445
|
-
console.log(` adapted: ${f}`);
|
|
471
|
+
console.log(ui.meta(` adapted: ${f}`));
|
|
446
472
|
}
|
|
447
473
|
if (res.cliSkipped) {
|
|
448
|
-
console.log(`note: \`${target}\` CLI not found — manifests were generated, but nothing was enabled in ${target}.`);
|
|
474
|
+
console.log(ui.warn(`note: \`${target}\` CLI not found — manifests were generated, but nothing was enabled in ${target}.`));
|
|
449
475
|
}
|
|
450
476
|
return;
|
|
451
477
|
}
|
|
@@ -456,9 +482,9 @@ async function runPlugins(rawVerb, rest) {
|
|
|
456
482
|
scope: scopeOf(values),
|
|
457
483
|
});
|
|
458
484
|
for (const r of results)
|
|
459
|
-
console.log(`${r.changed ? "updated" : "unchanged"} ${r.name}@${r.version}`);
|
|
485
|
+
console.log(`${r.changed ? ui.ok("updated") : ui.meta("unchanged")} ${ui.name(`${r.name}@${r.version}`)}`);
|
|
460
486
|
for (const m of missing)
|
|
461
|
-
console.error(` ! missing directory for locked plugin: ${m}`);
|
|
487
|
+
console.error(ui.warn(` ! missing directory for locked plugin: ${m}`));
|
|
462
488
|
reportAgents(agents, "re-synced");
|
|
463
489
|
return;
|
|
464
490
|
}
|
|
@@ -475,17 +501,17 @@ async function runPlugins(rawVerb, rest) {
|
|
|
475
501
|
scope: scopeOf(values),
|
|
476
502
|
});
|
|
477
503
|
if (res.removedDir)
|
|
478
|
-
console.log(
|
|
504
|
+
console.log(`${ui.ok("removed")} ${ui.name(res.name)} ${ui.meta(`-> ${res.removedDir}`)}`);
|
|
479
505
|
else
|
|
480
|
-
console.log(
|
|
506
|
+
console.log(`${ui.ok("removed")} ${ui.name(res.name)} ${ui.meta("(no directory on disk)")}`);
|
|
481
507
|
for (const link of res.unlinked)
|
|
482
|
-
console.log(` unlinked: ${link}`);
|
|
508
|
+
console.log(ui.meta(` unlinked: ${link}`));
|
|
483
509
|
for (const r of res.agents ?? []) {
|
|
484
510
|
if (r.affected.length > 0)
|
|
485
|
-
console.log(` disabled in ${getAgent(r.agent)?.displayName ?? r.agent}`);
|
|
511
|
+
console.log(ui.meta(` disabled in ${getAgent(r.agent)?.displayName ?? r.agent}`));
|
|
486
512
|
}
|
|
487
513
|
if (!res.removedFromLock && !res.removedDir) {
|
|
488
|
-
console.log(` ${res.name} was not recorded in the lock`);
|
|
514
|
+
console.log(ui.warn(` ${res.name} was not recorded in the lock`));
|
|
489
515
|
}
|
|
490
516
|
return;
|
|
491
517
|
}
|
|
@@ -494,21 +520,42 @@ async function runPlugins(rawVerb, rest) {
|
|
|
494
520
|
const pluginsDir = resolveScopeDir(values);
|
|
495
521
|
const plugins = listPlugins(pluginsDir);
|
|
496
522
|
if (plugins.length === 0) {
|
|
497
|
-
console.log(`no plugins recorded in ${pluginsDir}`);
|
|
523
|
+
console.log(ui.meta(`no plugins recorded in ${pluginsDir}`));
|
|
498
524
|
return;
|
|
499
525
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
526
|
+
// Pre-compute each plugin's display row so the name/path columns can be
|
|
527
|
+
// aligned across rows (à la `adg skills list`). The `Agents:` column is
|
|
528
|
+
// derived from the exposed component types — which agents can adapt it.
|
|
529
|
+
const PATH_MAX = 44;
|
|
530
|
+
const rows = plugins.map((p) => {
|
|
531
|
+
const exposed = Object.entries(p.contents ?? {}).filter(([, names]) => names.length > 0);
|
|
532
|
+
const types = exposed.map(([type]) => type);
|
|
533
|
+
const agents = agentsForComponents(types).map((a) => a.displayName);
|
|
534
|
+
return {
|
|
535
|
+
p,
|
|
536
|
+
label: `${p.name}@${p.version}`,
|
|
537
|
+
path: abbrevHome(installedPluginDir(pluginsDir, p.name, p.origin)),
|
|
538
|
+
agents: agents.length > 0 ? agents.join(", ") : "—",
|
|
539
|
+
counts: exposed.map(([type, names]) => `${type}: ${names.length}`),
|
|
540
|
+
};
|
|
541
|
+
});
|
|
542
|
+
const nameW = Math.max(...rows.map((r) => r.label.length));
|
|
543
|
+
const pathW = Math.min(PATH_MAX, Math.max(...rows.map((r) => r.path.length)));
|
|
544
|
+
const ellip = (s, w) => (s.length > w ? "…" + s.slice(s.length - w + 1) : s);
|
|
545
|
+
// Color mirrors `adg skills list`: cyan name, dim path / dim "Agents:"
|
|
546
|
+
// label with the agent names left bright, and the provenance/counts line
|
|
547
|
+
// fully dimmed as secondary metadata. Widths are measured on the uncolored
|
|
548
|
+
// strings (above), so wrapping the padded text keeps columns aligned.
|
|
549
|
+
// picocolors auto-disables on non-TTY / NO_COLOR, so pipes stay plain.
|
|
550
|
+
for (const r of rows) {
|
|
551
|
+
const partial = r.p.selection ? " (partial)" : "";
|
|
552
|
+
const name = ui.name(r.label.padEnd(nameW));
|
|
553
|
+
const path = ui.meta(ellip(r.path, pathW).padEnd(pathW));
|
|
554
|
+
console.log(`${name} ${path} ${ui.meta("Agents:")} ${r.agents}`);
|
|
555
|
+
const provenance = `[${r.p.origin.type}] ${r.p.folderHash.slice(0, 19)}${partial}`;
|
|
556
|
+
console.log(ui.meta(` ${[provenance, ...r.counts].join(" ")}`));
|
|
557
|
+
if (values.verbose)
|
|
558
|
+
printContents(r.p.contents, 4);
|
|
512
559
|
}
|
|
513
560
|
return;
|
|
514
561
|
}
|
|
@@ -516,11 +563,11 @@ async function runPlugins(rawVerb, rest) {
|
|
|
516
563
|
const { values } = parseVerb(verb, cmd.flags, rest);
|
|
517
564
|
const res = migrateLayout(resolveScopeDir(values));
|
|
518
565
|
for (const m of res.moved)
|
|
519
|
-
console.log(
|
|
566
|
+
console.log(`${ui.ok("moved")} ${ui.name(m.name)}: ${ui.meta(`${m.from} -> ${m.to}`)}`);
|
|
520
567
|
for (const m of res.missing)
|
|
521
|
-
console.error(` ! missing directory for locked plugin: ${m}`);
|
|
568
|
+
console.error(ui.warn(` ! missing directory for locked plugin: ${m}`));
|
|
522
569
|
if (res.moved.length === 0)
|
|
523
|
-
console.log(`nothing to migrate (${res.unchanged.length} already in place)`);
|
|
570
|
+
console.log(ui.meta(`nothing to migrate (${res.unchanged.length} already in place)`));
|
|
524
571
|
return;
|
|
525
572
|
}
|
|
526
573
|
case "marketplace":
|
|
@@ -563,7 +610,7 @@ async function runMarketplace(args) {
|
|
|
563
610
|
const dir = resolveScopeDir(values);
|
|
564
611
|
const groups = marketplaceList({ pluginsDir: dir });
|
|
565
612
|
if (groups.length === 0) {
|
|
566
|
-
console.log("No plugins installed.");
|
|
613
|
+
console.log(ui.meta("No plugins installed."));
|
|
567
614
|
return;
|
|
568
615
|
}
|
|
569
616
|
// Verbose: drill each plugin down to its components (reuses `plugins list -v`).
|
|
@@ -571,12 +618,12 @@ async function runMarketplace(args) {
|
|
|
571
618
|
for (const g of groups) {
|
|
572
619
|
const ref = g.ref ? `@${g.ref}` : "";
|
|
573
620
|
const n = g.installed.length;
|
|
574
|
-
const tag = g.remote ? "" : " (local — re-run add to update)";
|
|
575
|
-
console.log(`${g.source}${ref} (${n} plugin${n !== 1 ? "s" : ""})${tag}`);
|
|
621
|
+
const tag = g.remote ? "" : ui.warn(" (local — re-run add to update)");
|
|
622
|
+
console.log(`${ui.name(`${g.source}${ref}`)} ${ui.meta(`(${n} plugin${n !== 1 ? "s" : ""})`)}${tag}`);
|
|
576
623
|
if (byName) {
|
|
577
624
|
for (const name of g.installed) {
|
|
578
625
|
const p = byName.get(name);
|
|
579
|
-
console.log(` ${name}${p?.selection ? " (partial)" : ""}`);
|
|
626
|
+
console.log(` ${ui.name(name)}${p?.selection ? ui.meta(" (partial)") : ""}`);
|
|
580
627
|
printContents(p?.contents, 4);
|
|
581
628
|
}
|
|
582
629
|
}
|
|
@@ -599,11 +646,11 @@ async function runMarketplace(args) {
|
|
|
599
646
|
});
|
|
600
647
|
for (const r of results) {
|
|
601
648
|
const conv = r.converted.length ? ` (${r.converted.length} converted from native)` : "";
|
|
602
|
-
console.log(
|
|
649
|
+
console.log(`${ui.ok("upgraded")} ${ui.name(r.source)}: ${r.updated.length} plugin(s)${ui.meta(conv)}`);
|
|
603
650
|
for (const p of r.updated)
|
|
604
|
-
console.log(` ${p.name}
|
|
651
|
+
console.log(` ${ui.name(p.name)} ${ui.meta(`-> ${p.installedTo}`)}`);
|
|
605
652
|
if (r.available.length > 0) {
|
|
606
|
-
console.log(` ${r.available.length} more available (use --all): ${r.available.join(", ")}`);
|
|
653
|
+
console.log(ui.meta(` ${r.available.length} more available (use --all): ${r.available.join(", ")}`));
|
|
607
654
|
}
|
|
608
655
|
}
|
|
609
656
|
return;
|
|
@@ -622,11 +669,11 @@ async function runMarketplace(args) {
|
|
|
622
669
|
force: values.force,
|
|
623
670
|
deactivate: true,
|
|
624
671
|
});
|
|
625
|
-
console.log(
|
|
672
|
+
console.log(`${ui.ok("removed")} ${res.removed.length} plugin(s) from ${ui.name(res.source)}: ${res.removed.join(", ")}`);
|
|
626
673
|
return;
|
|
627
674
|
}
|
|
628
675
|
default: {
|
|
629
|
-
console.error(
|
|
676
|
+
console.error(`${ui.err("error:")} unknown marketplace subcommand: ${sub}\n`);
|
|
630
677
|
console.error(MARKETPLACE_USAGE);
|
|
631
678
|
process.exit(1);
|
|
632
679
|
}
|
|
@@ -729,7 +776,7 @@ function isInvokedDirectly() {
|
|
|
729
776
|
}
|
|
730
777
|
if (isInvokedDirectly()) {
|
|
731
778
|
main(process.argv.slice(2)).catch((err) => {
|
|
732
|
-
console.error(
|
|
779
|
+
console.error(`${ui.err("error:")} ${err instanceof Error ? err.message : String(err)}`);
|
|
733
780
|
process.exit(1);
|
|
734
781
|
});
|
|
735
782
|
}
|
|
@@ -7,4 +7,15 @@ export const ADAPTERS = {
|
|
|
7
7
|
openai: toCodexManifest,
|
|
8
8
|
};
|
|
9
9
|
export const ADAPTER_TARGETS = ["claude", "codex"];
|
|
10
|
+
/**
|
|
11
|
+
* Component categories each adapter target can actually express, mirroring what
|
|
12
|
+
* the adapters emit: the Claude manifest carries skills/agents/commands/hooks/mcp
|
|
13
|
+
* (`toAnthropicManifest`), while Codex only consumes skills (`toCodexManifest`).
|
|
14
|
+
* `apps` is emitted by neither, so it maps to no target. Used to derive which
|
|
15
|
+
* agents a plugin is adaptable to from its exposed component types.
|
|
16
|
+
*/
|
|
17
|
+
export const ADAPTER_COMPONENTS = {
|
|
18
|
+
claude: ["skills", "agents", "commands", "hooks", "mcp"],
|
|
19
|
+
codex: ["skills"],
|
|
20
|
+
};
|
|
10
21
|
export { toAnthropicManifest, toCodexManifest };
|
package/dist/src/agents/index.js
CHANGED
|
@@ -6,5 +6,5 @@ import { codexAgent } from "./codex.js";
|
|
|
6
6
|
registerAgent(claudeAgent);
|
|
7
7
|
registerAgent(codexAgent);
|
|
8
8
|
export * from "./types.js";
|
|
9
|
-
export { registerAgent, getAgent, allAgents, detectedAgents, resolveAgents } from "./registry.js";
|
|
9
|
+
export { registerAgent, getAgent, allAgents, detectedAgents, resolveAgents, agentsForComponents } from "./registry.js";
|
|
10
10
|
export { writeClaudeCatalog } from "./claude.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ADAPTER_COMPONENTS } from "../adapters/index.js";
|
|
1
2
|
/**
|
|
2
3
|
* The agent registry — the "factory": construction/lookup only. Orchestration
|
|
3
4
|
* (looping, dependency order, store writes) stays in the command layer.
|
|
@@ -16,6 +17,17 @@ export function allAgents() {
|
|
|
16
17
|
export function detectedAgents(env) {
|
|
17
18
|
return allAgents().filter((a) => a.detect(env));
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Registered agents whose adapter can express at least one of the given exposed
|
|
22
|
+
* component types — i.e. the agents a plugin is adaptable to. An empty `types`
|
|
23
|
+
* (no manifest / nothing exposed) can't be proven incompatible, so all agents
|
|
24
|
+
* are returned.
|
|
25
|
+
*/
|
|
26
|
+
export function agentsForComponents(types) {
|
|
27
|
+
if (types.length === 0)
|
|
28
|
+
return allAgents();
|
|
29
|
+
return allAgents().filter((a) => (ADAPTER_COMPONENTS[a.adaptTarget] ?? []).some((c) => types.includes(c)));
|
|
30
|
+
}
|
|
19
31
|
/** Agents matching the given ids, or every registered agent when none are given. */
|
|
20
32
|
export function resolveAgents(targets) {
|
|
21
33
|
if (!targets)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbbtsn0w/adg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-beta.1",
|
|
4
4
|
"description": "Agent Directory Group (ADG) toolkit — two domains: plugins and skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"adg": "node ./bin/adg.ts",
|
|
26
|
-
"build": "
|
|
26
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json --noCheck && node -e \"require('fs').chmodSync('dist/bin/adg.js',0o755)\"",
|
|
27
27
|
"test": "node --test 'test/**/*.test.ts'",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
29
|
"prepare": "npm run typecheck",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@semantic-release/npm": "^13.1.5",
|
|
53
53
|
"@semantic-release/release-notes-generator": "^14.1.1",
|
|
54
54
|
"@types/node": "^22.0.0",
|
|
55
|
+
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
55
56
|
"semantic-release": "^25.0.5",
|
|
56
57
|
"typescript": "^5.6.0"
|
|
57
58
|
}
|