@jaggerxtrm/specialists 2.1.0 → 2.1.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/dist/index.js +61 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25080,6 +25080,57 @@ class PiAgentSession {
|
|
|
25080
25080
|
}
|
|
25081
25081
|
|
|
25082
25082
|
// src/specialist/beads.ts
|
|
25083
|
+
import { spawnSync } from "node:child_process";
|
|
25084
|
+
|
|
25085
|
+
class BeadsClient {
|
|
25086
|
+
available;
|
|
25087
|
+
constructor() {
|
|
25088
|
+
this.available = BeadsClient.checkAvailable();
|
|
25089
|
+
if (!this.available) {
|
|
25090
|
+
console.warn("[specialists] bd CLI not found — beads tracking disabled");
|
|
25091
|
+
}
|
|
25092
|
+
}
|
|
25093
|
+
static checkAvailable() {
|
|
25094
|
+
const result = spawnSync("bd", ["--version"], { stdio: "ignore" });
|
|
25095
|
+
return result.status === 0;
|
|
25096
|
+
}
|
|
25097
|
+
isAvailable() {
|
|
25098
|
+
return this.available;
|
|
25099
|
+
}
|
|
25100
|
+
createBead(specialistName) {
|
|
25101
|
+
if (!this.available)
|
|
25102
|
+
return null;
|
|
25103
|
+
const result = spawnSync("bd", ["q", `specialist:${specialistName}`, "--type", "task", "--labels", "specialist"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
|
|
25104
|
+
if (result.status !== 0)
|
|
25105
|
+
return null;
|
|
25106
|
+
const id = result.stdout?.trim();
|
|
25107
|
+
return id || null;
|
|
25108
|
+
}
|
|
25109
|
+
closeBead(id, status, durationMs, model) {
|
|
25110
|
+
if (!this.available || !id)
|
|
25111
|
+
return;
|
|
25112
|
+
const reason = `${status}, ${Math.round(durationMs)}ms, ${model}`;
|
|
25113
|
+
spawnSync("bd", ["close", id, "-r", reason], { stdio: "ignore" });
|
|
25114
|
+
}
|
|
25115
|
+
auditBead(id, toolName, model, exitCode) {
|
|
25116
|
+
if (!this.available || !id)
|
|
25117
|
+
return;
|
|
25118
|
+
spawnSync("bd", [
|
|
25119
|
+
"audit",
|
|
25120
|
+
"record",
|
|
25121
|
+
"--kind",
|
|
25122
|
+
"tool_call",
|
|
25123
|
+
"--tool-name",
|
|
25124
|
+
toolName,
|
|
25125
|
+
"--model",
|
|
25126
|
+
model,
|
|
25127
|
+
"--issue-id",
|
|
25128
|
+
id,
|
|
25129
|
+
"--exit-code",
|
|
25130
|
+
String(exitCode)
|
|
25131
|
+
], { stdio: "ignore" });
|
|
25132
|
+
}
|
|
25133
|
+
}
|
|
25083
25134
|
function shouldCreateBead(beadsIntegration, permissionRequired) {
|
|
25084
25135
|
if (beadsIntegration === "never")
|
|
25085
25136
|
return false;
|
|
@@ -25096,7 +25147,7 @@ class SpecialistRunner {
|
|
|
25096
25147
|
this.deps = deps;
|
|
25097
25148
|
this.sessionFactory = deps.sessionFactory ?? PiAgentSession.create.bind(PiAgentSession);
|
|
25098
25149
|
}
|
|
25099
|
-
async run(options, onProgress, onEvent, onMeta, onKillRegistered) {
|
|
25150
|
+
async run(options, onProgress, onEvent, onMeta, onKillRegistered, onBeadCreated) {
|
|
25100
25151
|
const { loader, hooks, circuitBreaker, beadsClient } = this.deps;
|
|
25101
25152
|
const invocationId = crypto.randomUUID();
|
|
25102
25153
|
const start = Date.now();
|
|
@@ -25156,6 +25207,8 @@ You have access via Bash:
|
|
|
25156
25207
|
let beadId;
|
|
25157
25208
|
if (beadsClient && shouldCreateBead(beadsIntegration, execution.permission_required)) {
|
|
25158
25209
|
beadId = beadsClient.createBead(metadata.name) ?? undefined;
|
|
25210
|
+
if (beadId)
|
|
25211
|
+
onBeadCreated?.(beadId);
|
|
25159
25212
|
}
|
|
25160
25213
|
let output;
|
|
25161
25214
|
let session;
|
|
@@ -25240,7 +25293,7 @@ You have access via Bash:
|
|
|
25240
25293
|
model: "?",
|
|
25241
25294
|
specialistVersion
|
|
25242
25295
|
});
|
|
25243
|
-
this.run(options, (text) => registry2.appendOutput(jobId, text), (eventType) => registry2.setCurrentEvent(jobId, eventType), (meta) => registry2.setMeta(jobId, meta), (killFn) => registry2.setKillFn(jobId, killFn)).then((result) => registry2.complete(jobId, result)).catch((err) => registry2.fail(jobId, err));
|
|
25296
|
+
this.run(options, (text) => registry2.appendOutput(jobId, text), (eventType) => registry2.setCurrentEvent(jobId, eventType), (meta) => registry2.setMeta(jobId, meta), (killFn) => registry2.setKillFn(jobId, killFn), (beadId) => registry2.setBeadId(jobId, beadId)).then((result) => registry2.complete(jobId, result)).catch((err) => registry2.fail(jobId, err));
|
|
25244
25297
|
return jobId;
|
|
25245
25298
|
}
|
|
25246
25299
|
}
|
|
@@ -25638,15 +25691,15 @@ function createStopSpecialistTool(registry2) {
|
|
|
25638
25691
|
}
|
|
25639
25692
|
|
|
25640
25693
|
// src/tools/specialist/specialist_init.tool.ts
|
|
25641
|
-
import { spawnSync } from "node:child_process";
|
|
25694
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
25642
25695
|
import { existsSync as existsSync2 } from "node:fs";
|
|
25643
25696
|
import { join as join2 } from "node:path";
|
|
25644
|
-
var specialistInitSchema =
|
|
25697
|
+
var specialistInitSchema = objectType({});
|
|
25645
25698
|
function createSpecialistInitTool(loader, deps) {
|
|
25646
25699
|
const resolved = deps ?? {
|
|
25647
|
-
bdAvailable: () =>
|
|
25700
|
+
bdAvailable: () => spawnSync2("bd", ["--version"], { stdio: "ignore" }).status === 0,
|
|
25648
25701
|
beadsExists: () => existsSync2(join2(process.cwd(), ".beads")),
|
|
25649
|
-
bdInit: () =>
|
|
25702
|
+
bdInit: () => spawnSync2("bd", ["init"], { stdio: "ignore" })
|
|
25650
25703
|
};
|
|
25651
25704
|
return {
|
|
25652
25705
|
name: "specialist_init",
|
|
@@ -25682,7 +25735,8 @@ class SpecialistsServer {
|
|
|
25682
25735
|
const hooks = new HookEmitter({
|
|
25683
25736
|
tracePath: join3(process.cwd(), ".specialists", "trace.jsonl")
|
|
25684
25737
|
});
|
|
25685
|
-
const
|
|
25738
|
+
const beadsClient = new BeadsClient;
|
|
25739
|
+
const runner = new SpecialistRunner({ loader, hooks, circuitBreaker, beadsClient });
|
|
25686
25740
|
const registry2 = new JobRegistry;
|
|
25687
25741
|
this.tools = [
|
|
25688
25742
|
createListSpecialistsTool(loader),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaggerxtrm/specialists",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
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",
|