kibi-cli 0.12.1 → 0.12.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AA2EA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA8bD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0V/B"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AA2EA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAgcD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0V/B"}
@@ -101,7 +101,9 @@ function buildManifestLookup(stagedFiles) {
101
101
  const authoredSymbolResult = {
102
102
  entity: entry.entity,
103
103
  relationships: entry.relationships,
104
- ...(entry.sourceFile !== undefined ? { sourceFile: entry.sourceFile } : {}),
104
+ ...(entry.sourceFile !== undefined
105
+ ? { sourceFile: entry.sourceFile }
106
+ : {}),
105
107
  };
106
108
  authoredSymbolResults.push(authoredSymbolResult);
107
109
  stagedAuthoredSymbolResults.push(authoredSymbolResult);
@@ -147,7 +149,7 @@ function hasTraceabilityRelationship(result) {
147
149
  }
148
150
  function hasValidGranularityReason(result) {
149
151
  const reason = result.entity.granularity_reason;
150
- return (typeof reason === "string" && ALLOWED_GRANULARITY_REASONS.has(reason));
152
+ return typeof reason === "string" && ALLOWED_GRANULARITY_REASONS.has(reason);
151
153
  }
152
154
  function createSymbolGranularityDiagnostics(options) {
153
155
  const diagnostics = [];
@@ -161,7 +163,9 @@ function createSymbolGranularityDiagnostics(options) {
161
163
  const granularSymbols = getGranularSymbolsForSourceFile(result.sourceFile, options.symbolsByFile, options.sourceContentByFile);
162
164
  if (granularSymbols.length === 0)
163
165
  continue;
164
- const granularNames = [...new Set(granularSymbols.map((s) => s.name))].sort();
166
+ const granularNames = [
167
+ ...new Set(granularSymbols.map((s) => s.name)),
168
+ ].sort();
165
169
  if (granularNames.includes(result.entity.title))
166
170
  continue;
167
171
  diagnostics.push({
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAqCA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AA2VD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgI/B"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAqCA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAiWD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgI/B"}
@@ -135,7 +135,7 @@ function hasTraceabilityRelationship(symbol) {
135
135
  return false;
136
136
  }
137
137
  const type = relationship.type;
138
- return typeof type === "string" && TRACEABILITY_RELATIONSHIP_TYPES.has(type);
138
+ return (typeof type === "string" && TRACEABILITY_RELATIONSHIP_TYPES.has(type));
139
139
  });
140
140
  }
141
141
  function getGranularNames(cwd, sourceFile) {
@@ -218,7 +218,9 @@ function migrateSymbolGranularity(options) {
218
218
  const migratedSymbolIds = new Set();
219
219
  const granularNamesByFile = new Map();
220
220
  for (const symbol of manifest.symbols) {
221
- if (symbol === null || typeof symbol !== "object" || Array.isArray(symbol)) {
221
+ if (symbol === null ||
222
+ typeof symbol !== "object" ||
223
+ Array.isArray(symbol)) {
222
224
  continue;
223
225
  }
224
226
  const record = symbol;
@@ -1 +1 @@
1
- {"version":3,"file":"usage-metrics.d.ts","sourceRoot":"","sources":["../../src/commands/usage-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAuBpC"}
1
+ {"version":3,"file":"usage-metrics.d.ts","sourceRoot":"","sources":["../../src/commands/usage-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAuBpC"}
@@ -54,6 +54,9 @@ function buildUsageMetricsReport(rows, limit) {
54
54
  const zeroResultToolCounts = new Map();
55
55
  const zeroResultSourceFileCounts = new Map();
56
56
  const upsertErrorCategories = new Map();
57
+ const errorCategories = new Map();
58
+ const errorStages = new Map();
59
+ const errorsByTool = new Map();
57
60
  const violationTrend = [];
58
61
  let successCount = 0;
59
62
  let errorCount = 0;
@@ -69,6 +72,10 @@ function buildUsageMetricsReport(rows, limit) {
69
72
  }
70
73
  if (outcome === "error") {
71
74
  errorCount += 1;
75
+ const category = row.error_category ?? categorizeError(row.error_message ?? row.error);
76
+ increment(errorCategories, category);
77
+ increment(errorStages, row.error_stage ?? inferErrorStage(row.error_message ?? row.error));
78
+ increment(errorsByTool, normalizeKey(row.tool, "unknown"));
72
79
  }
73
80
  if (hasCompleteTelemetry(row)) {
74
81
  telemetryCompleteCount += 1;
@@ -128,6 +135,11 @@ function buildUsageMetricsReport(rows, limit) {
128
135
  upsertErrors: {
129
136
  categories: mapToSortedObject(upsertErrorCategories),
130
137
  },
138
+ errors: {
139
+ categories: mapToSortedObject(errorCategories),
140
+ stages: mapToSortedObject(errorStages),
141
+ byTool: mapToSortedObject(errorsByTool),
142
+ },
131
143
  };
132
144
  }
133
145
  function hasCompleteTelemetry(row) {
@@ -180,9 +192,31 @@ function getSourceFile(row) {
180
192
  return null;
181
193
  }
182
194
  function categorizeUpsertError(errorMessage) {
195
+ return categorizeError(errorMessage);
196
+ }
197
+ function categorizeError(errorMessage) {
183
198
  if (!errorMessage) {
184
199
  return "Unknown error";
185
200
  }
201
+ const lower = errorMessage.toLowerCase();
202
+ if (lower.includes("stale_snapshot")) {
203
+ return "stale_snapshot";
204
+ }
205
+ if (lower.includes("unknown option") && lower.includes("h for help")) {
206
+ return "prolog_unknown_option";
207
+ }
208
+ if (lower.includes("prolog process not started")) {
209
+ return "prolog_process_not_started";
210
+ }
211
+ if (lower.includes("coarsely while granular symbols are available")) {
212
+ return "coarse_symbol_linkage";
213
+ }
214
+ if (lower.includes("module load failed")) {
215
+ return "prolog_module_load_failed";
216
+ }
217
+ if (lower.includes("query failed")) {
218
+ return "prolog_query_failed";
219
+ }
186
220
  if (errorMessage.startsWith("Entity validation failed:")) {
187
221
  return "Entity validation failed";
188
222
  }
@@ -199,6 +233,29 @@ function categorizeUpsertError(errorMessage) {
199
233
  }
200
234
  return errorMessage.trim() || "Unknown error";
201
235
  }
236
+ function inferErrorStage(errorMessage) {
237
+ if (!errorMessage) {
238
+ return "unknown";
239
+ }
240
+ const lower = errorMessage.toLowerCase();
241
+ if (lower.includes("stale_snapshot")) {
242
+ return "persistence";
243
+ }
244
+ if (lower.includes("unknown option") ||
245
+ lower.includes("module load failed") ||
246
+ lower.includes("query failed")) {
247
+ return "prolog_runtime";
248
+ }
249
+ if (lower.includes("prolog process not started")) {
250
+ return "prolog_lifecycle";
251
+ }
252
+ if (lower.includes("validation failed") ||
253
+ lower.includes("relationship source must match") ||
254
+ lower.includes("coarsely while granular symbols are available")) {
255
+ return "validation";
256
+ }
257
+ return "unknown";
258
+ }
202
259
  function increment(counts, key) {
203
260
  counts.set(key, (counts.get(key) ?? 0) + 1);
204
261
  }
@@ -221,6 +278,9 @@ function renderUsageMetricsReport(report) {
221
278
  renderZeroResultsTable(report),
222
279
  renderViolationTrendTable(report),
223
280
  renderCountsTable("Upsert Error Categories", "Category", report.upsertErrors.categories),
281
+ renderCountsTable("Error Categories", "Category", report.errors.categories),
282
+ renderCountsTable("Error Stages", "Stage", report.errors.stages),
283
+ renderCountsTable("Errors By Tool", "Tool", report.errors.byTool),
224
284
  ].filter(Boolean);
225
285
  return sections.join("\n\n");
226
286
  }
@@ -1,7 +1,7 @@
1
1
  import { type ManifestSymbolEntry, enrichSymbolCoordinatesWithTsMorph } from "./symbols-ts.js";
2
2
  export type { ManifestSymbolEntry };
3
3
  export type SourceAnalysisMode = "parser" | "fallback";
4
- export type SourceSymbolKind = "function" | "class" | "interface" | "type" | "enum" | "variable" | "unknown";
4
+ export type SourceSymbolKind = "function" | "class" | "method" | "interface" | "type" | "enum" | "variable" | "unknown";
5
5
  export interface SourceSymbolAnalysis {
6
6
  name: string;
7
7
  kind: SourceSymbolKind;
@@ -1 +1 @@
1
- {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,mBAAmB,EAExB,kCAAkC,EACnC,MAAM,iBAAiB,CAAC;AAazB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,OAAO,GACP,WAAW,GACX,MAAM,GACN,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACtE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,kCAAkC,CAAC;CAChE;AA+BD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAClC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CAAC;AAkCxB,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
1
+ {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,mBAAmB,EAExB,kCAAkC,EACnC,MAAM,iBAAiB,CAAC;AAazB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,WAAW,GACX,MAAM,GACN,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACtE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,kCAAkC,CAAC;CAChE;AA+BD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAClC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CAAC;AAkCxB,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
@@ -184,10 +184,16 @@ function collectSourceSymbols(sourceFile) {
184
184
  for (const decl of sourceFile.getClasses()) {
185
185
  if (!decl.isExported())
186
186
  continue;
187
- symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "class", decl.getNameNode() ?? decl, decl, `${decl.getText()}\n${decl
187
+ symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "class", decl.getNameNode() ?? decl, decl, decl
188
188
  .getJsDocs()
189
189
  .map((doc) => doc.getFullText())
190
- .join("\n")}`));
190
+ .join("\n")));
191
+ for (const method of decl.getMethods()) {
192
+ symbols.push(toSourceSymbolAnalysis(sourceFile, formatMethodSymbolName(decl.getName(), method.getName()), "method", method.getNameNode() ?? method, method, `${method.getFullText()}\n${method
193
+ .getJsDocs()
194
+ .map((doc) => doc.getFullText())
195
+ .join("\n")}`));
196
+ }
191
197
  }
192
198
  for (const decl of sourceFile.getInterfaces()) {
193
199
  if (!decl.isExported())
@@ -226,6 +232,9 @@ function toSourceSymbolAnalysis(sourceFile, name, kind, startNode, endNode, dire
226
232
  directiveText,
227
233
  };
228
234
  }
235
+ function formatMethodSymbolName(className, methodName) {
236
+ return className ? `${className}.${methodName}` : methodName;
237
+ }
229
238
  function chooseScriptKind(filePath) {
230
239
  const lower = filePath.toLowerCase();
231
240
  if (lower.endsWith(".tsx"))
@@ -252,6 +261,22 @@ function inferModuleTitle(filePath) {
252
261
  return basename.length > 0 ? basename : path.basename(filePath);
253
262
  }
254
263
  function findNamedDeclaration(sourceFile, title) {
264
+ const qualifiedMethod = parseQualifiedMethodTitle(title);
265
+ if (qualifiedMethod) {
266
+ for (const cls of sourceFile.getClasses()) {
267
+ if (cls.getName() !== qualifiedMethod.className)
268
+ continue;
269
+ for (const method of cls.getMethods()) {
270
+ if (method.getName() !== qualifiedMethod.methodName)
271
+ continue;
272
+ const nameNode = method.getNameNode();
273
+ if (!nameNode)
274
+ continue;
275
+ return { node: method, getNameNode: () => nameNode };
276
+ }
277
+ }
278
+ return null;
279
+ }
255
280
  const candidates = [];
256
281
  for (const decl of sourceFile.getFunctions()) {
257
282
  if (!decl.isExported())
@@ -357,3 +382,12 @@ function findNamedDeclaration(sourceFile, title) {
357
382
  candidates.sort((a, b) => a.getNameNode().getStart() - b.getNameNode().getStart());
358
383
  return candidates[0] ?? null;
359
384
  }
385
+ function parseQualifiedMethodTitle(title) {
386
+ const separatorIndex = title.lastIndexOf(".");
387
+ if (separatorIndex <= 0 || separatorIndex === title.length - 1)
388
+ return null;
389
+ return {
390
+ className: title.slice(0, separatorIndex),
391
+ methodName: title.slice(separatorIndex + 1),
392
+ };
393
+ }
package/dist/prolog.d.ts CHANGED
@@ -16,6 +16,7 @@ export declare class PrologProcess {
16
16
  private errorBuffer;
17
17
  private cache;
18
18
  private interactiveQueryTail;
19
+ private terminationPromise;
19
20
  private useOneShotMode;
20
21
  private attachedKbPath;
21
22
  private onProcessExit;
@@ -30,6 +31,8 @@ export declare class PrologProcess {
30
31
  private queryOneShot;
31
32
  private execOneShot;
32
33
  private normalizeGoal;
34
+ private clearQueryBuffers;
35
+ private isProcessUsable;
33
36
  private extractBindings;
34
37
  private translateError;
35
38
  isRunning(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,IAAI,MAAM,CAsCxC;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,cAAc,CACyC;IAC/D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,GAAE,aAAkB;IAKjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAsCd,YAAY;IA0CpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAoK1D,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IAsGnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IA+BtB,SAAS,IAAI,OAAO;IAIpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAyBjC"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,IAAI,MAAM,CAsCxC;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,cAAc,CACyC;IAC/D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,GAAE,aAAkB;IAKjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAuCd,YAAY;IA0CpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAmK1D,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IAsGnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IA+BtB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAwCjC"}
package/dist/prolog.js CHANGED
@@ -67,6 +67,7 @@ export class PrologProcess {
67
67
  errorBuffer = "";
68
68
  cache = new Map();
69
69
  interactiveQueryTail = Promise.resolve();
70
+ terminationPromise = null;
70
71
  useOneShotMode = typeof globalThis.Bun !== "undefined";
71
72
  attachedKbPath = null;
72
73
  onProcessExit = null;
@@ -84,6 +85,7 @@ export class PrologProcess {
84
85
  `use_module('${kbPath}'), use_module(library(semweb/rdf_db)), set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])`,
85
86
  "--quiet",
86
87
  ]);
88
+ this.clearQueryBuffers();
87
89
  if (!this.process.stdout || !this.process.stderr || !this.process.stdin) {
88
90
  throw new Error("Failed to spawn Prolog process");
89
91
  }
@@ -155,12 +157,11 @@ export class PrologProcess {
155
157
  const batchGoal = `(${goal.map((item) => this.normalizeGoal(item)).join(", ")})`;
156
158
  return this.query(batchGoal);
157
159
  }
158
- if (!this.process || !this.process.stdin) {
160
+ if (!this.isProcessUsable()) {
159
161
  throw new Error("Prolog process not started");
160
162
  }
161
163
  const runInteractiveQuery = async () => {
162
- this.outputBuffer = "";
163
- this.errorBuffer = "";
164
+ this.clearQueryBuffers();
164
165
  const debug = isPrologDebugEnabled();
165
166
  const normalizedGoal = this.normalizeGoal(goal);
166
167
  const wrappedGoal = /^once\s*\(/.test(normalizedGoal)
@@ -258,7 +259,7 @@ export class PrologProcess {
258
259
  });
259
260
  await previousQuery;
260
261
  try {
261
- if (!this.process || !this.process.stdin) {
262
+ if (!this.isProcessUsable()) {
262
263
  throw new Error("Prolog process not started");
263
264
  }
264
265
  return await runInteractiveQuery();
@@ -410,6 +411,16 @@ export class PrologProcess {
410
411
  normalizeGoal(goal) {
411
412
  return goal.trim().replace(/\.+\s*$/, "");
412
413
  }
414
+ clearQueryBuffers() {
415
+ this.outputBuffer = "";
416
+ this.errorBuffer = "";
417
+ }
418
+ // implements REQ-009
419
+ isProcessUsable() {
420
+ return Boolean(this.process?.stdin &&
421
+ !this.process?.killed &&
422
+ this.process?.exitCode === null);
423
+ }
413
424
  extractBindings(output) {
414
425
  const bindings = {};
415
426
  const lines = output.split("\n");
@@ -447,30 +458,44 @@ export class PrologProcess {
447
458
  return simpleError || "Unknown error";
448
459
  }
449
460
  isRunning() {
450
- return this.process !== null && !this.process.killed;
461
+ return Boolean(this.process && !this.process.killed && this.process?.exitCode === null);
451
462
  }
452
463
  getPid() {
453
464
  return this.process?.pid || 0;
454
465
  }
455
466
  async terminate() {
467
+ if (this.terminationPromise) {
468
+ await this.terminationPromise;
469
+ return;
470
+ }
456
471
  if (this.onProcessExit) {
457
472
  process.off("exit", this.onProcessExit);
458
473
  this.onProcessExit = null;
459
474
  }
460
- if (this.process) {
461
- this.process.stdin?.end();
462
- this.process.kill("SIGTERM");
463
- await new Promise((resolve) => {
464
- const timeout = setTimeout(() => {
465
- this.process?.kill("SIGKILL");
466
- resolve(undefined);
467
- }, 1000);
468
- this.process?.on("exit", () => {
469
- clearTimeout(timeout);
470
- resolve(undefined);
475
+ const current = this.process;
476
+ this.process = null;
477
+ this.clearQueryBuffers();
478
+ if (current) {
479
+ this.terminationPromise = (async () => {
480
+ current.stdin?.end();
481
+ current.kill("SIGTERM");
482
+ await new Promise((resolve) => {
483
+ const timeout = setTimeout(() => {
484
+ current.kill("SIGKILL");
485
+ resolve(undefined);
486
+ }, 1000);
487
+ current.on("exit", () => {
488
+ clearTimeout(timeout);
489
+ resolve(undefined);
490
+ });
471
491
  });
472
- });
473
- this.process = null;
492
+ })();
493
+ try {
494
+ await this.terminationPromise;
495
+ }
496
+ finally {
497
+ this.terminationPromise = null;
498
+ }
474
499
  }
475
500
  }
476
501
  }
@@ -24,6 +24,10 @@ Consult this skill before any Kibi knowledge base operation, on first interactio
24
24
 
25
25
  Interact with the knowledge base exclusively through MCP tools. Do not read or edit files inside `.kb/` directly. Do not run any `kibi` CLI commands from the agent session. The MCP surface is the only sanctioned interface for agents.
26
26
 
27
+ ### Tool Name Prefixes
28
+
29
+ Kibi's canonical MCP names are `kb_search`, `kb_query`, `kb_upsert`, `kb_check`, and related `kb_*` tools. Some hosts add a server prefix when exposing tools to agents. In OpenCode, use the visible `kibi_kb_search`, `kibi_kb_query`, `kibi_kb_upsert`, and `kibi_kb_check` names when exact tool identifiers are required; they map to the same canonical MCP names.
30
+
27
31
  ## Discovery-First Workflow
28
32
 
29
33
  Always discover before you mutate. Start with `kb_search` for exploratory discovery across metadata and markdown body text. Split broad queries into 1-3 focused probes. Review top hits for relevance before concluding the KB lacks knowledge.
@@ -6,7 +6,7 @@ type TraceabilityRelationship = {
6
6
  export interface ExtractedSymbol {
7
7
  id: string;
8
8
  name: string;
9
- kind: "function" | "class" | "interface" | "type" | "variable" | "enum" | "unknown";
9
+ kind: "function" | "class" | "method" | "interface" | "type" | "variable" | "enum" | "unknown";
10
10
  location: {
11
11
  file: string;
12
12
  startLine: number;
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAU7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EACA,UAAU,GACV,OAAO,GACP,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,GACN,SAAS,CAAC;IACd,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG5E;AAkOD,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,EAAE,CA+MnB"}
1
+ {"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAU7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EACA,UAAU,GACV,OAAO,GACP,QAAQ,GACR,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,GACN,SAAS,CAAC;IACd,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG5E;AAkOD,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,EAAE,CAyOnB"}
@@ -229,15 +229,30 @@ stagedFile, manifestLookup) {
229
229
  const start = cls.getNameNode()?.getStart() ?? cls.getStart();
230
230
  const end = cls.getEnd();
231
231
  const span = getSpan(start, end);
232
- const reqLinks = parseReqDirectives(`${cls.getText()}\n${cls
233
- .getJsDocs()
234
- .map((d) => d.getFullText())
235
- .join("\n")}`);
232
+ const reqLinks = parseReqDirectives(getJsDocText(cls.getJsDocs()));
236
233
  results.push(buildSymbolResult(stagedFile, name, "class", span, reqLinks, manifestLookup));
237
234
  }
238
235
  catch {
239
236
  void stagedFile.path;
240
237
  }
238
+ for (const method of typeof cls.getMethods === "function"
239
+ ? cls.getMethods()
240
+ : []) {
241
+ try {
242
+ const name = formatMethodSymbolName(cls.getName(), method.getName());
243
+ const start = method.getNameNode()?.getStart() ?? method.getStart();
244
+ const end = method.getEnd();
245
+ const span = getSpan(start, end);
246
+ const reqLinks = parseReqDirectives(`${method.getFullText()}\n${method
247
+ .getJsDocs()
248
+ .map((d) => d.getFullText())
249
+ .join("\n")}`);
250
+ results.push(buildSymbolResult(stagedFile, name, "method", span, reqLinks, manifestLookup));
251
+ }
252
+ catch {
253
+ void stagedFile.path;
254
+ }
255
+ }
241
256
  }
242
257
  // Enums
243
258
  for (const en of sf.getEnums()) {
@@ -255,7 +270,9 @@ stagedFile, manifestLookup) {
255
270
  void stagedFile.path;
256
271
  }
257
272
  }
258
- for (const iface of typeof sf.getInterfaces === "function" ? sf.getInterfaces() : []) {
273
+ for (const iface of typeof sf.getInterfaces === "function"
274
+ ? sf.getInterfaces()
275
+ : []) {
259
276
  if (!iface.isExported())
260
277
  continue;
261
278
  try {
@@ -270,7 +287,9 @@ stagedFile, manifestLookup) {
270
287
  void stagedFile.path;
271
288
  }
272
289
  }
273
- for (const alias of typeof sf.getTypeAliases === "function" ? sf.getTypeAliases() : []) {
290
+ for (const alias of typeof sf.getTypeAliases === "function"
291
+ ? sf.getTypeAliases()
292
+ : []) {
274
293
  if (!alias.isExported())
275
294
  continue;
276
295
  try {
@@ -311,6 +330,12 @@ stagedFile, manifestLookup) {
311
330
  }
312
331
  return results;
313
332
  }
333
+ function formatMethodSymbolName(className, methodName) {
334
+ return className ? `${className}.${methodName}` : methodName;
335
+ }
336
+ function getJsDocText(jsDocs) {
337
+ return jsDocs.map((d) => d.getFullText()).join("\n");
338
+ }
314
339
  function intersectingHunks(startLine, endLine, hunks) {
315
340
  const out = [];
316
341
  for (const h of hunks) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "0.12.1",
3
+ "version": "0.12.4",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
@@ -11,13 +11,7 @@
11
11
  "bin": {
12
12
  "kibi": "bin/kibi"
13
13
  },
14
- "files": [
15
- "dist",
16
- "bin",
17
- "schema",
18
- "src/schemas",
19
- "src/public"
20
- ],
14
+ "files": ["dist", "bin", "schema", "src/schemas", "src/public"],
21
15
  "scripts": {
22
16
  "build": "tsc -p tsconfig.json && mkdir -p dist/public/skills && cp -r src/public/skills/. dist/public/skills/",
23
17
  "prepack": "npm run build"
@@ -24,6 +24,10 @@ Consult this skill before any Kibi knowledge base operation, on first interactio
24
24
 
25
25
  Interact with the knowledge base exclusively through MCP tools. Do not read or edit files inside `.kb/` directly. Do not run any `kibi` CLI commands from the agent session. The MCP surface is the only sanctioned interface for agents.
26
26
 
27
+ ### Tool Name Prefixes
28
+
29
+ Kibi's canonical MCP names are `kb_search`, `kb_query`, `kb_upsert`, `kb_check`, and related `kb_*` tools. Some hosts add a server prefix when exposing tools to agents. In OpenCode, use the visible `kibi_kb_search`, `kibi_kb_query`, `kibi_kb_upsert`, and `kibi_kb_check` names when exact tool identifiers are required; they map to the same canonical MCP names.
30
+
27
31
  ## Discovery-First Workflow
28
32
 
29
33
  Always discover before you mutate. Start with `kb_search` for exploratory discovery across metadata and markdown body text. Split broad queries into 1-3 focused probes. Review top hits for relevance before concluding the KB lacks knowledge.