kibi-cli 0.18.1 → 0.19.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.
Files changed (89) hide show
  1. package/dist/cli-json-command.d.ts +1 -2
  2. package/dist/cli-json-command.d.ts.map +1 -1
  3. package/dist/cli-json-command.js +2 -34
  4. package/dist/cli-operation-loader.d.ts +3 -0
  5. package/dist/cli-operation-loader.d.ts.map +1 -0
  6. package/dist/cli-operation-loader.js +58 -0
  7. package/dist/cli-operation-metadata.d.ts +82 -0
  8. package/dist/cli-operation-metadata.d.ts.map +1 -0
  9. package/dist/cli-operation-metadata.js +106 -0
  10. package/dist/cli-protocol.d.ts +1 -1
  11. package/dist/cli-protocol.d.ts.map +1 -1
  12. package/dist/cli-protocol.js +4 -3
  13. package/dist/cli-register-foundation.d.ts.map +1 -1
  14. package/dist/cli-register-foundation.js +14 -17
  15. package/dist/cli-register-json.d.ts +3 -0
  16. package/dist/cli-register-json.d.ts.map +1 -0
  17. package/dist/cli-register-json.js +35 -0
  18. package/dist/cli-register-maintenance.d.ts.map +1 -1
  19. package/dist/cli-register-maintenance.js +35 -10
  20. package/dist/cli-register-reporting.d.ts.map +1 -1
  21. package/dist/cli-register-reporting.js +13 -14
  22. package/dist/cli-register-skills.d.ts.map +1 -1
  23. package/dist/cli-register-skills.js +8 -6
  24. package/dist/cli.js +1 -1
  25. package/dist/commands/check.d.ts.map +1 -1
  26. package/dist/commands/check.js +30 -12
  27. package/dist/commands/coverage.js +1 -1
  28. package/dist/commands/discovery-shared.d.ts +2 -1
  29. package/dist/commands/discovery-shared.d.ts.map +1 -1
  30. package/dist/commands/discovery-shared.js +35 -13
  31. package/dist/commands/engine.d.ts +8 -0
  32. package/dist/commands/engine.d.ts.map +1 -0
  33. package/dist/commands/engine.js +100 -0
  34. package/dist/commands/gaps.js +1 -1
  35. package/dist/commands/graph.js +1 -1
  36. package/dist/commands/query.d.ts.map +1 -1
  37. package/dist/commands/query.js +3 -1
  38. package/dist/commands/search.d.ts.map +1 -1
  39. package/dist/commands/search.js +3 -1
  40. package/dist/commands/status.d.ts.map +1 -1
  41. package/dist/commands/status.js +2 -1
  42. package/dist/commands/sync/cache.d.ts +10 -0
  43. package/dist/commands/sync/cache.d.ts.map +1 -1
  44. package/dist/commands/sync/cache.js +30 -1
  45. package/dist/commands/sync/persistence.d.ts +10 -1
  46. package/dist/commands/sync/persistence.d.ts.map +1 -1
  47. package/dist/commands/sync/persistence.js +220 -44
  48. package/dist/commands/sync/staging.d.ts +10 -1
  49. package/dist/commands/sync/staging.d.ts.map +1 -1
  50. package/dist/commands/sync/staging.js +84 -1
  51. package/dist/commands/sync.d.ts.map +1 -1
  52. package/dist/commands/sync.js +450 -13
  53. package/dist/engine-daemon.d.ts +3 -0
  54. package/dist/engine-daemon.d.ts.map +1 -0
  55. package/dist/engine-daemon.js +34 -0
  56. package/dist/engine.d.ts +63 -0
  57. package/dist/engine.d.ts.map +1 -0
  58. package/dist/engine.js +1256 -0
  59. package/dist/extractors/relationships.d.ts +2 -0
  60. package/dist/extractors/relationships.d.ts.map +1 -1
  61. package/dist/extractors/relationships.js +15 -17
  62. package/dist/prolog.d.ts +8 -0
  63. package/dist/prolog.d.ts.map +1 -1
  64. package/dist/prolog.js +39 -8
  65. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  66. package/dist/public/operations/discovery-entities.js +3 -2
  67. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  68. package/dist/public/operations/discovery-executors.js +40 -3
  69. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  70. package/dist/public/operations/prolog-json.js +14 -4
  71. package/dist/public/operations/runtime-types.d.ts +31 -0
  72. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  73. package/dist/public/skills/init-kibi/SKILL.md +2 -2
  74. package/dist/public/skills/kibi-freshness/SKILL.md +2 -2
  75. package/dist/public/skills/kibi-traceability/SKILL.md +1 -1
  76. package/dist/public/skills/kibi-usage/SKILL.md +2 -2
  77. package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -1
  78. package/dist/runtime/cli-runtime.d.ts.map +1 -1
  79. package/dist/runtime/cli-runtime.js +33 -37
  80. package/package.json +8 -4
  81. package/src/public/operations/discovery-entities.ts +3 -2
  82. package/src/public/operations/discovery-executors.ts +44 -3
  83. package/src/public/operations/prolog-json.ts +15 -3
  84. package/src/public/operations/runtime-types.ts +39 -0
  85. package/src/public/skills/init-kibi/SKILL.md +2 -2
  86. package/src/public/skills/kibi-freshness/SKILL.md +2 -2
  87. package/src/public/skills/kibi-traceability/SKILL.md +1 -1
  88. package/src/public/skills/kibi-usage/SKILL.md +2 -2
  89. package/src/public/skills/kibi-usage/resources/operation-access.md +1 -1
@@ -20,6 +20,8 @@ export interface ShardExtractionResult {
20
20
  * @returns Array of extraction results, one per shard file
21
21
  */
22
22
  export declare function extractFromRelationshipShards(relationshipsDir: string): ShardExtractionResult[];
23
+ /** Parse one changed shard. Callers can hash first and skip unchanged files. */
24
+ export declare function extractRelationshipShard(shardPath: string): ShardExtractionResult;
23
25
  /**
24
26
  * Gets the path to the relationships directory for a given KB root.
25
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/extractors/relationships.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,qBAAqB,EAAE,CAAC;CACxC;AAwBD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,gBAAgB,EAAE,MAAM,GACvB,qBAAqB,EAAE,CAyCzB;AAmDD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,EAAE,GAC/B,qBAAqB,EAAE,CAEzB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,qBAAqB,EAAE,EACtC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,KAAK,CAAC;IACP,YAAY,EAAE,qBAAqB,CAAC;IACpC,KAAK,EAAE,cAAc,GAAG,YAAY,CAAC;CACtC,CAAC,CAgBD"}
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/extractors/relationships.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,qBAAqB,EAAE,CAAC;CACxC;AAwBD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,gBAAgB,EAAE,MAAM,GACvB,qBAAqB,EAAE,CAmBzB;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,GAChB,qBAAqB,CAiBvB;AAmDD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,EAAE,GAC/B,qBAAqB,EAAE,CAEzB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,qBAAqB,EAAE,EACtC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,KAAK,CAAC;IACP,YAAY,EAAE,qBAAqB,CAAC;IACpC,KAAK,EAAE,cAAc,GAAG,YAAY,CAAC;CACtC,CAAC,CAgBD"}
@@ -56,27 +56,25 @@ export function extractFromRelationshipShards(relationshipsDir) {
56
56
  continue;
57
57
  }
58
58
  const shardPath = path.join(relationshipsDir, file);
59
- const stats = fs.statSync(shardPath);
60
- if (!stats.isFile()) {
59
+ if (!fs.statSync(shardPath).isFile())
61
60
  continue;
62
- }
63
- try {
64
- const records = readShard(shardPath);
65
- const relationships = records
66
- .map(convertRecordToRelationship)
67
- .filter((r) => r !== null);
68
- results.push({
69
- shardPath,
70
- relationships,
71
- });
72
- }
73
- catch (error) {
74
- // Re-throw with shard path context
75
- throw new Error(`Failed to extract relationships from ${shardPath}: ${error instanceof Error ? error.message : String(error)}`);
76
- }
61
+ results.push(extractRelationshipShard(shardPath));
77
62
  }
78
63
  return results;
79
64
  }
65
+ /** Parse one changed shard. Callers can hash first and skip unchanged files. */
66
+ export function extractRelationshipShard(shardPath) {
67
+ try {
68
+ const records = readShard(shardPath);
69
+ const relationships = records
70
+ .map(convertRecordToRelationship)
71
+ .filter((relationship) => relationship !== null);
72
+ return { shardPath, relationships };
73
+ }
74
+ catch (error) {
75
+ throw new Error(`Failed to extract relationships from ${shardPath}: ${error instanceof Error ? error.message : String(error)}`);
76
+ }
77
+ }
80
78
  /**
81
79
  * Converts a RelationshipRecord to an ExtractedRelationship.
82
80
  * Returns null if the record is invalid.
package/dist/prolog.d.ts CHANGED
@@ -2,6 +2,12 @@ export declare function resolveKbPlPath(): string;
2
2
  export interface PrologOptions {
3
3
  swiplPath?: string;
4
4
  timeout?: number;
5
+ /**
6
+ * Force one-shot SWI execution. Production callers are Node-only and keep
7
+ * one interactive process alive; the fallback is retained for isolated
8
+ * repository tests that still run under Bun.
9
+ */
10
+ oneShot?: boolean;
5
11
  }
6
12
  export interface QueryResult {
7
13
  success: boolean;
@@ -28,6 +34,8 @@ export declare class PrologProcess {
28
34
  start(): Promise<void>;
29
35
  private waitForReady;
30
36
  query(goal: string | string[]): Promise<QueryResult>;
37
+ /** Execute a group of goals as one transaction and one durable save. */
38
+ queryBatch(goals: readonly string[]): Promise<QueryResult>;
31
39
  invalidateCache(): void;
32
40
  private isCacheableGoal;
33
41
  private isMutatingGoal;
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AAkDA,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,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,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;YAsDd,YAAY;IAyCpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IA8L1D,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IA8NnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,iBAAiB;YAkBX,oBAAoB;IAyBlC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,cAAc;IA+EtB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAkCjC"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AAkDA,wBAAgB,eAAe,IAAI,MAAM,CAsCxC;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;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,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,GAAE,aAAkB;IASjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAsDd,YAAY;IAyCpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAgN1D,wEAAwE;IAClE,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAIhE,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IA8NnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,iBAAiB;YAkBX,oBAAoB;IAyBlC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,cAAc;IA+EtB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAkCjC"}
package/dist/prolog.js CHANGED
@@ -91,12 +91,16 @@ export class PrologProcess {
91
91
  interactiveQueryTail = Promise.resolve();
92
92
  terminationPromise = null;
93
93
  oneShotProcesses = new Set();
94
- useOneShotMode = typeof globalThis.Bun !== "undefined";
94
+ useOneShotMode;
95
95
  attachedKbPath = null;
96
96
  onProcessExit = null;
97
97
  constructor(options = {}) {
98
98
  this.swiplPath = options.swiplPath || "swipl";
99
99
  this.timeout = options.timeout || 30000;
100
+ this.useOneShotMode =
101
+ options.oneShot ??
102
+ (process.env.NODE_ENV === "test" &&
103
+ typeof globalThis.Bun !== "undefined");
100
104
  }
101
105
  async start() {
102
106
  if (!existsSync(this.swiplPath) && this.swiplPath !== "swipl") {
@@ -189,10 +193,21 @@ export class PrologProcess {
189
193
  return oneShotResult;
190
194
  }
191
195
  if (!isSingleGoal) {
192
- const batchGoal = `(${goal.map((item) => this.normalizeGoal(item)).join(", ")})`;
196
+ // A batch is one logical write. Wrapping it here keeps RDF mutations
197
+ // atomic in the long-lived process; persistence is appended by the
198
+ // interactive wrapper once the transaction succeeds.
199
+ const batchGoal = `rdf_transaction((${goal.map((item) => this.normalizeGoal(item)).join(", ")}))`;
193
200
  return this.query(batchGoal);
194
201
  }
195
202
  if (!this.isProcessUsable()) {
203
+ // Keep the low-level PrologPort useful for isolated callers that only
204
+ // need a single read (and for legacy unit fixtures). Normal CLI/MCP
205
+ // runtimes provide an EngineClient, while explicitly attached callers
206
+ // call start() and stay interactive; this fallback never participates
207
+ // in the engine-backed workflow.
208
+ if (this.process === null) {
209
+ return this.execOneShot(goal, this.attachedKbPath);
210
+ }
196
211
  throw new Error("Prolog process not started");
197
212
  }
198
213
  const runInteractiveQuery = async () => {
@@ -200,9 +215,15 @@ export class PrologProcess {
200
215
  const debug = isPrologDebugEnabled();
201
216
  const normalizedGoal = this.normalizeGoal(goal);
202
217
  const goalLabel = this.goalLabel(normalizedGoal);
203
- const wrappedGoal = /^once\s*\(/.test(normalizedGoal)
204
- ? `catch(${normalizedGoal}, _E, (print_message(error, _E), fail))`
205
- : `catch(once((${normalizedGoal})), _E, (print_message(error, _E), fail))`;
218
+ const shouldPersist = this.isMutatingGoal(normalizedGoal) &&
219
+ !normalizedGoal.includes("kb_save") &&
220
+ !normalizedGoal.includes("kb_commit_upsert");
221
+ const goalWithPersistence = shouldPersist
222
+ ? `(${normalizedGoal}, kb_save)`
223
+ : normalizedGoal;
224
+ const wrappedGoal = /^once\s*\(/.test(goalWithPersistence)
225
+ ? `catch(${goalWithPersistence}, _E, (print_message(error, _E), fail))`
226
+ : `catch(once((${goalWithPersistence})), _E, (print_message(error, _E), fail))`;
206
227
  const start = Date.now();
207
228
  if (debug) {
208
229
  console.error(`[prolog debug] start query: ${goalLabel}`);
@@ -321,14 +342,26 @@ export class PrologProcess {
321
342
  releaseQuery();
322
343
  }
323
344
  }
345
+ /** Execute a group of goals as one transaction and one durable save. */
346
+ async queryBatch(goals) {
347
+ return this.query([...goals]);
348
+ }
324
349
  invalidateCache() {
325
350
  this.cache.clear();
326
351
  }
327
352
  isCacheableGoal(goal) {
328
353
  const trimmed = goal.trim();
354
+ if (trimmed.startsWith("rdf_transaction(") ||
355
+ this.isMutatingGoal(trimmed)) {
356
+ return false;
357
+ }
329
358
  return !(trimmed.startsWith("kb_attach(") ||
330
359
  trimmed.startsWith("kb_detach") ||
331
360
  trimmed.startsWith("kb_save") ||
361
+ trimmed.startsWith("kb_storage_status") ||
362
+ trimmed.startsWith("kb_storage_compact") ||
363
+ trimmed.startsWith("kb_storage_export") ||
364
+ trimmed.startsWith("status:") ||
332
365
  trimmed.startsWith("kb_commit_upsert(") ||
333
366
  trimmed.startsWith("kb_assert_") ||
334
367
  trimmed.startsWith("kb_delete_") ||
@@ -336,9 +369,7 @@ export class PrologProcess {
336
369
  }
337
370
  // implements REQ-009
338
371
  isMutatingGoal(goal) {
339
- return (goal.includes("kb_assert_") ||
340
- goal.includes("kb_delete_") ||
341
- goal.includes("kb_retract_"));
372
+ return /(?:kb_(?:assert|delete|retract|commit|save|log)_|\bkb_save\b|\brdf_(?:assert|retract))/u.test(goal);
342
373
  }
343
374
  // implements REQ-009
344
375
  isExplicitSaveGoal(goal) {
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-entities.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-entities.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,gFASrB,CAAC;AAGX,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAMtD;AAGD,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CA+B/D;AAGD,wBAAsB,YAAY,CAChC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CA0BpC;AAGD,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,CAAC,EAAE,CAEL;AAGD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAQ3B"}
1
+ {"version":3,"file":"discovery-entities.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-entities.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,gFASrB,CAAC;AAGX,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAMtD;AAGD,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAgC/D;AAGD,wBAAsB,YAAY,CAChC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CA0BpC;AAGD,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,CAAC,EAAE,CAEL;AAGD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAQ3B"}
@@ -36,11 +36,12 @@ export function buildEntityGoal(input) {
36
36
  return `findall(['${safeId}',Type,Props], kb_entity('${safeId}', Type, Props), Results)`;
37
37
  }
38
38
  if (tags && tags.length > 0) {
39
+ const tagTerms = tags.map((tag) => `'${escapeAtomContent(tag)}'`).join(",");
39
40
  if (type) {
40
41
  const safeType = escapeAtomContent(type);
41
- return `findall([Id,'${safeType}',Props], kb_entity(Id, '${safeType}', Props), Results)`;
42
+ return `findall([Id,'${safeType}',Props], (member(Tag, [${tagTerms}]), kb_entities_by_tag(Tag, TagIds), member(Id, TagIds), kb_entity(Id, '${safeType}', Props)), Results)`;
42
43
  }
43
- return "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)";
44
+ return `findall([Id,Type,Props], (member(Tag, [${tagTerms}]), kb_entities_by_tag(Tag, TagIds), member(Id, TagIds), kb_entity(Id, Type, Props)), Results)`;
44
45
  }
45
46
  if (type) {
46
47
  const safeType = escapeAtomContent(type);
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACjD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAC7C,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAChD,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAC9C,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CAC7C,CAAC;AAqBF,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CA+BxC;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAsCzC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAwCzC"}
1
+ {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACjD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAC7C,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAChD,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAC9C,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CAC7C,CAAC;AAqBF,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CA6DxC;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAiDzC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAwCzC"}
@@ -22,6 +22,32 @@ export async function executeQuery(input, context) {
22
22
  // implements REQ-kibi-operation-interface-parity
23
23
  const { type, id, tags, sourceFile, limit = 100, offset = 0 } = input;
24
24
  try {
25
+ const prolog = requireProlog(context);
26
+ const indexedPage = prolog.queryEntities
27
+ ? await prolog.queryEntities({
28
+ ...(type !== undefined ? { type } : {}),
29
+ ...(id !== undefined ? { id } : {}),
30
+ ...(tags !== undefined ? { tags } : {}),
31
+ ...(sourceFile !== undefined ? { sourceFile } : {}),
32
+ limit,
33
+ offset,
34
+ })
35
+ : null;
36
+ if (indexedPage !== null) {
37
+ const paginated = indexedPage.entities;
38
+ const text = indexedPage.count === 0
39
+ ? `No entities found${type ? ` of type '${type}'` : ""}.`
40
+ : `Found ${indexedPage.count} entities${type ? ` of type '${type}'` : ""}. Showing ${paginated.length} (offset ${offset}, limit ${limit}): ${paginated
41
+ .map((entity) => {
42
+ const entityId = String(entity.id ?? "").replace(/^file:\/\/.*\//, "");
43
+ return `${entityId} (${String(entity.title ?? "")}, status=${String(entity.status ?? "")})`;
44
+ })
45
+ .join(", ")}`;
46
+ return {
47
+ content: [{ type: "text", text }],
48
+ structuredContent: { entities: paginated, count: indexedPage.count },
49
+ };
50
+ }
25
51
  const entities = await loadEntities(requireProlog(context), {
26
52
  ...(type !== undefined ? { type } : {}),
27
53
  ...(id !== undefined ? { id } : {}),
@@ -56,9 +82,20 @@ export async function executeSearch(input, context) {
56
82
  }
57
83
  validateEntityType(type);
58
84
  try {
59
- const entities = await loadEntities(requireProlog(context), {
60
- ...(type !== undefined ? { type } : {}),
61
- });
85
+ const prolog = requireProlog(context);
86
+ const indexedCandidates = prolog.searchEntities
87
+ ? await prolog.searchEntities({
88
+ query: trimmedQuery,
89
+ ...(type !== undefined ? { type } : {}),
90
+ limit: 100_000,
91
+ offset: 0,
92
+ })
93
+ : null;
94
+ const entities = indexedCandidates
95
+ ? [...indexedCandidates.entities]
96
+ : await loadEntities(prolog, {
97
+ ...(type !== undefined ? { type } : {}),
98
+ });
62
99
  const matches = await rankEntities(entities, trimmedQuery, context.workspaceRoot);
63
100
  const paginated = paginateResults(matches, limit, offset);
64
101
  const text = matches.length === 0
@@ -1 +1 @@
1
- {"version":3,"file":"prolog-json.d.ts","sourceRoot":"","sources":["../../../src/public/operations/prolog-json.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUrD,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CAuBZ;AAiBD,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAI/D"}
1
+ {"version":3,"file":"prolog-json.d.ts","sourceRoot":"","sources":["../../../src/public/operations/prolog-json.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUrD,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAiBD,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAI/D"}
@@ -8,10 +8,20 @@ function resolveCoreModulePath(fileName) {
8
8
  }
9
9
  export async function runOperationJsonQuery(prolog, fileName, goal, errorLabel) {
10
10
  const modulePath = escapeAtom(resolveCoreModulePath(fileName).replaceAll("\\", "/"));
11
- const oneShotMode = typeof globalThis.Bun !== "undefined";
12
- const result = oneShotMode
13
- ? await prolog.query(`(use_module('${modulePath}'), ${goal})`)
14
- : await runInteractiveModuleQuery(prolog, modulePath, goal, errorLabel);
11
+ // Loading a module and invoking its predicate in one interactive goal makes
12
+ // SWI reject `use_module/1` under the engine's guarded `once/1` wrapper, so
13
+ // use two serialized requests for production and retain the combined goal
14
+ // only for the repository's Bun-based one-shot tests.
15
+ const longLivedEngine = typeof prolog.storageStatus === "function";
16
+ const oneShotMode = !longLivedEngine &&
17
+ process.env.NODE_ENV === "test" &&
18
+ typeof globalThis.Bun !== "undefined";
19
+ const typedStatusQuery = prolog.queryStatusJson;
20
+ const result = fileName === "status.pl" && typeof typedStatusQuery === "function"
21
+ ? await typedStatusQuery.call(prolog)
22
+ : oneShotMode
23
+ ? await prolog.query(`(use_module('${modulePath}'), ${goal})`)
24
+ : await runInteractiveModuleQuery(prolog, modulePath, goal, errorLabel);
15
25
  if (!result.success) {
16
26
  throw new Error(`${errorLabel} query failed: ${result.error ?? "Unknown error"}`);
17
27
  }
@@ -5,11 +5,42 @@ export type PrologQueryResult = {
5
5
  readonly bindings: Readonly<Record<string, string>>;
6
6
  readonly error?: string;
7
7
  };
8
+ export type PrologEntityQueryInput = Readonly<{
9
+ type?: string;
10
+ id?: string;
11
+ tags?: readonly string[];
12
+ sourceFile?: string;
13
+ limit: number;
14
+ offset: number;
15
+ }>;
16
+ export type PrologEntityQueryResult = Readonly<{
17
+ entities: readonly Record<string, unknown>[];
18
+ count: number;
19
+ }>;
20
+ export type PrologSearchQueryInput = Readonly<{
21
+ query: string;
22
+ type?: string;
23
+ /** Candidate bound before deterministic TypeScript ranking. */
24
+ limit: number;
25
+ offset: number;
26
+ }>;
27
+ export type PrologSearchQueryResult = Readonly<{
28
+ entities: readonly Record<string, unknown>[];
29
+ count: number;
30
+ }>;
8
31
  export interface PrologPort {
9
32
  query(goal: string): Promise<PrologQueryResult>;
33
+ /** Optional index-backed page query supplied by the journaled engine. */
34
+ queryEntities?(input: PrologEntityQueryInput): Promise<PrologEntityQueryResult>;
35
+ /** Optional normalized-token candidate lookup supplied by the engine. */
36
+ searchEntities?(input: PrologSearchQueryInput): Promise<PrologSearchQueryResult>;
10
37
  nextSolution(): Promise<PrologQueryResult | null>;
11
38
  invalidateCache?(): void;
12
39
  save(): Promise<PrologQueryResult>;
40
+ /** Present on the journaled engine; used to distinguish a persistent port from one-shot SWI. */
41
+ storageStatus?(): Promise<PrologQueryResult>;
42
+ /** Typed public freshness query; avoids exposing module loading over RPC. */
43
+ queryStatusJson?(): Promise<PrologQueryResult>;
13
44
  }
14
45
  export type FilesystemStat = {
15
46
  readonly isFile: () => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-types.d.ts","sourceRoot":"","sources":["../../../src/public/operations/runtime-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-types.d.ts","sourceRoot":"","sources":["../../../src/public/operations/runtime-types.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ Set up or refresh Kibi knowledge for the current branch through approved Kibi in
17
17
  ## Interface Selection
18
18
 
19
19
  1. If approved Kibi MCP tools are visible, use the MCP route.
20
- 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback: `npx --no-install kibi ...` or `bunx --no-install kibi ...`.
20
+ 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback: `npx --no-install kibi ...`.
21
21
  3. If neither approved MCP tools nor the project-local CLI are available, stop and tell the operator to enable or install Kibi for this workspace.
22
22
  4. Never use a global fallback, an installing runner, or any route outside the approved Kibi interface.
23
23
 
@@ -59,4 +59,4 @@ echo '{"maxCandidates":25,"minConfidence":0.8}' | npx --no-install kibi autopilo
59
59
 
60
60
  ```json
61
61
  [{"taskId":"init-kibi-bootstrap-analysis-train-1","family":"bootstrap-analysis","reflection":"Analyze the cold-start repository and produce a read-only bootstrap preview. This is train case 1; use only the public Kibi MCP surface."},{"taskId":"init-kibi-bootstrap-analysis-train-2","family":"bootstrap-analysis","reflection":"Analyze the cold-start repository and produce a read-only bootstrap preview. This is train case 2; use only the public Kibi MCP surface."},{"taskId":"init-kibi-bounded-context-questions-train-1","family":"bounded-context-questions","reflection":"Ask only the bounded context questions needed before bootstrap synthesis. This is train case 1; use only the public Kibi MCP surface."},{"taskId":"init-kibi-bounded-context-questions-train-2","family":"bounded-context-questions","reflection":"Ask only the bounded context questions needed before bootstrap synthesis. This is train case 2; use only the public Kibi MCP surface."},{"taskId":"init-kibi-approval-sequential-writes-train-1","family":"approval-sequential-writes","reflection":"Apply the approved bootstrap plan sequentially and finish with validation. This is train case 1; use only the public Kibi MCP surface."},{"taskId":"init-kibi-approval-sequential-writes-train-2","family":"approval-sequential-writes","reflection":"Apply the approved bootstrap plan sequentially and finish with validation. This is train case 2; use only the public Kibi MCP surface."},{"taskId":"init-kibi-repair-escalation-train-1","family":"repair-escalation","reflection":"Identify the partial setup and stop at the documented operator repair boundary. This is train case 1; use only the public Kibi MCP surface."},{"taskId":"init-kibi-repair-escalation-train-2","family":"repair-escalation","reflection":"Identify the partial setup and stop at the documented operator repair boundary. This is train case 2; use only the public Kibi MCP surface."}]
62
- ```
62
+ ```
@@ -17,7 +17,7 @@ Help agents decide whether Kibi knowledge is current enough to support safe chan
17
17
  ## Interface Selection
18
18
 
19
19
  1. If Kibi MCP tools are visible and approved for the workspace, use the MCP surface only.
20
- 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback through `npx --no-install kibi ...` or `bunx --no-install kibi ...`.
20
+ 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback through `npx --no-install kibi ...`.
21
21
  3. If the project-local CLI is unavailable or too old, stop and tell the operator to enable or install Kibi.
22
22
  4. Never use a global fallback or an installing runner.
23
23
 
@@ -41,4 +41,4 @@ echo '{}' | npx --no-install kibi status --input -
41
41
  - If entities look stale, refresh context through an approved Kibi capability and then re-query.
42
42
  - Preserve source-file traceability by carrying `sourceFile`, text references, and validation evidence through discovery, mutation, and completion.
43
43
  - Do not read or edit files inside `.kb` directly; use the selected Kibi interface instead.
44
- - Completion must state one freshness outcome: KB updated, no KB impact with rationale, or deferred/failed.
44
+ - Completion must state one freshness outcome: KB updated, no KB impact with rationale, or deferred/failed.
@@ -17,7 +17,7 @@ Validate and strengthen requirement, scenario, test, behavioral-symbol, and sour
17
17
  ## Interface Selection
18
18
 
19
19
  1. If Kibi MCP tools are visible and approved, use the MCP surface as the primary authority.
20
- 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback through `npx --no-install kibi ...` or `bunx --no-install kibi ...`.
20
+ 2. Otherwise, in a trusted workspace, use the canonical project-local CLI fallback through `npx --no-install kibi ...`.
21
21
  3. If neither approved MCP tools nor the project-local CLI are available, or if the CLI is unavailable or too old, stop and tell the operator to enable or install Kibi.
22
22
  4. Never use a global fallback or an installing runner.
23
23
 
@@ -27,7 +27,7 @@ Consult this skill before any Kibi knowledge base operation, on first interactio
27
27
  Kibi exposes two peer surfaces over the same 18 operations: visible MCP tools and the trusted project-local CLI. Both accept the same business input and effects (see `resources/operation-access.md`). Choose by what is visible and approved in the current environment — MCP and the CLI are equal choices, not a preference order:
28
28
 
29
29
  1. If Kibi MCP tools are visible and approved in the current environment, use MCP.
30
- 2. Otherwise, in a trusted workspace, use the project-local CLI through a non-installing runner: `npx --no-install kibi ...` or `bunx --no-install kibi ...`. The CLI is a peer interface, not a fallback.
30
+ 2. Otherwise, in a trusted workspace, use the project-local CLI through a non-installing runner: `npx --no-install kibi ...`. The CLI is a peer interface, not a fallback.
31
31
  3. If the project-local CLI is unavailable or too old for the needed route, stop and tell the operator to enable or install Kibi.
32
32
  4. Never use a global fallback or an installing runner. Never probe or install packages as a side effect of interface selection.
33
33
 
@@ -40,7 +40,7 @@ echo '{"type":"req","id":"REQ-001","properties":{"title":"Test","status":"open"}
40
40
  ```
41
41
 
42
42
  ```bash
43
- echo '{"query":"authentication","limit":10}' | bunx --no-install kibi search --input -
43
+ echo '{"query":"authentication","limit":10}' | npx --no-install kibi search --input -
44
44
  ```
45
45
 
46
46
  ## MCP Tool Names
@@ -36,7 +36,7 @@ echo '{"type":"req","id":"REQ-001","properties":{"title":"Test","status":"open"}
36
36
  ```
37
37
 
38
38
  ```bash
39
- echo '{"rules":["required-fields","no-dangling-refs"]}' | bunx --no-install kibi check --input -
39
+ echo '{"rules":["required-fields","no-dangling-refs"]}' | npx --no-install kibi check --input -
40
40
  ```
41
41
 
42
42
  ## Telemetry handling
@@ -1 +1 @@
1
- {"version":3,"file":"cli-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/cli-runtime.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,gBAAgB,EAGhB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAwC/C,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,cAAmB,GAC3B,gBAAgB,CAoElB"}
1
+ {"version":3,"file":"cli-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/cli-runtime.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,gBAAgB,EAEhB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAgC/C,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,cAAmB,GAC3B,gBAAgB,CA2ElB"}
@@ -1,24 +1,16 @@
1
1
  import path from "node:path";
2
- import { PrologProcess } from "../prolog.js";
2
+ import { EngineClient } from "../engine.js";
3
3
  import { nodeFilesystem, nodeGit, nodeNetwork, } from "../public/operations/node-ports.js";
4
4
  import { resolveActiveBranch } from "../utils/branch-resolver.js";
5
- function createDefaultProlog() {
6
- const process = new PrologProcess({ timeout: 120_000 });
7
- let lastResult = null;
8
- return {
9
- start: () => process.start(),
10
- query: async (goal) => {
11
- lastResult = await process.query(goal);
12
- return lastResult;
13
- },
14
- nextSolution: async () => {
15
- const result = lastResult;
16
- lastResult = null;
17
- return result;
18
- },
19
- save: () => process.query("kb_save"),
20
- terminate: () => process.terminate(),
21
- };
5
+ function createDefaultProlog(root, branch) {
6
+ const engine = new EngineClient({
7
+ workspaceRoot: root,
8
+ branch,
9
+ timeout: 120_000,
10
+ });
11
+ // Keep the concrete client so sync and operation runtimes can use its
12
+ // batched queue, storage controls, and cancellation-aware socket lifecycle.
13
+ return engine;
22
14
  }
23
15
  function workspaceRoot(options) {
24
16
  const envRoot = process.env.KIBI_WORKSPACE ??
@@ -53,30 +45,34 @@ export function createCliRuntime(options = {}) {
53
45
  if (!spec.requiresProlog) {
54
46
  return contextBase;
55
47
  }
56
- const prolog = merged.prolog ?? createDefaultProlog();
57
- try {
58
- await prolog.start?.();
59
- let branch = process.env.KIBI_BRANCH?.trim();
60
- if (!branch) {
61
- const resolved = resolveActiveBranch(root);
62
- if ("error" in resolved) {
63
- const isNonGitContext = resolved.code === "NOT_A_GIT_REPO" ||
64
- resolved.code === "GIT_NOT_AVAILABLE";
65
- if (isNonGitContext) {
66
- branch = "main";
67
- }
68
- else {
69
- throw new Error(`Failed to resolve active branch: ${resolved.error}`);
70
- }
48
+ let branch = process.env.KIBI_BRANCH?.trim();
49
+ if (!branch) {
50
+ const resolved = resolveActiveBranch(root);
51
+ if ("error" in resolved) {
52
+ const isNonGitContext = resolved.code === "NOT_A_GIT_REPO" ||
53
+ resolved.code === "GIT_NOT_AVAILABLE";
54
+ if (isNonGitContext) {
55
+ branch = "main";
71
56
  }
72
57
  else {
73
- branch = resolved.branch;
58
+ await merged.prolog?.terminate?.();
59
+ throw new Error(`Failed to resolve active branch: ${resolved.error}`);
74
60
  }
75
61
  }
62
+ else {
63
+ branch = resolved.branch;
64
+ }
65
+ }
66
+ const usesEngine = merged.prolog === undefined;
67
+ const prolog = merged.prolog ?? createDefaultProlog(root, branch);
68
+ try {
69
+ await prolog.start?.();
76
70
  const kbPath = path.join(root, ".kb", "branches", branch);
77
- const attached = await prolog.query(`kb_attach('${quoteProlog(kbPath)}')`);
78
- if (!attached.success) {
79
- throw new Error(attached.error ?? "Failed to attach branch KB");
71
+ if (!usesEngine) {
72
+ const attached = await prolog.query(`kb_attach('${quoteProlog(kbPath)}')`);
73
+ if (!attached.success) {
74
+ throw new Error(attached.error ?? "Failed to attach branch KB");
75
+ }
80
76
  }
81
77
  const context = { ...contextBase, prolog };
82
78
  ownedPrologs.set(context, prolog);
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
7
- "node": ">=18",
8
- "bun": ">=1.0"
7
+ "node": ">=18"
9
8
  },
10
9
  "main": "./dist/cli.js",
11
10
  "bin": {
@@ -14,6 +13,7 @@
14
13
  "files": ["dist", "bin", "schema", "src/schemas", "src/public"],
15
14
  "scripts": {
16
15
  "build": "tsc -p tsconfig.json && mkdir -p dist/public/skills && cp -r src/public/skills/. dist/public/skills/",
16
+ "test": "node ../../scripts/run-owned-engine-tests.mjs -- bun test --timeout 15000 .",
17
17
  "typecheck": "tsc -p tsconfig.json --noEmit",
18
18
  "prepack": "npm run build"
19
19
  },
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/prolog/codec.d.ts",
31
31
  "default": "./dist/prolog/codec.js"
32
32
  },
33
+ "./engine": {
34
+ "types": "./dist/engine.d.ts",
35
+ "default": "./dist/engine.js"
36
+ },
33
37
  "./operations/runtime-types": {
34
38
  "types": "./dist/public/operations/runtime-types.d.ts",
35
39
  "default": "./dist/public/operations/runtime-types.js"
@@ -189,7 +193,7 @@
189
193
  "fast-glob": "^3.2.12",
190
194
  "gray-matter": "^4.0.3",
191
195
  "js-yaml": "^4.1.0",
192
- "kibi-core": "^0.9.1",
196
+ "kibi-core": "^0.10.0",
193
197
  "ts-morph": "^23.0.0",
194
198
  "ignore": "^5.3.0"
195
199
  },
@@ -54,11 +54,12 @@ export function buildEntityGoal(input: EntityQueryInput): string {
54
54
  return `findall(['${safeId}',Type,Props], kb_entity('${safeId}', Type, Props), Results)`;
55
55
  }
56
56
  if (tags && tags.length > 0) {
57
+ const tagTerms = tags.map((tag) => `'${escapeAtomContent(tag)}'`).join(",");
57
58
  if (type) {
58
59
  const safeType = escapeAtomContent(type);
59
- return `findall([Id,'${safeType}',Props], kb_entity(Id, '${safeType}', Props), Results)`;
60
+ return `findall([Id,'${safeType}',Props], (member(Tag, [${tagTerms}]), kb_entities_by_tag(Tag, TagIds), member(Id, TagIds), kb_entity(Id, '${safeType}', Props)), Results)`;
60
61
  }
61
- return "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)";
62
+ return `findall([Id,Type,Props], (member(Tag, [${tagTerms}]), kb_entities_by_tag(Tag, TagIds), member(Id, TagIds), kb_entity(Id, Type, Props)), Results)`;
62
63
  }
63
64
  if (type) {
64
65
  const safeType = escapeAtomContent(type);