@jaggerxtrm/specialists 2.1.19 → 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 +184 -68
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18218,17 +18218,18 @@ async function run3() {
18218
18218
  return;
18219
18219
  }
18220
18220
  const nameWidth = Math.max(...specialists.map((s) => s.name.length), 4);
18221
- const modelWidth = Math.max(...specialists.map((s) => s.model.length), 5);
18222
18221
  console.log(`
18223
18222
  ${bold(`Specialists (${specialists.length})`)}
18224
18223
  `);
18225
18224
  for (const s of specialists) {
18226
18225
  const name = cyan(s.name.padEnd(nameWidth));
18227
- const model = dim(s.model.padEnd(modelWidth));
18228
18226
  const scopeTag = yellow(`[${s.scope}]`);
18229
- console.log(` ${name} ${model} ${s.description} ${scopeTag}`);
18227
+ const model = dim(s.model);
18228
+ const desc = s.description.length > 80 ? s.description.slice(0, 79) + "…" : s.description;
18229
+ console.log(` ${name} ${scopeTag} ${model}`);
18230
+ console.log(` ${" ".repeat(nameWidth)} ${dim(desc)}`);
18231
+ console.log();
18230
18232
  }
18231
- console.log();
18232
18233
  }
18233
18234
  var dim = (s) => `\x1B[2m${s}\x1B[0m`, bold = (s) => `\x1B[1m${s}\x1B[0m`, cyan = (s) => `\x1B[36m${s}\x1B[0m`, yellow = (s) => `\x1B[33m${s}\x1B[0m`, ArgParseError;
18234
18235
  var init_list = __esm(() => {
@@ -18241,23 +18242,128 @@ var init_list = __esm(() => {
18241
18242
  };
18242
18243
  });
18243
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
+
18244
18350
  // src/cli/init.ts
18245
18351
  var exports_init = {};
18246
18352
  __export(exports_init, {
18247
- run: () => run4
18353
+ run: () => run5
18248
18354
  });
18249
18355
  import { existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync } from "node:fs";
18250
18356
  import { join as join5 } from "node:path";
18251
18357
  function ok(msg) {
18252
- console.log(` ${green("✓")} ${msg}`);
18358
+ console.log(` ${green2("✓")} ${msg}`);
18253
18359
  }
18254
18360
  function skip(msg) {
18255
- console.log(` ${yellow2("○")} ${msg}`);
18361
+ console.log(` ${yellow3("○")} ${msg}`);
18256
18362
  }
18257
- async function run4() {
18363
+ async function run5() {
18258
18364
  const cwd = process.cwd();
18259
18365
  console.log(`
18260
- ${bold2("specialists init")}
18366
+ ${bold3("specialists init")}
18261
18367
  `);
18262
18368
  const specialistsDir = join5(cwd, "specialists");
18263
18369
  if (existsSync3(specialistsDir)) {
@@ -18282,15 +18388,15 @@ ${bold2("specialists init")}
18282
18388
  ok("created AGENTS.md with Specialists section");
18283
18389
  }
18284
18390
  console.log(`
18285
- ${bold2("Done!")}
18391
+ ${bold3("Done!")}
18286
18392
  `);
18287
- console.log(` ${dim2("Next steps:")}`);
18288
- console.log(` 1. Add your specialists to ${yellow2("specialists/")}`);
18289
- 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`);
18290
18396
  console.log(` 3. Restart Claude Code to pick up AGENTS.md changes
18291
18397
  `);
18292
18398
  }
18293
- 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";
18294
18400
  var init_init = __esm(() => {
18295
18401
  AGENTS_BLOCK = `
18296
18402
  ## Specialists
@@ -18305,10 +18411,10 @@ specialist without user intervention.
18305
18411
  // src/cli/edit.ts
18306
18412
  var exports_edit = {};
18307
18413
  __export(exports_edit, {
18308
- run: () => run5
18414
+ run: () => run6
18309
18415
  });
18310
18416
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
18311
- function parseArgs2(argv) {
18417
+ function parseArgs3(argv) {
18312
18418
  const name = argv[0];
18313
18419
  if (!name || name.startsWith("--")) {
18314
18420
  console.error("Usage: specialists edit <name> --<field> <value> [--dry-run]");
@@ -18370,8 +18476,8 @@ function setIn(doc2, path, value) {
18370
18476
  node.set(leaf, value);
18371
18477
  }
18372
18478
  }
18373
- async function run5() {
18374
- const args = parseArgs2(process.argv.slice(3));
18479
+ async function run6() {
18480
+ const args = parseArgs3(process.argv.slice(3));
18375
18481
  const { name, field, value, dryRun, scope } = args;
18376
18482
  const loader = new SpecialistLoader;
18377
18483
  const all = await loader.list();
@@ -18379,7 +18485,7 @@ async function run5() {
18379
18485
  if (!match) {
18380
18486
  const hint = scope ? ` (scope: ${scope})` : "";
18381
18487
  console.error(`Error: specialist "${name}" not found${hint}`);
18382
- console.error(` Run ${yellow3("specialists list")} to see available specialists`);
18488
+ console.error(` Run ${yellow4("specialists list")} to see available specialists`);
18383
18489
  process.exit(1);
18384
18490
  }
18385
18491
  const raw = readFileSync2(match.filePath, "utf-8");
@@ -18395,10 +18501,10 @@ async function run5() {
18395
18501
  const updated = doc2.toString();
18396
18502
  if (dryRun) {
18397
18503
  console.log(`
18398
- ${bold3(`[dry-run] ${match.filePath}`)}
18504
+ ${bold4(`[dry-run] ${match.filePath}`)}
18399
18505
  `);
18400
- console.log(dim3("--- current"));
18401
- console.log(dim3(`+++ updated`));
18506
+ console.log(dim4("--- current"));
18507
+ console.log(dim4(`+++ updated`));
18402
18508
  const oldLines = raw.split(`
18403
18509
  `);
18404
18510
  const newLines = updated.split(`
@@ -18406,8 +18512,8 @@ ${bold3(`[dry-run] ${match.filePath}`)}
18406
18512
  newLines.forEach((line, i) => {
18407
18513
  if (line !== oldLines[i]) {
18408
18514
  if (oldLines[i] !== undefined)
18409
- console.log(dim3(`- ${oldLines[i]}`));
18410
- console.log(green2(`+ ${line}`));
18515
+ console.log(dim4(`- ${oldLines[i]}`));
18516
+ console.log(green3(`+ ${line}`));
18411
18517
  }
18412
18518
  });
18413
18519
  console.log();
@@ -18415,9 +18521,9 @@ ${bold3(`[dry-run] ${match.filePath}`)}
18415
18521
  }
18416
18522
  writeFileSync2(match.filePath, updated, "utf-8");
18417
18523
  const displayValue = field === "tags" ? `[${typedValue.join(", ")}]` : String(typedValue);
18418
- console.log(`${green2("✓")} ${bold3(name)}: ${yellow3(field)} = ${displayValue}` + dim3(` (${match.filePath})`));
18524
+ console.log(`${green3("✓")} ${bold4(name)}: ${yellow4(field)} = ${displayValue}` + dim4(` (${match.filePath})`));
18419
18525
  }
18420
- 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;
18421
18527
  var init_edit = __esm(() => {
18422
18528
  init_dist();
18423
18529
  init_loader();
@@ -18435,10 +18541,10 @@ var init_edit = __esm(() => {
18435
18541
  // src/cli/run.ts
18436
18542
  var exports_run = {};
18437
18543
  __export(exports_run, {
18438
- run: () => run6
18544
+ run: () => run7
18439
18545
  });
18440
18546
  import { join as join6 } from "node:path";
18441
- async function parseArgs3(argv) {
18547
+ async function parseArgs4(argv) {
18442
18548
  const name = argv[0];
18443
18549
  if (!name || name.startsWith("--")) {
18444
18550
  console.error('Usage: specialists run <name> [--prompt "..."] [--model <model>] [--no-beads]');
@@ -18464,7 +18570,7 @@ async function parseArgs3(argv) {
18464
18570
  }
18465
18571
  if (!prompt) {
18466
18572
  if (process.stdin.isTTY) {
18467
- process.stderr.write(dim4("Prompt (Ctrl+D when done): "));
18573
+ process.stderr.write(dim5("Prompt (Ctrl+D when done): "));
18468
18574
  }
18469
18575
  prompt = await new Promise((resolve) => {
18470
18576
  let buf = "";
@@ -18477,8 +18583,8 @@ async function parseArgs3(argv) {
18477
18583
  }
18478
18584
  return { name, prompt, model, noBeads };
18479
18585
  }
18480
- async function run6() {
18481
- const args = await parseArgs3(process.argv.slice(3));
18586
+ async function run7() {
18587
+ const args = await parseArgs4(process.argv.slice(3));
18482
18588
  const loader = new SpecialistLoader;
18483
18589
  const circuitBreaker = new CircuitBreaker;
18484
18590
  const hooks = new HookEmitter({ tracePath: join6(process.cwd(), ".specialists", "trace.jsonl") });
@@ -18490,7 +18596,7 @@ async function run6() {
18490
18596
  beadsClient: beadsClient ?? undefined
18491
18597
  });
18492
18598
  process.stderr.write(`
18493
- ${bold4(`Running ${cyan2(args.name)}`)}
18599
+ ${bold5(`Running ${cyan3(args.name)}`)}
18494
18600
 
18495
18601
  `);
18496
18602
  let beadId;
@@ -18498,7 +18604,7 @@ ${bold4(`Running ${cyan2(args.name)}`)}
18498
18604
  name: args.name,
18499
18605
  prompt: args.prompt,
18500
18606
  backendOverride: args.model
18501
- }, (delta) => process.stdout.write(delta), undefined, (meta) => process.stderr.write(dim4(`
18607
+ }, (delta) => process.stdout.write(delta), undefined, (meta) => process.stderr.write(dim5(`
18502
18608
  [${meta.backend} / ${meta.model}]
18503
18609
 
18504
18610
  `)), (killFn) => {
@@ -18512,7 +18618,7 @@ Interrupted.
18512
18618
  });
18513
18619
  }, (id) => {
18514
18620
  beadId = id;
18515
- process.stderr.write(dim4(`
18621
+ process.stderr.write(dim5(`
18516
18622
  [bead: ${id}]
18517
18623
  `));
18518
18624
  });
@@ -18524,14 +18630,14 @@ Interrupted.
18524
18630
  const footer = [
18525
18631
  beadId ? `bead ${beadId}` : "",
18526
18632
  `${secs}s`,
18527
- dim4(result.model)
18633
+ dim5(result.model)
18528
18634
  ].filter(Boolean).join(" ");
18529
18635
  process.stderr.write(`
18530
- ${green3("✓")} ${footer}
18636
+ ${green4("✓")} ${footer}
18531
18637
 
18532
18638
  `);
18533
18639
  }
18534
- 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`;
18535
18641
  var init_run = __esm(() => {
18536
18642
  init_loader();
18537
18643
  init_runner();
@@ -18542,30 +18648,30 @@ var init_run = __esm(() => {
18542
18648
  // src/cli/status.ts
18543
18649
  var exports_status = {};
18544
18650
  __export(exports_status, {
18545
- run: () => run7
18651
+ run: () => run8
18546
18652
  });
18547
- import { spawnSync as spawnSync3 } from "node:child_process";
18653
+ import { spawnSync as spawnSync4 } from "node:child_process";
18548
18654
  import { existsSync as existsSync4 } from "node:fs";
18549
18655
  import { join as join7 } from "node:path";
18550
18656
  function ok2(msg) {
18551
- console.log(` ${green4("✓")} ${msg}`);
18657
+ console.log(` ${green5("✓")} ${msg}`);
18552
18658
  }
18553
18659
  function warn(msg) {
18554
- console.log(` ${yellow4("○")} ${msg}`);
18660
+ console.log(` ${yellow5("○")} ${msg}`);
18555
18661
  }
18556
18662
  function fail(msg) {
18557
18663
  console.log(` ${red("✗")} ${msg}`);
18558
18664
  }
18559
18665
  function info(msg) {
18560
- console.log(` ${dim5(msg)}`);
18666
+ console.log(` ${dim6(msg)}`);
18561
18667
  }
18562
18668
  function section(label) {
18563
18669
  const line = "─".repeat(Math.max(0, 38 - label.length));
18564
18670
  console.log(`
18565
- ${bold5(`── ${label} ${line}`)}`);
18671
+ ${bold6(`── ${label} ${line}`)}`);
18566
18672
  }
18567
18673
  function cmd(bin, args) {
18568
- const r = spawnSync3(bin, args, {
18674
+ const r = spawnSync4(bin, args, {
18569
18675
  encoding: "utf8",
18570
18676
  stdio: "pipe",
18571
18677
  timeout: 5000
@@ -18573,69 +18679,69 @@ function cmd(bin, args) {
18573
18679
  return { ok: r.status === 0 && !r.error, stdout: (r.stdout ?? "").trim() };
18574
18680
  }
18575
18681
  function isInstalled(bin) {
18576
- return spawnSync3("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
18682
+ return spawnSync4("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
18577
18683
  }
18578
- async function run7() {
18684
+ async function run8() {
18579
18685
  console.log(`
18580
- ${bold5("specialists status")}
18686
+ ${bold6("specialists status")}
18581
18687
  `);
18582
18688
  section("Specialists");
18583
18689
  const loader = new SpecialistLoader;
18584
18690
  const all = await loader.list();
18585
18691
  if (all.length === 0) {
18586
- warn(`no specialists found — run ${yellow4("specialists init")} to scaffold`);
18692
+ warn(`no specialists found — run ${yellow5("specialists init")} to scaffold`);
18587
18693
  } else {
18588
18694
  const byScope = all.reduce((acc, s) => {
18589
18695
  acc[s.scope] = (acc[s.scope] ?? 0) + 1;
18590
18696
  return acc;
18591
18697
  }, {});
18592
18698
  const scopeSummary = Object.entries(byScope).map(([scope, n]) => `${n} ${scope}`).join(", ");
18593
- ok2(`${all.length} found ${dim5(`(${scopeSummary})`)}`);
18699
+ ok2(`${all.length} found ${dim6(`(${scopeSummary})`)}`);
18594
18700
  for (const s of all) {
18595
18701
  const staleness = await checkStaleness(s);
18596
18702
  if (staleness === "AGED") {
18597
- warn(`${s.name} ${red("AGED")} ${dim5(s.scope)}`);
18703
+ warn(`${s.name} ${red("AGED")} ${dim6(s.scope)}`);
18598
18704
  } else if (staleness === "STALE") {
18599
- warn(`${s.name} ${yellow4("STALE")} ${dim5(s.scope)}`);
18705
+ warn(`${s.name} ${yellow5("STALE")} ${dim6(s.scope)}`);
18600
18706
  }
18601
18707
  }
18602
18708
  }
18603
18709
  section("pi (coding agent runtime)");
18604
18710
  if (!isInstalled("pi")) {
18605
- fail(`pi not installed — run ${yellow4("specialists install")}`);
18711
+ fail(`pi not installed — run ${yellow5("specialists install")}`);
18606
18712
  } else {
18607
18713
  const version2 = cmd("pi", ["--version"]);
18608
18714
  const models = cmd("pi", ["--list-models"]);
18609
18715
  const providers = new Set(models.stdout.split(`
18610
18716
  `).slice(1).map((line) => line.split(/\s+/)[0]).filter(Boolean));
18611
18717
  const vStr = version2.ok ? `v${version2.stdout}` : "unknown version";
18612
- 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");
18613
18719
  ok2(`${vStr} — ${pStr}`);
18614
18720
  }
18615
18721
  section("beads (issue tracker)");
18616
18722
  if (!isInstalled("bd")) {
18617
- fail(`bd not installed — run ${yellow4("specialists install")}`);
18723
+ fail(`bd not installed — run ${yellow5("specialists install")}`);
18618
18724
  } else {
18619
18725
  const bdVersion = cmd("bd", ["--version"]);
18620
- ok2(`bd installed${bdVersion.ok ? ` ${dim5(bdVersion.stdout)}` : ""}`);
18726
+ ok2(`bd installed${bdVersion.ok ? ` ${dim6(bdVersion.stdout)}` : ""}`);
18621
18727
  if (existsSync4(join7(process.cwd(), ".beads"))) {
18622
18728
  ok2(".beads/ present in project");
18623
18729
  } else {
18624
- 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`);
18625
18731
  }
18626
18732
  }
18627
18733
  section("MCP");
18628
18734
  const specialistsBin = cmd("which", ["specialists"]);
18629
18735
  if (!specialistsBin.ok) {
18630
- 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")}`);
18631
18737
  } else {
18632
- ok2(`specialists binary installed ${dim5(specialistsBin.stdout)}`);
18738
+ ok2(`specialists binary installed ${dim6(specialistsBin.stdout)}`);
18633
18739
  info(`verify registration: claude mcp get specialists`);
18634
18740
  info(`re-register: specialists install`);
18635
18741
  }
18636
18742
  console.log();
18637
18743
  }
18638
- 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`;
18639
18745
  var init_status = __esm(() => {
18640
18746
  init_loader();
18641
18747
  });
@@ -18643,27 +18749,28 @@ var init_status = __esm(() => {
18643
18749
  // src/cli/help.ts
18644
18750
  var exports_help = {};
18645
18751
  __export(exports_help, {
18646
- run: () => run8
18752
+ run: () => run9
18647
18753
  });
18648
- async function run8() {
18754
+ async function run9() {
18649
18755
  const lines = [
18650
18756
  "",
18651
- bold6("specialists <command>"),
18757
+ bold7("specialists <command>"),
18652
18758
  "",
18653
18759
  "Commands:",
18654
- ...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim6(desc)}`),
18760
+ ...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim7(desc)}`),
18655
18761
  "",
18656
- dim6("Run 'specialists <command> --help' for command-specific options."),
18762
+ dim7("Run 'specialists <command> --help' for command-specific options."),
18657
18763
  ""
18658
18764
  ];
18659
18765
  console.log(lines.join(`
18660
18766
  `));
18661
18767
  }
18662
- 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;
18663
18769
  var init_help = __esm(() => {
18664
18770
  COMMANDS = [
18665
18771
  ["install", "Full-stack installer: pi, beads, dolt, MCP registration, hooks"],
18666
18772
  ["list", "List available specialists with model and description"],
18773
+ ["models", "List models available on pi, flagged with thinking/images support"],
18667
18774
  ["version", "Print installed version"],
18668
18775
  ["init", "Initialize specialists in the current project"],
18669
18776
  ["edit", "Edit a specialist field (e.g. --model, --description)"],
@@ -26416,12 +26523,12 @@ class SpecialistsServer {
26416
26523
 
26417
26524
  // src/index.ts
26418
26525
  var sub = process.argv[2];
26419
- async function run9() {
26526
+ async function run10() {
26420
26527
  if (sub === "install") {
26421
26528
  const { run: handler } = await Promise.resolve().then(() => (init_install(), exports_install));
26422
26529
  return handler();
26423
26530
  }
26424
- if (sub === "version") {
26531
+ if (sub === "version" || sub === "--version" || sub === "-v") {
26425
26532
  const { run: handler } = await Promise.resolve().then(() => (init_version(), exports_version));
26426
26533
  return handler();
26427
26534
  }
@@ -26429,6 +26536,10 @@ async function run9() {
26429
26536
  const { run: handler } = await Promise.resolve().then(() => (init_list(), exports_list));
26430
26537
  return handler();
26431
26538
  }
26539
+ if (sub === "models") {
26540
+ const { run: handler } = await Promise.resolve().then(() => (init_models(), exports_models));
26541
+ return handler();
26542
+ }
26432
26543
  if (sub === "init") {
26433
26544
  const { run: handler } = await Promise.resolve().then(() => (init_init(), exports_init));
26434
26545
  return handler();
@@ -26449,11 +26560,16 @@ async function run9() {
26449
26560
  const { run: handler } = await Promise.resolve().then(() => (init_help(), exports_help));
26450
26561
  return handler();
26451
26562
  }
26563
+ if (sub) {
26564
+ console.error(`Unknown command: '${sub}'
26565
+ Run 'specialists help' to see available commands.`);
26566
+ process.exit(1);
26567
+ }
26452
26568
  logger.info("Starting Specialists MCP Server...");
26453
26569
  const server = new SpecialistsServer;
26454
26570
  await server.start();
26455
26571
  }
26456
- run9().catch((error2) => {
26572
+ run10().catch((error2) => {
26457
26573
  logger.error(`Fatal error: ${error2}`);
26458
26574
  process.exit(1);
26459
26575
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "2.1.19",
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",