@bli-cockpit/mcp 0.1.47 → 0.1.48

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/ops-tools.js +26 -1
  2. package/package.json +1 -1
package/dist/ops-tools.js CHANGED
@@ -57,6 +57,8 @@ export function registerOpsTools(server, deps) {
57
57
  job: z.string().min(1).max(100).optional().describe("One pipeline id instead of the whole board."),
58
58
  skips: z.boolean().optional().describe("Also return the open ingest-skip ledgers."),
59
59
  memory: z.boolean().optional().describe("Also return memory adoption and observed prompt-hook outcomes, delay bounds and cache reuse. No memory text."),
60
+ turns: z.boolean().optional().describe("Also return 30-day JARVIS turn aggregates: latency, hops, tools, tokens and error classes."),
61
+ tool_router: z.boolean().optional().describe("Also return the seven-day shadow tool-router agreement board."),
60
62
  },
61
63
  }, async (args) => withSession(deps, async (session) => {
62
64
  const params = new URLSearchParams();
@@ -64,6 +66,8 @@ export function registerOpsTools(server, deps) {
64
66
  params.set("job", String(args.job));
65
67
  if (args.skips)
66
68
  params.set("skips", "1");
69
+ if (args.turns)
70
+ params.set("turns", "1");
67
71
  const response = await callAgentDoor(session, deps.fetchImpl, "GET", `/api/ops/status${queryString(params)}`);
68
72
  if (!response.ok)
69
73
  return errorResult(doorFailureText("ops_status", response));
@@ -100,6 +104,11 @@ export function registerOpsTools(server, deps) {
100
104
  ? await callAgentDoor(session, deps.fetchImpl, "GET", "/api/ops/memory-usage") : null;
101
105
  if (memory && !memory.ok)
102
106
  return errorResult(doorFailureText("ops_status memory", memory));
107
+ const toolRouter = args.tool_router
108
+ ? await callAgentDoor(session, deps.fetchImpl, "GET", "/api/ops/tool-router")
109
+ : null;
110
+ if (toolRouter && !toolRouter.ok)
111
+ return errorResult(doorFailureText("ops_status tool router", toolRouter));
103
112
  const experience = memory?.ok ? asRecord(memory.body.experience) : null;
104
113
  const experienceLines = experience ? ["EXPERIENCE", experience.summary, ...(Array.isArray(experience.lines) ? experience.lines : [])].join("\n") : "";
105
114
  const hooks = memory?.ok ? asRecord(memory.body.hooks) : null;
@@ -108,6 +117,18 @@ export function registerOpsTools(server, deps) {
108
117
  const row = asRecord(device);
109
118
  return [row.line, row.performanceLine].filter((line) => typeof line === "string").join("\n");
110
119
  }).join("\n") : "";
120
+ const turns = asRecord(body.turns);
121
+ const turnLine = args.turns
122
+ ? typeof turns.turns === "number"
123
+ ? `TURNS ${turns.turns} turns / ${typeof turns.windowDays === "number" ? turns.windowDays : 30}d`
124
+ : "TURNS not read (turns_section_absent)"
125
+ : "";
126
+ const toolRouterBoard = toolRouter?.ok ? asRecord(toolRouter.body.board) : null;
127
+ const toolRouterLine = args.tool_router
128
+ ? toolRouterBoard && typeof toolRouterBoard.turnsRouted === "number"
129
+ ? `TOOL ROUTER ${toolRouterBoard.turnsRouted} routed`
130
+ : "TOOL ROUTER not read (tool_router_section_absent)"
131
+ : "";
111
132
  // Both branches say something. A board that is entirely green and
112
133
  // reports nothing cannot answer "did anybody look today?".
113
134
  return textResult(`${rows.length} pipeline(s), ${unhealthy.length} unhealthy`
@@ -115,7 +136,9 @@ export function registerOpsTools(server, deps) {
115
136
  + `${lines ? `\n${lines}` : ""}`
116
137
  + `${ladderLine ? `\n${ladderLine}` : ""}`
117
138
  + `${memoryLines ? `\n${memoryLines}` : ""}`
118
- + `${experienceLines ? `\n${experienceLines}` : ""}`,
139
+ + `${experienceLines ? `\n${experienceLines}` : ""}`
140
+ + `${turnLine ? `\n${turnLine}` : ""}`
141
+ + `${toolRouterLine ? `\n${toolRouterLine}` : ""}`,
119
142
  // The API owns the wording and the timing boundary on every surface.
120
143
  {
121
144
  pipelines: rows,
@@ -125,6 +148,8 @@ export function registerOpsTools(server, deps) {
125
148
  ...(body.skips ? { skips: body.skips } : {}),
126
149
  ...(body.ladder ? { ladder: body.ladder } : {}),
127
150
  ...(memory?.ok ? { memory: memory.body.memory, hooks: memory.body.hooks, experience: memory.body.experience } : {}),
151
+ ...(args.turns ? { turns: body.turns ?? null } : {}),
152
+ ...(toolRouter?.ok ? { toolRouter: toolRouter.body.board ?? null } : {}),
128
153
  });
129
154
  }));
130
155
  register("slack_coverage", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/mcp",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "private": false,
5
5
  "description": "bli-tower: an MCP server over BLI Cockpit's agent doors: JARVIS (jarvis_*), documents (docs_*), channels (msg_*), issues (work_*), the daily page (brief_*), meeting notes (notes_*), the ops board (ops_status/slack_*), settings/team/model, Scout and the workbook, plus the legacy event-stream tools (emit_event, get_ticket_timeline, get_active_tickets).",
6
6
  "type": "module",