@jaggerxtrm/specialists 3.6.2 → 3.6.3
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.
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"output_type": "analysis",
|
|
24
24
|
"permission_required": "READ_ONLY",
|
|
25
25
|
"max_retries": 0,
|
|
26
|
-
"interactive":
|
|
26
|
+
"interactive": true
|
|
27
27
|
},
|
|
28
28
|
"prompt": {
|
|
29
29
|
"system": "You are a codebase explorer specialist with access to the GitNexus knowledge graph.\nYour job is to analyze codebases deeply and provide clear, structured answers about\narchitecture, patterns, and code organization.\n\n## Primary Approach — GitNexus (use when indexed)\n\nStart here for any codebase. GitNexus gives you call chains, execution flows,\nand symbol relationships that grep/find cannot provide:\n\n1. Read `gitnexus://repo/{name}/context`\n → Stats, staleness check. If stale, fall back to bash.\n2. `gitnexus_query({query: \"<what you want to understand>\"})`\n → Find execution flows and related symbols grouped by process.\n3. `gitnexus_context({name: \"<symbol>\"})`\n → 360-degree view: callers, callees, processes the symbol participates in.\n4. Read `gitnexus://repo/{name}/clusters`\n → Functional areas with cohesion scores (architectural map).\n5. Read `gitnexus://repo/{name}/process/{name}`\n → Step-by-step execution trace for a specific flow.\n\n## Fallback Approach — Bash/Grep\n\nUse when GitNexus is unavailable or index is stale:\n- `find`, `tree`, `grep -r` for structure discovery\n- Read key files: package.json, tsconfig.json, README.md, src/index.ts\n- Trace imports manually to understand layer dependencies\n\n## Output Format\n\nAlways provide:\n1. **Summary** (2-3 sentences)\n2. **Architecture overview** — layers, modules, key patterns\n3. **Execution flows** (GitNexus) or **Directory map** (fallback)\n4. **Key symbols** — entry points, central hubs, important interfaces\n5. **Answer** — direct response to the specific question\n\nSTRICT CONSTRAINTS:\n- You MUST NOT edit, write, or modify any files.\n- Read-only: bash (read-only commands), grep, find, ls, GitNexus tools only.\n- If you find something worth fixing, REPORT it — do not fix it.\nEFFICIENCY RULE: Stop using tools and write your final answer after at most 12 tool calls.\n",
|
package/dist/index.js
CHANGED
|
@@ -21248,6 +21248,26 @@ class SqliteClient {
|
|
|
21248
21248
|
return events;
|
|
21249
21249
|
}, "readEvents");
|
|
21250
21250
|
}
|
|
21251
|
+
readLatestToolEvent(jobId) {
|
|
21252
|
+
return withRetry(() => {
|
|
21253
|
+
const row = this.db.query(`
|
|
21254
|
+
SELECT seq, event_json FROM specialist_events
|
|
21255
|
+
WHERE job_id = ? AND type = 'tool'
|
|
21256
|
+
ORDER BY seq DESC, id DESC
|
|
21257
|
+
LIMIT 1;
|
|
21258
|
+
`).get(jobId);
|
|
21259
|
+
if (!row?.event_json)
|
|
21260
|
+
return null;
|
|
21261
|
+
try {
|
|
21262
|
+
const parsed = JSON.parse(row.event_json);
|
|
21263
|
+
if (parsed.type !== "tool")
|
|
21264
|
+
return null;
|
|
21265
|
+
return typeof parsed.seq === "number" ? parsed : { ...parsed, seq: row.seq };
|
|
21266
|
+
} catch {
|
|
21267
|
+
return null;
|
|
21268
|
+
}
|
|
21269
|
+
}, "readLatestToolEvent");
|
|
21270
|
+
}
|
|
21251
21271
|
readResult(jobId) {
|
|
21252
21272
|
return withRetry(() => {
|
|
21253
21273
|
const row = this.db.query("SELECT output FROM specialist_results WHERE job_id = ? LIMIT 1").get(jobId);
|
|
@@ -22580,8 +22600,14 @@ class Supervisor {
|
|
|
22580
22600
|
});
|
|
22581
22601
|
if (timelineEvent) {
|
|
22582
22602
|
appendTimelineEvent(timelineEvent);
|
|
22583
|
-
if (eventType === "tool_execution_end"
|
|
22584
|
-
|
|
22603
|
+
if (eventType === "tool_execution_end") {
|
|
22604
|
+
if (toolCallId) {
|
|
22605
|
+
activeToolCalls.delete(toolCallId);
|
|
22606
|
+
} else {
|
|
22607
|
+
latestUncorrelatedToolState = undefined;
|
|
22608
|
+
}
|
|
22609
|
+
const nextActiveTool = activeToolCalls.values().next().value?.tool;
|
|
22610
|
+
setStatus({ current_tool: nextActiveTool });
|
|
22585
22611
|
}
|
|
22586
22612
|
} else if (eventType === "text" && !textLogged) {
|
|
22587
22613
|
textLogged = true;
|
|
@@ -22734,6 +22760,7 @@ class Supervisor {
|
|
|
22734
22760
|
}
|
|
22735
22761
|
}
|
|
22736
22762
|
}
|
|
22763
|
+
setStatus({ current_tool: undefined });
|
|
22737
22764
|
});
|
|
22738
22765
|
latestOutput = result.output;
|
|
22739
22766
|
mkdirSync3(this.jobDir(id), { recursive: true });
|
|
@@ -30582,6 +30609,49 @@ function readStatusesFromFiles(jobsDir) {
|
|
|
30582
30609
|
}
|
|
30583
30610
|
return statuses.sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30584
30611
|
}
|
|
30612
|
+
function readLastToolEventFromFile(jobsDir, jobId) {
|
|
30613
|
+
const eventsPath = join20(jobsDir, jobId, "events.jsonl");
|
|
30614
|
+
if (!existsSync18(eventsPath))
|
|
30615
|
+
return;
|
|
30616
|
+
try {
|
|
30617
|
+
const lines = readFileSync14(eventsPath, "utf-8").split(`
|
|
30618
|
+
`);
|
|
30619
|
+
for (let index = lines.length - 1;index >= 0; index -= 1) {
|
|
30620
|
+
const line = lines[index]?.trim();
|
|
30621
|
+
if (!line)
|
|
30622
|
+
continue;
|
|
30623
|
+
const parsed = parseTimelineEvent(line);
|
|
30624
|
+
if (!parsed || parsed.type !== "tool")
|
|
30625
|
+
continue;
|
|
30626
|
+
return parsed;
|
|
30627
|
+
}
|
|
30628
|
+
} catch {
|
|
30629
|
+
return;
|
|
30630
|
+
}
|
|
30631
|
+
return;
|
|
30632
|
+
}
|
|
30633
|
+
function resolveDerivedCurrentTool(status, jobsDir, sqliteClient) {
|
|
30634
|
+
let lastToolEvent;
|
|
30635
|
+
try {
|
|
30636
|
+
lastToolEvent = sqliteClient?.readLatestToolEvent(status.id) ?? undefined;
|
|
30637
|
+
} catch {
|
|
30638
|
+
lastToolEvent = undefined;
|
|
30639
|
+
}
|
|
30640
|
+
if (!lastToolEvent) {
|
|
30641
|
+
lastToolEvent = readLastToolEventFromFile(jobsDir, status.id);
|
|
30642
|
+
}
|
|
30643
|
+
if (!lastToolEvent)
|
|
30644
|
+
return status.current_tool;
|
|
30645
|
+
if (lastToolEvent.phase === "start")
|
|
30646
|
+
return lastToolEvent.tool;
|
|
30647
|
+
return;
|
|
30648
|
+
}
|
|
30649
|
+
function enrichStatusesWithDerivedCurrentTool(statuses, jobsDir, sqliteClient) {
|
|
30650
|
+
return statuses.map((status) => ({
|
|
30651
|
+
...status,
|
|
30652
|
+
current_tool: resolveDerivedCurrentTool(status, jobsDir, sqliteClient)
|
|
30653
|
+
}));
|
|
30654
|
+
}
|
|
30585
30655
|
function loadStatuses() {
|
|
30586
30656
|
const sqliteClient = createObservabilitySqliteClient();
|
|
30587
30657
|
const jobsDir = resolveJobsDir();
|
|
@@ -30589,10 +30659,7 @@ function loadStatuses() {
|
|
|
30589
30659
|
try {
|
|
30590
30660
|
const sqliteStatuses = sqliteClient?.listStatuses() ?? [];
|
|
30591
30661
|
if (sqliteStatuses.length === 0) {
|
|
30592
|
-
return fileStatuses;
|
|
30593
|
-
}
|
|
30594
|
-
if (fileStatuses.length === 0) {
|
|
30595
|
-
return sqliteStatuses.sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30662
|
+
return enrichStatusesWithDerivedCurrentTool(fileStatuses, jobsDir, sqliteClient).sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30596
30663
|
}
|
|
30597
30664
|
const merged = new Map;
|
|
30598
30665
|
for (const status of fileStatuses)
|
|
@@ -30603,9 +30670,9 @@ function loadStatuses() {
|
|
|
30603
30670
|
merged.set(status.id, status);
|
|
30604
30671
|
}
|
|
30605
30672
|
}
|
|
30606
|
-
return [...merged.values()].sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30673
|
+
return enrichStatusesWithDerivedCurrentTool([...merged.values()], jobsDir, sqliteClient).sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30607
30674
|
} catch {
|
|
30608
|
-
return fileStatuses;
|
|
30675
|
+
return enrichStatusesWithDerivedCurrentTool(fileStatuses, jobsDir, sqliteClient).sort((a, b) => b.started_at_ms - a.started_at_ms);
|
|
30609
30676
|
} finally {
|
|
30610
30677
|
sqliteClient?.close();
|
|
30611
30678
|
}
|
|
@@ -31284,6 +31351,7 @@ var init_ps = __esm(() => {
|
|
|
31284
31351
|
init_supervisor();
|
|
31285
31352
|
init_job_root();
|
|
31286
31353
|
init_observability_sqlite();
|
|
31354
|
+
init_timeline_events();
|
|
31287
31355
|
init_node_resolve();
|
|
31288
31356
|
init_epic_readiness();
|
|
31289
31357
|
ACTIVE_STATES = ["starting", "running", "waiting"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaggerxtrm/specialists",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.3",
|
|
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",
|