kibi-mcp 2.1.0 → 2.2.0
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/diagnostics.js +65 -22
- package/dist/server/docs.js +1 -1
- package/package.json +4 -3
package/dist/diagnostics.js
CHANGED
|
@@ -10,13 +10,32 @@
|
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import path from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { appendPayloadCountField, normalizeResultPayload } from "kibi-runtime";
|
|
13
15
|
import { resolveWorkspaceRoot } from "./workspace.js";
|
|
14
16
|
export { buildDiagnosticToolCall, classifyDiagnosticError, deriveDiagnosticHints, deriveDiagnosticRetryKey, extractToolCallPayload, redactDiagnosticArgs, } from "./diagnostics-helpers.js";
|
|
15
17
|
const DIAGNOSTIC_MODE_FLAG = "--diagnostic-mode";
|
|
16
|
-
|
|
18
|
+
const DIAGNOSTIC_MODE_ENV_KEY = "KIBI_DIAGNOSTIC_MODE";
|
|
19
|
+
/**
|
|
20
|
+
* Usage telemetry is opt-in and stays off unless the operator asks for it.
|
|
21
|
+
*
|
|
22
|
+
* The launch flag covers hosts whose MCP command line the operator writes by
|
|
23
|
+
* hand. `KIBI_DIAGNOSTIC_MODE=1` covers hosts where a plugin owns the command
|
|
24
|
+
* line, so opting in never requires editing a shipped launcher. Neither
|
|
25
|
+
* signal is set by default, and plugin installation alone never enables it.
|
|
26
|
+
*/
|
|
27
|
+
export function diagnosticModeRequested(argv = process.argv, env = process.env) {
|
|
28
|
+
if (argv.includes(DIAGNOSTIC_MODE_FLAG))
|
|
29
|
+
return true;
|
|
30
|
+
const optIn = env[DIAGNOSTIC_MODE_ENV_KEY]?.trim().toLowerCase();
|
|
31
|
+
return optIn === "1" || optIn === "true";
|
|
32
|
+
}
|
|
33
|
+
export const DIAGNOSTIC_MODE_ENABLED = diagnosticModeRequested();
|
|
17
34
|
let diagnosticUsageLogPath = null;
|
|
35
|
+
let diagnosticOriginFields = {};
|
|
18
36
|
export function initializeDiagnosticMode(enabled = DIAGNOSTIC_MODE_ENABLED) {
|
|
19
37
|
diagnosticUsageLogPath = null;
|
|
38
|
+
diagnosticOriginFields = {};
|
|
20
39
|
if (!enabled) {
|
|
21
40
|
process.env.KIBI_MCP_DIAGNOSTIC_MODE = "0";
|
|
22
41
|
return;
|
|
@@ -30,13 +49,50 @@ export function initializeDiagnosticMode(enabled = DIAGNOSTIC_MODE_ENABLED) {
|
|
|
30
49
|
diagnosticUsageLogPath =
|
|
31
50
|
process.env.KIBI_MCP_DIAGNOSTIC_USAGE_LOG_PATH ??
|
|
32
51
|
path.join(workspaceRoot, ".kb", "usage.log");
|
|
52
|
+
diagnosticOriginFields = resolveOriginFields(workspaceRoot);
|
|
33
53
|
process.env.KIBI_MCP_DIAGNOSTIC_MODE = "1";
|
|
34
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Identify which host, package build, and checkout produced a usage row.
|
|
57
|
+
*
|
|
58
|
+
* Without these a multi-worktree or multi-host setup cannot tell whether a
|
|
59
|
+
* behavioral difference came from the agent, the editor integration, or the
|
|
60
|
+
* installed Kibi version, because nothing else in a row names its origin.
|
|
61
|
+
*/
|
|
62
|
+
function resolveOriginFields(workspaceRoot) {
|
|
63
|
+
return {
|
|
64
|
+
interface: "mcp",
|
|
65
|
+
host: process.env.KIBI_MCP_HOST?.trim() || "unknown",
|
|
66
|
+
package_version: readMcpPackageVersion(),
|
|
67
|
+
workspace_root: workspaceRoot,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function readMcpPackageVersion() {
|
|
71
|
+
let current = path.dirname(fileURLToPath(import.meta.url));
|
|
72
|
+
while (true) {
|
|
73
|
+
const candidate = path.join(current, "package.json");
|
|
74
|
+
if (fs.existsSync(candidate)) {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
77
|
+
const version = isRecord(parsed) ? parsed.version : undefined;
|
|
78
|
+
return typeof version === "string" ? version : null;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const parent = path.dirname(current);
|
|
85
|
+
if (parent === current)
|
|
86
|
+
return null;
|
|
87
|
+
current = parent;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
35
90
|
export function appendUsageLogLine(entry) {
|
|
36
91
|
if (!diagnosticUsageLogPath)
|
|
37
92
|
return;
|
|
38
93
|
fs.mkdirSync(path.dirname(diagnosticUsageLogPath), { recursive: true });
|
|
39
|
-
|
|
94
|
+
const row = { ...diagnosticOriginFields, ...entry };
|
|
95
|
+
fs.appendFileSync(diagnosticUsageLogPath, `${JSON.stringify(row)}\n`, {
|
|
40
96
|
encoding: "utf8",
|
|
41
97
|
});
|
|
42
98
|
}
|
|
@@ -77,12 +133,6 @@ export const DIAGNOSTIC_TELEMETRY_SCHEMA = {
|
|
|
77
133
|
function isRecord(value) {
|
|
78
134
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
79
135
|
}
|
|
80
|
-
function structuredContentFrom(result) {
|
|
81
|
-
if (!isRecord(result))
|
|
82
|
-
return undefined;
|
|
83
|
-
const structuredContent = result.structuredContent;
|
|
84
|
-
return isRecord(structuredContent) ? structuredContent : undefined;
|
|
85
|
-
}
|
|
86
136
|
function stringArray(value) {
|
|
87
137
|
if (!Array.isArray(value))
|
|
88
138
|
return [];
|
|
@@ -276,11 +326,8 @@ export function deriveDiagnosticFields(toolName, args, telemetry, result) {
|
|
|
276
326
|
fields.actor_id = telemetry.actor_id;
|
|
277
327
|
}
|
|
278
328
|
}
|
|
279
|
-
const envelope =
|
|
280
|
-
|
|
281
|
-
? envelope.data
|
|
282
|
-
: envelope;
|
|
283
|
-
if (envelope?.kibiProtocol === 1) {
|
|
329
|
+
const { envelope, data: structuredContent } = normalizeResultPayload(result);
|
|
330
|
+
if (envelope) {
|
|
284
331
|
fields.protocol_version = envelope.kibiProtocol;
|
|
285
332
|
fields.result_version = envelope.resultVersion ?? null;
|
|
286
333
|
fields.result_status = envelope.status ?? null;
|
|
@@ -296,18 +343,14 @@ export function deriveDiagnosticFields(toolName, args, telemetry, result) {
|
|
|
296
343
|
fields.unsafe_original_retry = telemetry?.unsafe_original_retry === true;
|
|
297
344
|
}
|
|
298
345
|
if (toolName === "kb_query" || toolName === "kb_search") {
|
|
299
|
-
|
|
300
|
-
fields.result_count
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
resultCount === 0 ? "0 results" : `${resultCount} results`;
|
|
346
|
+
appendPayloadCountField(fields, "result_count", "results", structuredContent);
|
|
347
|
+
if (typeof fields.result_count === "number") {
|
|
348
|
+
fields.zero_results = fields.result_count === 0;
|
|
349
|
+
}
|
|
304
350
|
}
|
|
305
351
|
if (toolName === "kb_check") {
|
|
306
|
-
|
|
307
|
-
fields.violation_count = violationCount;
|
|
352
|
+
appendPayloadCountField(fields, "violation_count", "violations", structuredContent);
|
|
308
353
|
fields.requested_rules = Array.isArray(args.rules) ? args.rules : [];
|
|
309
|
-
fields.result_summary =
|
|
310
|
-
violationCount === 0 ? "0 violations" : `${violationCount} violations`;
|
|
311
354
|
}
|
|
312
355
|
if (toolName === "kb_coverage" && structuredContent) {
|
|
313
356
|
appendCoverageFields(fields, args, structuredContent);
|
package/dist/server/docs.js
CHANGED
|
@@ -199,7 +199,7 @@ function registerDocResources() {
|
|
|
199
199
|
'2. `kb_coverage` with `{ "by": "req", "includePassing": false }` to review proof rows and `repairPlan`; require `repairPlan.scope.complete` before treating it as a project-wide inventory',
|
|
200
200
|
"3. Apply only a `repairPlan` batch whose state is `ready`; batches are non-auto-applicable guidance, so query current endpoints, validate every write, and keep `kb_upsert` sequential",
|
|
201
201
|
"4. Re-run `kb_coverage` after each batch instead of continuing from a stale plan",
|
|
202
|
-
'5. `kb_graph` with `{ "seedIds": ["REQ-
|
|
202
|
+
'5. `kb_graph` with `{ "seedIds": ["REQ-cli-gc"], "direction": "both", "depth": 2 }` to inspect neighboring entities',
|
|
203
203
|
"",
|
|
204
204
|
"## Add a requirement and link it to a test",
|
|
205
205
|
'1. `kb_query` with `{ "type": "test" }` to check for existing test IDs',
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"mcpName": "io.github.Looted/kibi-mcp",
|
|
4
5
|
"dependencies": {
|
|
5
6
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
6
7
|
"ajv": "^8.18.0",
|
|
@@ -9,8 +10,8 @@
|
|
|
9
10
|
"fast-glob": "^3.2.12",
|
|
10
11
|
"gray-matter": "^4.0.3",
|
|
11
12
|
"js-yaml": "^4.1.0",
|
|
12
|
-
"kibi-runtime": "^2.0.
|
|
13
|
-
"kibi-core": "^0.
|
|
13
|
+
"kibi-runtime": "^2.0.2",
|
|
14
|
+
"kibi-core": "^0.14.0",
|
|
14
15
|
"mcpcat": "^0.1.12",
|
|
15
16
|
"zod": "^4.3.6"
|
|
16
17
|
},
|