@jaggerxtrm/specialists 2.1.12 → 2.1.14

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 CHANGED
@@ -195,13 +195,18 @@ Pre-script output is formatted as `<pre_flight_context>` XML and available in `t
195
195
 
196
196
  ## CLI
197
197
 
198
- Once installed globally, the `specialists` command provides:
198
+ Once installed globally, `specialists <command>` provides:
199
199
 
200
200
  | Command | Description |
201
201
  |---------|-------------|
202
- | `specialists install` | Full-stack installer: pi, beads, dolt, MCP registration, hooks, scaffold |
203
- | `specialists list` | List all discovered specialists with model, description, and scope |
204
- | `specialists version` | Print the installed package version |
202
+ | `specialists install` | Full-stack installer: pi, beads, dolt, MCP registration, hooks |
203
+ | `specialists init` | Scaffold `./specialists/` and inject usage block into `AGENTS.md` |
204
+ | `specialists list` | List discovered specialists with model, description, and scope |
205
+ | `specialists edit <name> --<field> <value>` | Edit a specialist field in-place |
206
+ | `specialists run <name>` | Run a specialist and stream output to stdout |
207
+ | `specialists status` | Show system health: specialists, pi, beads, MCP |
208
+ | `specialists version` | Print installed package version |
209
+ | `specialists help` | Show command reference |
205
210
  | `specialists` | Start the MCP server (called by Claude Code — not for direct use) |
206
211
 
207
212
  ### specialists list
@@ -218,6 +223,59 @@ Specialists (9)
218
223
 
219
224
  Scopes: `[project]` = `./specialists/` (or `.claude/specialists/`), `[user]` = `~/.agents/specialists/`
220
225
 
226
+ Filter by scope or category: `specialists list --scope user --category analysis`
227
+
228
+ ### specialists edit
229
+
230
+ Edit individual fields without opening the file:
231
+
232
+ ```bash
233
+ specialists edit init-session --model anthropic/claude-sonnet-4-6
234
+ specialists edit bug-hunt --permission MEDIUM
235
+ specialists edit overthinker --timeout 300000
236
+ specialists edit codebase-explorer --tags "analysis,architecture"
237
+ specialists edit my-spec --description "New description" --dry-run
238
+ ```
239
+
240
+ Editable fields: `model`, `fallback-model`, `description`, `permission`, `timeout`, `tags`
241
+
242
+ ### specialists run
243
+
244
+ Run a specialist directly from the terminal — no MCP required:
245
+
246
+ ```bash
247
+ # Inline prompt
248
+ specialists run init-session --prompt "What changed recently?"
249
+
250
+ # Pipe from stdin
251
+ echo "Analyse the architecture" | specialists run codebase-explorer
252
+
253
+ # Override model, skip beads
254
+ specialists run overthinker --prompt "Refactor strategy?" --model anthropic/claude-sonnet-4-6 --no-beads
255
+ ```
256
+
257
+ Output streams to stdout in real time. Model, duration, and bead ID appear on stderr.
258
+
259
+ ### specialists status
260
+
261
+ ```
262
+ specialists status
263
+
264
+ ── Specialists ───────────────────────────
265
+ ✓ 9 found (9 project)
266
+
267
+ ── pi (coding agent runtime) ────────────
268
+ ✓ v0.57.1 — 4 providers active (anthropic, google-gemini-cli, qwen, zai)
269
+
270
+ ── beads (issue tracker) ────────────────
271
+ ✓ bd installed v0.59.0
272
+ ✓ .beads/ present in project
273
+
274
+ ── MCP ───────────────────────────────────
275
+ ✓ specialists binary installed /usr/local/bin/specialists
276
+ verify registration: claude mcp get specialists
277
+ ```
278
+
221
279
  ---
222
280
 
223
281
  ## Development
package/bin/install.js CHANGED
@@ -303,14 +303,14 @@ process.exit(0);
303
303
 
304
304
  const BEADS_EDIT_GATE_ENTRY = {
305
305
  matcher: 'Edit|Write|MultiEdit|NotebookEdit|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol',
306
- hooks: [{ type: 'command', command: BEADS_EDIT_GATE_FILE, timeout: 10 }],
306
+ hooks: [{ type: 'command', command: BEADS_EDIT_GATE_FILE, timeout: 10000 }],
307
307
  };
308
308
  const BEADS_COMMIT_GATE_ENTRY = {
309
309
  matcher: 'Bash',
310
- hooks: [{ type: 'command', command: BEADS_COMMIT_GATE_FILE, timeout: 10 }],
310
+ hooks: [{ type: 'command', command: BEADS_COMMIT_GATE_FILE, timeout: 10000 }],
311
311
  };
312
312
  const BEADS_STOP_GATE_ENTRY = {
313
- hooks: [{ type: 'command', command: BEADS_STOP_GATE_FILE, timeout: 10 }],
313
+ hooks: [{ type: 'command', command: BEADS_STOP_GATE_FILE, timeout: 10000 }],
314
314
  };
315
315
 
316
316
  function installHook() {
package/dist/index.js CHANGED
@@ -18149,7 +18149,7 @@ import { execFileSync } from "node:child_process";
18149
18149
  import { fileURLToPath } from "node:url";
18150
18150
  import { dirname as dirname2, join as join4 } from "node:path";
18151
18151
  async function run() {
18152
- const installerPath = join4(dirname2(fileURLToPath(import.meta.url)), "..", "..", "bin", "install.js");
18152
+ const installerPath = join4(dirname2(fileURLToPath(import.meta.url)), "..", "bin", "install.js");
18153
18153
  execFileSync(process.execPath, [installerPath], { stdio: "inherit" });
18154
18154
  }
18155
18155
  var init_install = () => {};
@@ -18539,26 +18539,127 @@ var init_run = __esm(() => {
18539
18539
  init_beads();
18540
18540
  });
18541
18541
 
18542
+ // src/cli/status.ts
18543
+ var exports_status = {};
18544
+ __export(exports_status, {
18545
+ run: () => run7
18546
+ });
18547
+ import { spawnSync as spawnSync3 } from "node:child_process";
18548
+ import { existsSync as existsSync4 } from "node:fs";
18549
+ import { join as join7 } from "node:path";
18550
+ function ok2(msg) {
18551
+ console.log(` ${green4("✓")} ${msg}`);
18552
+ }
18553
+ function warn(msg) {
18554
+ console.log(` ${yellow4("○")} ${msg}`);
18555
+ }
18556
+ function fail(msg) {
18557
+ console.log(` ${red("✗")} ${msg}`);
18558
+ }
18559
+ function info(msg) {
18560
+ console.log(` ${dim5(msg)}`);
18561
+ }
18562
+ function section(label) {
18563
+ const line = "─".repeat(Math.max(0, 38 - label.length));
18564
+ console.log(`
18565
+ ${bold5(`── ${label} ${line}`)}`);
18566
+ }
18567
+ function cmd(bin, args) {
18568
+ const r = spawnSync3(bin, args, {
18569
+ encoding: "utf8",
18570
+ stdio: "pipe",
18571
+ timeout: 5000
18572
+ });
18573
+ return { ok: r.status === 0 && !r.error, stdout: (r.stdout ?? "").trim() };
18574
+ }
18575
+ function isInstalled(bin) {
18576
+ return spawnSync3("which", [bin], { encoding: "utf8", timeout: 2000 }).status === 0;
18577
+ }
18578
+ async function run7() {
18579
+ console.log(`
18580
+ ${bold5("specialists status")}
18581
+ `);
18582
+ section("Specialists");
18583
+ const loader = new SpecialistLoader;
18584
+ const all = await loader.list();
18585
+ if (all.length === 0) {
18586
+ warn(`no specialists found — run ${yellow4("specialists init")} to scaffold`);
18587
+ } else {
18588
+ const byScope = all.reduce((acc, s) => {
18589
+ acc[s.scope] = (acc[s.scope] ?? 0) + 1;
18590
+ return acc;
18591
+ }, {});
18592
+ const scopeSummary = Object.entries(byScope).map(([scope, n]) => `${n} ${scope}`).join(", ");
18593
+ ok2(`${all.length} found ${dim5(`(${scopeSummary})`)}`);
18594
+ for (const s of all) {
18595
+ const staleness = await checkStaleness(s);
18596
+ if (staleness === "AGED") {
18597
+ warn(`${s.name} ${red("AGED")} ${dim5(s.scope)}`);
18598
+ } else if (staleness === "STALE") {
18599
+ warn(`${s.name} ${yellow4("STALE")} ${dim5(s.scope)}`);
18600
+ }
18601
+ }
18602
+ }
18603
+ section("pi (coding agent runtime)");
18604
+ if (!isInstalled("pi")) {
18605
+ fail(`pi not installed — run ${yellow4("specialists install")}`);
18606
+ } else {
18607
+ const version2 = cmd("pi", ["--version"]);
18608
+ const models = cmd("pi", ["--list-models"]);
18609
+ const providers = new Set(models.stdout.split(`
18610
+ `).slice(1).map((line) => line.split(/\s+/)[0]).filter(Boolean));
18611
+ 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");
18613
+ ok2(`${vStr} — ${pStr}`);
18614
+ }
18615
+ section("beads (issue tracker)");
18616
+ if (!isInstalled("bd")) {
18617
+ fail(`bd not installed — run ${yellow4("specialists install")}`);
18618
+ } else {
18619
+ const bdVersion = cmd("bd", ["--version"]);
18620
+ ok2(`bd installed${bdVersion.ok ? ` ${dim5(bdVersion.stdout)}` : ""}`);
18621
+ if (existsSync4(join7(process.cwd(), ".beads"))) {
18622
+ ok2(".beads/ present in project");
18623
+ } else {
18624
+ warn(`.beads/ not found — run ${yellow4("bd init")} to enable issue tracking`);
18625
+ }
18626
+ }
18627
+ section("MCP");
18628
+ const specialistsBin = cmd("which", ["specialists"]);
18629
+ if (!specialistsBin.ok) {
18630
+ fail(`specialists not installed globally — run ${yellow4("npm install -g @jaggerxtrm/specialists")}`);
18631
+ } else {
18632
+ ok2(`specialists binary installed ${dim5(specialistsBin.stdout)}`);
18633
+ info(`verify registration: claude mcp get specialists`);
18634
+ info(`re-register: specialists install`);
18635
+ }
18636
+ console.log();
18637
+ }
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`;
18639
+ var init_status = __esm(() => {
18640
+ init_loader();
18641
+ });
18642
+
18542
18643
  // src/cli/help.ts
18543
18644
  var exports_help = {};
18544
18645
  __export(exports_help, {
18545
- run: () => run7
18646
+ run: () => run8
18546
18647
  });
18547
- async function run7() {
18648
+ async function run8() {
18548
18649
  const lines = [
18549
18650
  "",
18550
- bold5("specialists <command>"),
18651
+ bold6("specialists <command>"),
18551
18652
  "",
18552
18653
  "Commands:",
18553
- ...COMMANDS.map(([cmd, desc]) => ` ${cmd.padEnd(COL_WIDTH)} ${dim5(desc)}`),
18654
+ ...COMMANDS.map(([cmd2, desc]) => ` ${cmd2.padEnd(COL_WIDTH)} ${dim6(desc)}`),
18554
18655
  "",
18555
- dim5("Run 'specialists <command> --help' for command-specific options."),
18656
+ dim6("Run 'specialists <command> --help' for command-specific options."),
18556
18657
  ""
18557
18658
  ];
18558
18659
  console.log(lines.join(`
18559
18660
  `));
18560
18661
  }
18561
- var bold5 = (s) => `\x1B[1m${s}\x1B[0m`, dim5 = (s) => `\x1B[2m${s}\x1B[0m`, COMMANDS, COL_WIDTH;
18662
+ var bold6 = (s) => `\x1B[1m${s}\x1B[0m`, dim6 = (s) => `\x1B[2m${s}\x1B[0m`, COMMANDS, COL_WIDTH;
18562
18663
  var init_help = __esm(() => {
18563
18664
  COMMANDS = [
18564
18665
  ["install", "Full-stack installer: pi, beads, dolt, MCP registration, hooks"],
@@ -18570,7 +18671,7 @@ var init_help = __esm(() => {
18570
18671
  ["status", "Show system health (pi, beads, MCP)"],
18571
18672
  ["help", "Show this help message"]
18572
18673
  ];
18573
- COL_WIDTH = Math.max(...COMMANDS.map(([cmd]) => cmd.length));
18674
+ COL_WIDTH = Math.max(...COMMANDS.map(([cmd2]) => cmd2.length));
18574
18675
  });
18575
18676
 
18576
18677
  // node_modules/zod/v4/core/core.js
@@ -26315,7 +26416,7 @@ class SpecialistsServer {
26315
26416
 
26316
26417
  // src/index.ts
26317
26418
  var sub = process.argv[2];
26318
- async function run8() {
26419
+ async function run9() {
26319
26420
  if (sub === "install") {
26320
26421
  const { run: handler } = await Promise.resolve().then(() => (init_install(), exports_install));
26321
26422
  return handler();
@@ -26340,6 +26441,10 @@ async function run8() {
26340
26441
  const { run: handler } = await Promise.resolve().then(() => (init_run(), exports_run));
26341
26442
  return handler();
26342
26443
  }
26444
+ if (sub === "status") {
26445
+ const { run: handler } = await Promise.resolve().then(() => (init_status(), exports_status));
26446
+ return handler();
26447
+ }
26343
26448
  if (sub === "help" || sub === "--help" || sub === "-h") {
26344
26449
  const { run: handler } = await Promise.resolve().then(() => (init_help(), exports_help));
26345
26450
  return handler();
@@ -26348,7 +26453,7 @@ async function run8() {
26348
26453
  const server = new SpecialistsServer;
26349
26454
  await server.start();
26350
26455
  }
26351
- run8().catch((error2) => {
26456
+ run9().catch((error2) => {
26352
26457
  logger.error(`Fatal error: ${error2}`);
26353
26458
  process.exit(1);
26354
26459
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "2.1.12",
3
+ "version": "2.1.14",
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",