@jaggerxtrm/specialists 2.1.20 → 2.1.21

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.
Files changed (2) hide show
  1. package/dist/index.js +173 -63
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18242,23 +18242,128 @@ var init_list = __esm(() => {
18242
18242
  };
18243
18243
  });
18244
18244
 
18245
+ // src/cli/models.ts
18246
+ var exports_models = {};
18247
+ __export(exports_models, {
18248
+ run: () => run4
18249
+ });
18250
+ import { spawnSync as spawnSync3 } from "node:child_process";
18251
+ function parsePiModels() {
18252
+ const r = spawnSync3("pi", ["--list-models"], {
18253
+ encoding: "utf8",
18254
+ stdio: "pipe",
18255
+ timeout: 8000
18256
+ });
18257
+ if (r.status !== 0 || r.error)
18258
+ return null;
18259
+ return r.stdout.split(`
18260
+ `).slice(1).map((line) => line.trim()).filter(Boolean).map((line) => {
18261
+ const cols = line.split(/\s+/);
18262
+ return {
18263
+ provider: cols[0] ?? "",
18264
+ model: cols[1] ?? "",
18265
+ context: cols[2] ?? "",
18266
+ maxOut: cols[3] ?? "",
18267
+ thinking: cols[4] === "yes",
18268
+ images: cols[5] === "yes"
18269
+ };
18270
+ }).filter((m) => m.provider && m.model);
18271
+ }
18272
+ function parseArgs2(argv) {
18273
+ const out = {};
18274
+ for (let i = 0;i < argv.length; i++) {
18275
+ if (argv[i] === "--provider" && argv[i + 1]) {
18276
+ out.provider = argv[++i];
18277
+ continue;
18278
+ }
18279
+ if (argv[i] === "--used") {
18280
+ out.used = true;
18281
+ continue;
18282
+ }
18283
+ }
18284
+ return out;
18285
+ }
18286
+ async function run4() {
18287
+ const args = parseArgs2(process.argv.slice(3));
18288
+ const loader = new SpecialistLoader;
18289
+ const specialists = await loader.list();
18290
+ const usedBy = new Map;
18291
+ for (const s of specialists) {
18292
+ const key = s.model;
18293
+ if (!usedBy.has(key))
18294
+ usedBy.set(key, []);
18295
+ usedBy.get(key).push(s.name);
18296
+ }
18297
+ const allModels = parsePiModels();
18298
+ if (!allModels) {
18299
+ console.error("pi not found or failed — run specialists install");
18300
+ process.exit(1);
18301
+ }
18302
+ let models = allModels;
18303
+ if (args.provider) {
18304
+ models = models.filter((m) => m.provider.toLowerCase().includes(args.provider.toLowerCase()));
18305
+ }
18306
+ if (args.used) {
18307
+ models = models.filter((m) => usedBy.has(`${m.provider}/${m.model}`));
18308
+ }
18309
+ if (models.length === 0) {
18310
+ console.log("No models match.");
18311
+ return;
18312
+ }
18313
+ const byProvider = new Map;
18314
+ for (const m of models) {
18315
+ if (!byProvider.has(m.provider))
18316
+ byProvider.set(m.provider, []);
18317
+ byProvider.get(m.provider).push(m);
18318
+ }
18319
+ const total = models.length;
18320
+ console.log(`
18321
+ ${bold2(`Models on pi`)} ${dim2(`(${total} total)`)}
18322
+ `);
18323
+ for (const [provider, pModels] of byProvider) {
18324
+ console.log(` ${cyan2(provider)} ${dim2(`${pModels.length} model${pModels.length !== 1 ? "s" : ""}`)}`);
18325
+ const modelWidth = Math.max(...pModels.map((m) => m.model.length));
18326
+ for (const m of pModels) {
18327
+ const key = `${m.provider}/${m.model}`;
18328
+ const inUse = usedBy.get(key);
18329
+ const flags = [
18330
+ m.thinking ? green("thinking") : dim2("·"),
18331
+ m.images ? dim2("images") : ""
18332
+ ].filter(Boolean).join(" ");
18333
+ const ctx = dim2(`ctx ${m.context}`);
18334
+ const usedLabel = inUse ? ` ${yellow2("←")} ${dim2(inUse.join(", "))}` : "";
18335
+ console.log(` ${m.model.padEnd(modelWidth)} ${ctx.padEnd(18)} ${flags}${usedLabel}`);
18336
+ }
18337
+ console.log();
18338
+ }
18339
+ if (!args.used) {
18340
+ console.log(dim2(` --provider <name> filter by provider`));
18341
+ console.log(dim2(` --used only show models used by your specialists`));
18342
+ console.log();
18343
+ }
18344
+ }
18345
+ var bold2 = (s) => `\x1B[1m${s}\x1B[0m`, dim2 = (s) => `\x1B[2m${s}\x1B[0m`, cyan2 = (s) => `\x1B[36m${s}\x1B[0m`, yellow2 = (s) => `\x1B[33m${s}\x1B[0m`, green = (s) => `\x1B[32m${s}\x1B[0m`;
18346
+ var init_models = __esm(() => {
18347
+ init_loader();
18348
+ });
18349
+
18245
18350
  // src/cli/init.ts
18246
18351
  var exports_init = {};
18247
18352
  __export(exports_init, {
18248
- run: () => run4
18353
+ run: () => run5
18249
18354
  });
18250
18355
  import { existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync } from "node:fs";
18251
18356
  import { join as join5 } from "node:path";
18252
18357
  function ok(msg) {
18253
- console.log(` ${green("✓")} ${msg}`);
18358
+ console.log(` ${green2("✓")} ${msg}`);
18254
18359
  }
18255
18360
  function skip(msg) {
18256
- console.log(` ${yellow2("○")} ${msg}`);
18361
+ console.log(` ${yellow3("○")} ${msg}`);
18257
18362
  }
18258
- async function run4() {
18363
+ async function run5() {
18259
18364
  const cwd = process.cwd();
18260
18365
  console.log(`
18261
- ${bold2("specialists init")}
18366
+ ${bold3("specialists init")}
18262
18367
  `);
18263
18368
  const specialistsDir = join5(cwd, "specialists");
18264
18369
  if (existsSync3(specialistsDir)) {
@@ -18283,15 +18388,15 @@ ${bold2("specialists init")}
18283
18388
  ok("created AGENTS.md with Specialists section");
18284
18389
  }
18285
18390
  console.log(`
18286
- ${bold2("Done!")}
18391
+ ${bold3("Done!")}
18287
18392
  `);
18288
- console.log(` ${dim2("Next steps:")}`);
18289
- console.log(` 1. Add your specialists to ${yellow2("specialists/")}`);
18290
- console.log(` 2. Run ${yellow2("specialists list")} to verify they are discovered`);
18393
+ console.log(` ${dim3("Next steps:")}`);
18394
+ console.log(` 1. Add your specialists to ${yellow3("specialists/")}`);
18395
+ console.log(` 2. Run ${yellow3("specialists list")} to verify they are discovered`);
18291
18396
  console.log(` 3. Restart Claude Code to pick up AGENTS.md changes
18292
18397
  `);
18293
18398
  }
18294
- var bold2 = (s) => `\x1B[1m${s}\x1B[0m`, green = (s) => `\x1B[32m${s}\x1B[0m`, yellow2 = (s) => `\x1B[33m${s}\x1B[0m`, dim2 = (s) => `\x1B[2m${s}\x1B[0m`, AGENTS_BLOCK, AGENTS_MARKER = "## Specialists";
18399
+ var bold3 = (s) => `\x1B[1m${s}\x1B[0m`, green2 = (s) => `\x1B[32m${s}\x1B[0m`, yellow3 = (s) => `\x1B[33m${s}\x1B[0m`, dim3 = (s) => `\x1B[2m${s}\x1B[0m`, AGENTS_BLOCK, AGENTS_MARKER = "## Specialists";
18295
18400
  var init_init = __esm(() => {
18296
18401
  AGENTS_BLOCK = `
18297
18402
  ## Specialists
@@ -18306,10 +18411,10 @@ specialist without user intervention.
18306
18411
  // src/cli/edit.ts
18307
18412
  var exports_edit = {};
18308
18413
  __export(exports_edit, {
18309
- run: () => run5
18414
+ run: () => run6
18310
18415
  });
18311
18416
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
18312
- function parseArgs2(argv) {
18417
+ function parseArgs3(argv) {
18313
18418
  const name = argv[0];
18314
18419
  if (!name || name.startsWith("--")) {
18315
18420
  console.error("Usage: specialists edit <name> --<field> <value> [--dry-run]");
@@ -18371,8 +18476,8 @@ function setIn(doc2, path, value) {
18371
18476
  node.set(leaf, value);
18372
18477
  }
18373
18478
  }
18374
- async function run5() {
18375
- const args = parseArgs2(process.argv.slice(3));
18479
+ async function run6() {
18480
+ const args = parseArgs3(process.argv.slice(3));
18376
18481
  const { name, field, value, dryRun, scope } = args;
18377
18482
  const loader = new SpecialistLoader;
18378
18483
  const all = await loader.list();
@@ -18380,7 +18485,7 @@ async function run5() {
18380
18485
  if (!match) {
18381
18486
  const hint = scope ? ` (scope: ${scope})` : "";
18382
18487
  console.error(`Error: specialist "${name}" not found${hint}`);
18383
- console.error(` Run ${yellow3("specialists list")} to see available specialists`);
18488
+ console.error(` Run ${yellow4("specialists list")} to see available specialists`);
18384
18489
  process.exit(1);
18385
18490
  }
18386
18491
  const raw = readFileSync2(match.filePath, "utf-8");
@@ -18396,10 +18501,10 @@ async function run5() {
18396
18501
  const updated = doc2.toString();
18397
18502
  if (dryRun) {
18398
18503
  console.log(`
18399
- ${bold3(`[dry-run] ${match.filePath}`)}
18504
+ ${bold4(`[dry-run] ${match.filePath}`)}
18400
18505
  `);
18401
- console.log(dim3("--- current"));
18402
- console.log(dim3(`+++ updated`));
18506
+ console.log(dim4("--- current"));
18507
+ console.log(dim4(`+++ updated`));
18403
18508
  const oldLines = raw.split(`
18404
18509
  `);
18405
18510
  const newLines = updated.split(`
@@ -18407,8 +18512,8 @@ ${bold3(`[dry-run] ${match.filePath}`)}
18407
18512
  newLines.forEach((line, i) => {
18408
18513
  if (line !== oldLines[i]) {
18409
18514
  if (oldLines[i] !== undefined)
18410
- console.log(dim3(`- ${oldLines[i]}`));
18411
- console.log(green2(`+ ${line}`));
18515
+ console.log(dim4(`- ${oldLines[i]}`));
18516
+ console.log(green3(`+ ${line}`));
18412
18517
  }
18413
18518
  });
18414
18519
  console.log();
@@ -18416,9 +18521,9 @@ ${bold3(`[dry-run] ${match.filePath}`)}
18416
18521
  }
18417
18522
  writeFileSync2(match.filePath, updated, "utf-8");
18418
18523
  const displayValue = field === "tags" ? `[${typedValue.join(", ")}]` : String(typedValue);
18419
- console.log(`${green2("✓")} ${bold3(name)}: ${yellow3(field)} = ${displayValue}` + dim3(` (${match.filePath})`));
18524
+ console.log(`${green3("✓")} ${bold4(name)}: ${yellow4(field)} = ${displayValue}` + dim4(` (${match.filePath})`));
18420
18525
  }
18421
- var bold3 = (s) => `\x1B[1m${s}\x1B[0m`, green2 = (s) => `\x1B[32m${s}\x1B[0m`, yellow3 = (s) => `\x1B[33m${s}\x1B[0m`, dim3 = (s) => `\x1B[2m${s}\x1B[0m`, FIELD_MAP, VALID_PERMISSIONS;
18526
+ var bold4 = (s) => `\x1B[1m${s}\x1B[0m`, green3 = (s) => `\x1B[32m${s}\x1B[0m`, yellow4 = (s) => `\x1B[33m${s}\x1B[0m`, dim4 = (s) => `\x1B[2m${s}\x1B[0m`, FIELD_MAP, VALID_PERMISSIONS;
18422
18527
  var init_edit = __esm(() => {
18423
18528
  init_dist();
18424
18529
  init_loader();
@@ -18436,10 +18541,10 @@ var init_edit = __esm(() => {
18436
18541
  // src/cli/run.ts
18437
18542
  var exports_run = {};
18438
18543
  __export(exports_run, {
18439
- run: () => run6
18544
+ run: () => run7
18440
18545
  });
18441
18546
  import { join as join6 } from "node:path";
18442
- async function parseArgs3(argv) {
18547
+ async function parseArgs4(argv) {
18443
18548
  const name = argv[0];
18444
18549
  if (!name || name.startsWith("--")) {
18445
18550
  console.error('Usage: specialists run <name> [--prompt "..."] [--model <model>] [--no-beads]');
@@ -18465,7 +18570,7 @@ async function parseArgs3(argv) {
18465
18570
  }
18466
18571
  if (!prompt) {
18467
18572
  if (process.stdin.isTTY) {
18468
- process.stderr.write(dim4("Prompt (Ctrl+D when done): "));
18573
+ process.stderr.write(dim5("Prompt (Ctrl+D when done): "));
18469
18574
  }
18470
18575
  prompt = await new Promise((resolve) => {
18471
18576
  let buf = "";
@@ -18478,8 +18583,8 @@ async function parseArgs3(argv) {
18478
18583
  }
18479
18584
  return { name, prompt, model, noBeads };
18480
18585
  }
18481
- async function run6() {
18482
- const args = await parseArgs3(process.argv.slice(3));
18586
+ async function run7() {
18587
+ const args = await parseArgs4(process.argv.slice(3));
18483
18588
  const loader = new SpecialistLoader;
18484
18589
  const circuitBreaker = new CircuitBreaker;
18485
18590
  const hooks = new HookEmitter({ tracePath: join6(process.cwd(), ".specialists", "trace.jsonl") });
@@ -18491,7 +18596,7 @@ async function run6() {
18491
18596
  beadsClient: beadsClient ?? undefined
18492
18597
  });
18493
18598
  process.stderr.write(`
18494
- ${bold4(`Running ${cyan2(args.name)}`)}
18599
+ ${bold5(`Running ${cyan3(args.name)}`)}
18495
18600
 
18496
18601
  `);
18497
18602
  let beadId;
@@ -18499,7 +18604,7 @@ ${bold4(`Running ${cyan2(args.name)}`)}
18499
18604
  name: args.name,
18500
18605
  prompt: args.prompt,
18501
18606
  backendOverride: args.model
18502
- }, (delta) => process.stdout.write(delta), undefined, (meta) => process.stderr.write(dim4(`
18607
+ }, (delta) => process.stdout.write(delta), undefined, (meta) => process.stderr.write(dim5(`
18503
18608
  [${meta.backend} / ${meta.model}]
18504
18609
 
18505
18610
  `)), (killFn) => {
@@ -18513,7 +18618,7 @@ Interrupted.
18513
18618
  });
18514
18619
  }, (id) => {
18515
18620
  beadId = id;
18516
- process.stderr.write(dim4(`
18621
+ process.stderr.write(dim5(`
18517
18622
  [bead: ${id}]
18518
18623
  `));
18519
18624
  });
@@ -18525,14 +18630,14 @@ Interrupted.
18525
18630
  const footer = [
18526
18631
  beadId ? `bead ${beadId}` : "",
18527
18632
  `${secs}s`,
18528
- dim4(result.model)
18633
+ dim5(result.model)
18529
18634
  ].filter(Boolean).join(" ");
18530
18635
  process.stderr.write(`
18531
- ${green3("✓")} ${footer}
18636
+ ${green4("✓")} ${footer}
18532
18637
 
18533
18638
  `);
18534
18639
  }
18535
- var bold4 = (s) => `\x1B[1m${s}\x1B[0m`, dim4 = (s) => `\x1B[2m${s}\x1B[0m`, green3 = (s) => `\x1B[32m${s}\x1B[0m`, cyan2 = (s) => `\x1B[36m${s}\x1B[0m`;
18640
+ var bold5 = (s) => `\x1B[1m${s}\x1B[0m`, dim5 = (s) => `\x1B[2m${s}\x1B[0m`, green4 = (s) => `\x1B[32m${s}\x1B[0m`, cyan3 = (s) => `\x1B[36m${s}\x1B[0m`;
18536
18641
  var init_run = __esm(() => {
18537
18642
  init_loader();
18538
18643
  init_runner();
@@ -18543,30 +18648,30 @@ var init_run = __esm(() => {
18543
18648
  // src/cli/status.ts
18544
18649
  var exports_status = {};
18545
18650
  __export(exports_status, {
18546
- run: () => run7
18651
+ run: () => run8
18547
18652
  });
18548
- import { spawnSync as spawnSync3 } from "node:child_process";
18653
+ import { spawnSync as spawnSync4 } from "node:child_process";
18549
18654
  import { existsSync as existsSync4 } from "node:fs";
18550
18655
  import { join as join7 } from "node:path";
18551
18656
  function ok2(msg) {
18552
- console.log(` ${green4("✓")} ${msg}`);
18657
+ console.log(` ${green5("✓")} ${msg}`);
18553
18658
  }
18554
18659
  function warn(msg) {
18555
- console.log(` ${yellow4("○")} ${msg}`);
18660
+ console.log(` ${yellow5("○")} ${msg}`);
18556
18661
  }
18557
18662
  function fail(msg) {
18558
18663
  console.log(` ${red("✗")} ${msg}`);
18559
18664
  }
18560
18665
  function info(msg) {
18561
- console.log(` ${dim5(msg)}`);
18666
+ console.log(` ${dim6(msg)}`);
18562
18667
  }
18563
18668
  function section(label) {
18564
18669
  const line = "─".repeat(Math.max(0, 38 - label.length));
18565
18670
  console.log(`
18566
- ${bold5(`── ${label} ${line}`)}`);
18671
+ ${bold6(`── ${label} ${line}`)}`);
18567
18672
  }
18568
18673
  function cmd(bin, args) {
18569
- const r = spawnSync3(bin, args, {
18674
+ const r = spawnSync4(bin, args, {
18570
18675
  encoding: "utf8",
18571
18676
  stdio: "pipe",
18572
18677
  timeout: 5000
@@ -18574,69 +18679,69 @@ function cmd(bin, args) {
18574
18679
  return { ok: r.status === 0 && !r.error, stdout: (r.stdout ?? "").trim() };
18575
18680
  }
18576
18681
  function isInstalled(bin) {
18577
- return spawnSync3("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
18682
+ return spawnSync4("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
18578
18683
  }
18579
- async function run7() {
18684
+ async function run8() {
18580
18685
  console.log(`
18581
- ${bold5("specialists status")}
18686
+ ${bold6("specialists status")}
18582
18687
  `);
18583
18688
  section("Specialists");
18584
18689
  const loader = new SpecialistLoader;
18585
18690
  const all = await loader.list();
18586
18691
  if (all.length === 0) {
18587
- warn(`no specialists found — run ${yellow4("specialists init")} to scaffold`);
18692
+ warn(`no specialists found — run ${yellow5("specialists init")} to scaffold`);
18588
18693
  } else {
18589
18694
  const byScope = all.reduce((acc, s) => {
18590
18695
  acc[s.scope] = (acc[s.scope] ?? 0) + 1;
18591
18696
  return acc;
18592
18697
  }, {});
18593
18698
  const scopeSummary = Object.entries(byScope).map(([scope, n]) => `${n} ${scope}`).join(", ");
18594
- ok2(`${all.length} found ${dim5(`(${scopeSummary})`)}`);
18699
+ ok2(`${all.length} found ${dim6(`(${scopeSummary})`)}`);
18595
18700
  for (const s of all) {
18596
18701
  const staleness = await checkStaleness(s);
18597
18702
  if (staleness === "AGED") {
18598
- warn(`${s.name} ${red("AGED")} ${dim5(s.scope)}`);
18703
+ warn(`${s.name} ${red("AGED")} ${dim6(s.scope)}`);
18599
18704
  } else if (staleness === "STALE") {
18600
- warn(`${s.name} ${yellow4("STALE")} ${dim5(s.scope)}`);
18705
+ warn(`${s.name} ${yellow5("STALE")} ${dim6(s.scope)}`);
18601
18706
  }
18602
18707
  }
18603
18708
  }
18604
18709
  section("pi (coding agent runtime)");
18605
18710
  if (!isInstalled("pi")) {
18606
- fail(`pi not installed — run ${yellow4("specialists install")}`);
18711
+ fail(`pi not installed — run ${yellow5("specialists install")}`);
18607
18712
  } else {
18608
18713
  const version2 = cmd("pi", ["--version"]);
18609
18714
  const models = cmd("pi", ["--list-models"]);
18610
18715
  const providers = new Set(models.stdout.split(`
18611
18716
  `).slice(1).map((line) => line.split(/\s+/)[0]).filter(Boolean));
18612
18717
  const vStr = version2.ok ? `v${version2.stdout}` : "unknown version";
18613
- const pStr = providers.size > 0 ? `${providers.size} provider${providers.size > 1 ? "s" : ""} active ${dim5(`(${[...providers].join(", ")})`)} ` : yellow4("no providers configured — run pi config");
18718
+ const pStr = providers.size > 0 ? `${providers.size} provider${providers.size > 1 ? "s" : ""} active ${dim6(`(${[...providers].join(", ")})`)} ` : yellow5("no providers configured — run pi config");
18614
18719
  ok2(`${vStr} — ${pStr}`);
18615
18720
  }
18616
18721
  section("beads (issue tracker)");
18617
18722
  if (!isInstalled("bd")) {
18618
- fail(`bd not installed — run ${yellow4("specialists install")}`);
18723
+ fail(`bd not installed — run ${yellow5("specialists install")}`);
18619
18724
  } else {
18620
18725
  const bdVersion = cmd("bd", ["--version"]);
18621
- ok2(`bd installed${bdVersion.ok ? ` ${dim5(bdVersion.stdout)}` : ""}`);
18726
+ ok2(`bd installed${bdVersion.ok ? ` ${dim6(bdVersion.stdout)}` : ""}`);
18622
18727
  if (existsSync4(join7(process.cwd(), ".beads"))) {
18623
18728
  ok2(".beads/ present in project");
18624
18729
  } else {
18625
- warn(`.beads/ not found — run ${yellow4("bd init")} to enable issue tracking`);
18730
+ warn(`.beads/ not found — run ${yellow5("bd init")} to enable issue tracking`);
18626
18731
  }
18627
18732
  }
18628
18733
  section("MCP");
18629
18734
  const specialistsBin = cmd("which", ["specialists"]);
18630
18735
  if (!specialistsBin.ok) {
18631
- fail(`specialists not installed globally — run ${yellow4("npm install -g @jaggerxtrm/specialists")}`);
18736
+ fail(`specialists not installed globally — run ${yellow5("npm install -g @jaggerxtrm/specialists")}`);
18632
18737
  } else {
18633
- ok2(`specialists binary installed ${dim5(specialistsBin.stdout)}`);
18738
+ ok2(`specialists binary installed ${dim6(specialistsBin.stdout)}`);
18634
18739
  info(`verify registration: claude mcp get specialists`);
18635
18740
  info(`re-register: specialists install`);
18636
18741
  }
18637
18742
  console.log();
18638
18743
  }
18639
- var bold5 = (s) => `\x1B[1m${s}\x1B[0m`, dim5 = (s) => `\x1B[2m${s}\x1B[0m`, green4 = (s) => `\x1B[32m${s}\x1B[0m`, yellow4 = (s) => `\x1B[33m${s}\x1B[0m`, red = (s) => `\x1B[31m${s}\x1B[0m`;
18744
+ var bold6 = (s) => `\x1B[1m${s}\x1B[0m`, dim6 = (s) => `\x1B[2m${s}\x1B[0m`, green5 = (s) => `\x1B[32m${s}\x1B[0m`, yellow5 = (s) => `\x1B[33m${s}\x1B[0m`, red = (s) => `\x1B[31m${s}\x1B[0m`;
18640
18745
  var init_status = __esm(() => {
18641
18746
  init_loader();
18642
18747
  });
@@ -18644,27 +18749,28 @@ var init_status = __esm(() => {
18644
18749
  // src/cli/help.ts
18645
18750
  var exports_help = {};
18646
18751
  __export(exports_help, {
18647
- run: () => run8
18752
+ run: () => run9
18648
18753
  });
18649
- async function run8() {
18754
+ async function run9() {
18650
18755
  const lines = [
18651
18756
  "",
18652
- bold6("specialists <command>"),
18757
+ bold7("specialists <command>"),
18653
18758
  "",
18654
18759
  "Commands:",
18655
- ...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim6(desc)}`),
18760
+ ...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim7(desc)}`),
18656
18761
  "",
18657
- dim6("Run 'specialists <command> --help' for command-specific options."),
18762
+ dim7("Run 'specialists <command> --help' for command-specific options."),
18658
18763
  ""
18659
18764
  ];
18660
18765
  console.log(lines.join(`
18661
18766
  `));
18662
18767
  }
18663
- var bold6 = (s) => `\x1B[1m${s}\x1B[0m`, dim6 = (s) => `\x1B[2m${s}\x1B[0m`, COMMANDS, COL_WIDTH;
18768
+ var bold7 = (s) => `\x1B[1m${s}\x1B[0m`, dim7 = (s) => `\x1B[2m${s}\x1B[0m`, COMMANDS, COL_WIDTH;
18664
18769
  var init_help = __esm(() => {
18665
18770
  COMMANDS = [
18666
18771
  ["install", "Full-stack installer: pi, beads, dolt, MCP registration, hooks"],
18667
18772
  ["list", "List available specialists with model and description"],
18773
+ ["models", "List models available on pi, flagged with thinking/images support"],
18668
18774
  ["version", "Print installed version"],
18669
18775
  ["init", "Initialize specialists in the current project"],
18670
18776
  ["edit", "Edit a specialist field (e.g. --model, --description)"],
@@ -26417,7 +26523,7 @@ class SpecialistsServer {
26417
26523
 
26418
26524
  // src/index.ts
26419
26525
  var sub = process.argv[2];
26420
- async function run9() {
26526
+ async function run10() {
26421
26527
  if (sub === "install") {
26422
26528
  const { run: handler } = await Promise.resolve().then(() => (init_install(), exports_install));
26423
26529
  return handler();
@@ -26430,6 +26536,10 @@ async function run9() {
26430
26536
  const { run: handler } = await Promise.resolve().then(() => (init_list(), exports_list));
26431
26537
  return handler();
26432
26538
  }
26539
+ if (sub === "models") {
26540
+ const { run: handler } = await Promise.resolve().then(() => (init_models(), exports_models));
26541
+ return handler();
26542
+ }
26433
26543
  if (sub === "init") {
26434
26544
  const { run: handler } = await Promise.resolve().then(() => (init_init(), exports_init));
26435
26545
  return handler();
@@ -26459,7 +26569,7 @@ Run 'specialists help' to see available commands.`);
26459
26569
  const server = new SpecialistsServer;
26460
26570
  await server.start();
26461
26571
  }
26462
- run9().catch((error2) => {
26572
+ run10().catch((error2) => {
26463
26573
  logger.error(`Fatal error: ${error2}`);
26464
26574
  process.exit(1);
26465
26575
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "2.1.20",
3
+ "version": "2.1.21",
4
4
  "description": "OmniSpecialist — 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",