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.
- package/dist/cli-json-command.d.ts +1 -2
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +2 -34
- package/dist/cli-operation-loader.d.ts +3 -0
- package/dist/cli-operation-loader.d.ts.map +1 -0
- package/dist/cli-operation-loader.js +58 -0
- package/dist/cli-operation-metadata.d.ts +82 -0
- package/dist/cli-operation-metadata.d.ts.map +1 -0
- package/dist/cli-operation-metadata.js +106 -0
- package/dist/cli-protocol.d.ts +1 -1
- package/dist/cli-protocol.d.ts.map +1 -1
- package/dist/cli-protocol.js +4 -3
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +14 -17
- package/dist/cli-register-json.d.ts +3 -0
- package/dist/cli-register-json.d.ts.map +1 -0
- package/dist/cli-register-json.js +35 -0
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +35 -10
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +13 -14
- package/dist/cli-register-skills.d.ts.map +1 -1
- package/dist/cli-register-skills.js +8 -6
- package/dist/cli.js +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +30 -12
- package/dist/commands/coverage.js +1 -1
- package/dist/commands/discovery-shared.d.ts +2 -1
- package/dist/commands/discovery-shared.d.ts.map +1 -1
- package/dist/commands/discovery-shared.js +35 -13
- package/dist/commands/engine.d.ts +8 -0
- package/dist/commands/engine.d.ts.map +1 -0
- package/dist/commands/engine.js +100 -0
- package/dist/commands/gaps.js +1 -1
- package/dist/commands/graph.js +1 -1
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +3 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +3 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +2 -1
- package/dist/commands/sync/cache.d.ts +10 -0
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +30 -1
- package/dist/commands/sync/persistence.d.ts +10 -1
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +220 -44
- package/dist/commands/sync/staging.d.ts +10 -1
- package/dist/commands/sync/staging.d.ts.map +1 -1
- package/dist/commands/sync/staging.js +84 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +450 -13
- package/dist/engine-daemon.d.ts +3 -0
- package/dist/engine-daemon.d.ts.map +1 -0
- package/dist/engine-daemon.js +34 -0
- package/dist/engine.d.ts +63 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1256 -0
- package/dist/extractors/relationships.d.ts +2 -0
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +15 -17
- package/dist/prolog.d.ts +8 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +39 -8
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +3 -2
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +40 -3
- package/dist/public/operations/prolog-json.d.ts.map +1 -1
- package/dist/public/operations/prolog-json.js +14 -4
- package/dist/public/operations/runtime-types.d.ts +31 -0
- package/dist/public/operations/runtime-types.d.ts.map +1 -1
- package/dist/public/skills/init-kibi/SKILL.md +2 -2
- package/dist/public/skills/kibi-freshness/SKILL.md +2 -2
- package/dist/public/skills/kibi-traceability/SKILL.md +1 -1
- package/dist/public/skills/kibi-usage/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -1
- package/dist/runtime/cli-runtime.d.ts.map +1 -1
- package/dist/runtime/cli-runtime.js +33 -37
- package/package.json +8 -4
- package/src/public/operations/discovery-entities.ts +3 -2
- package/src/public/operations/discovery-executors.ts +44 -3
- package/src/public/operations/prolog-json.ts +15 -3
- package/src/public/operations/runtime-types.ts +39 -0
- package/src/public/skills/init-kibi/SKILL.md +2 -2
- package/src/public/skills/kibi-freshness/SKILL.md +2 -2
- package/src/public/skills/kibi-traceability/SKILL.md +1 -1
- package/src/public/skills/kibi-usage/SKILL.md +2 -2
- 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,
|
|
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
|
-
|
|
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;
|
package/dist/prolog.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
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
|
-
|
|
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
|
|
204
|
-
|
|
205
|
-
|
|
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 (
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
60
|
-
|
|
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,
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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}' |
|
|
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"]}' |
|
|
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,
|
|
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 {
|
|
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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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);
|