@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.
- package/dist/index.js +184 -68
- 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
|
-
|
|
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: () =>
|
|
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(` ${
|
|
18358
|
+
console.log(` ${green2("✓")} ${msg}`);
|
|
18253
18359
|
}
|
|
18254
18360
|
function skip(msg) {
|
|
18255
|
-
console.log(` ${
|
|
18361
|
+
console.log(` ${yellow3("○")} ${msg}`);
|
|
18256
18362
|
}
|
|
18257
|
-
async function
|
|
18363
|
+
async function run5() {
|
|
18258
18364
|
const cwd = process.cwd();
|
|
18259
18365
|
console.log(`
|
|
18260
|
-
${
|
|
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
|
-
${
|
|
18391
|
+
${bold3("Done!")}
|
|
18286
18392
|
`);
|
|
18287
|
-
console.log(` ${
|
|
18288
|
-
console.log(` 1. Add your specialists to ${
|
|
18289
|
-
console.log(` 2. Run ${
|
|
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
|
|
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: () =>
|
|
18414
|
+
run: () => run6
|
|
18309
18415
|
});
|
|
18310
18416
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
18311
|
-
function
|
|
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
|
|
18374
|
-
const args =
|
|
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 ${
|
|
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
|
-
${
|
|
18504
|
+
${bold4(`[dry-run] ${match.filePath}`)}
|
|
18399
18505
|
`);
|
|
18400
|
-
console.log(
|
|
18401
|
-
console.log(
|
|
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(
|
|
18410
|
-
console.log(
|
|
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(`${
|
|
18524
|
+
console.log(`${green3("✓")} ${bold4(name)}: ${yellow4(field)} = ${displayValue}` + dim4(` (${match.filePath})`));
|
|
18419
18525
|
}
|
|
18420
|
-
var
|
|
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: () =>
|
|
18544
|
+
run: () => run7
|
|
18439
18545
|
});
|
|
18440
18546
|
import { join as join6 } from "node:path";
|
|
18441
|
-
async function
|
|
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(
|
|
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
|
|
18481
|
-
const args = await
|
|
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
|
-
${
|
|
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(
|
|
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(
|
|
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
|
-
|
|
18633
|
+
dim5(result.model)
|
|
18528
18634
|
].filter(Boolean).join(" ");
|
|
18529
18635
|
process.stderr.write(`
|
|
18530
|
-
${
|
|
18636
|
+
${green4("✓")} ${footer}
|
|
18531
18637
|
|
|
18532
18638
|
`);
|
|
18533
18639
|
}
|
|
18534
|
-
var
|
|
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: () =>
|
|
18651
|
+
run: () => run8
|
|
18546
18652
|
});
|
|
18547
|
-
import { spawnSync as
|
|
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(` ${
|
|
18657
|
+
console.log(` ${green5("✓")} ${msg}`);
|
|
18552
18658
|
}
|
|
18553
18659
|
function warn(msg) {
|
|
18554
|
-
console.log(` ${
|
|
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(` ${
|
|
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
|
-
${
|
|
18671
|
+
${bold6(`── ${label} ${line}`)}`);
|
|
18566
18672
|
}
|
|
18567
18673
|
function cmd(bin, args) {
|
|
18568
|
-
const r =
|
|
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
|
|
18682
|
+
return spawnSync4("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
|
|
18577
18683
|
}
|
|
18578
|
-
async function
|
|
18684
|
+
async function run8() {
|
|
18579
18685
|
console.log(`
|
|
18580
|
-
${
|
|
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 ${
|
|
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 ${
|
|
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")} ${
|
|
18703
|
+
warn(`${s.name} ${red("AGED")} ${dim6(s.scope)}`);
|
|
18598
18704
|
} else if (staleness === "STALE") {
|
|
18599
|
-
warn(`${s.name} ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ? ` ${
|
|
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 ${
|
|
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 ${
|
|
18736
|
+
fail(`specialists not installed globally — run ${yellow5("npm install -g @jaggerxtrm/specialists")}`);
|
|
18631
18737
|
} else {
|
|
18632
|
-
ok2(`specialists binary installed ${
|
|
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
|
|
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: () =>
|
|
18752
|
+
run: () => run9
|
|
18647
18753
|
});
|
|
18648
|
-
async function
|
|
18754
|
+
async function run9() {
|
|
18649
18755
|
const lines = [
|
|
18650
18756
|
"",
|
|
18651
|
-
|
|
18757
|
+
bold7("specialists <command>"),
|
|
18652
18758
|
"",
|
|
18653
18759
|
"Commands:",
|
|
18654
|
-
...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${
|
|
18760
|
+
...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim7(desc)}`),
|
|
18655
18761
|
"",
|
|
18656
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
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",
|