kibi-cli 0.2.6 → 0.2.8
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/commands/aggregated-checks.js +4 -6
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +55 -30
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +46 -28
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +19 -26
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +0 -2
- package/dist/extractors/manifest.d.ts +2 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +1 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +9 -1
- package/dist/prolog.d.ts +2 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +45 -12
- package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/public/extractors/symbols-coordinator.js +1 -2
- package/dist/public/prolog/index.d.ts.map +1 -1
- package/dist/public/prolog/index.js +1 -2
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +1 -3
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -3
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +33 -7
- package/dist/traceability/symbol-extract.d.ts +6 -1
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +62 -34
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +4 -3
- package/dist/traceability/validate.d.ts.map +1 -1
- package/dist/traceability/validate.js +8 -7
- package/package.json +5 -1
- package/src/public/extractors/symbols-coordinator.ts +1 -2
- package/src/public/prolog/index.ts +1 -2
- package/src/public/schemas/entity.ts +1 -3
- package/src/public/schemas/relationship.ts +1 -3
|
@@ -23,8 +23,7 @@ export async function runAggregatedChecks(prolog, rulesAllowlist, requireAdr = f
|
|
|
23
23
|
try {
|
|
24
24
|
const result = await prolog.query(query);
|
|
25
25
|
if (!result.success) {
|
|
26
|
-
|
|
27
|
-
return [];
|
|
26
|
+
throw new Error(`Aggregated checks query failed: ${result.error || "Unknown error"}`);
|
|
28
27
|
}
|
|
29
28
|
let violationsDict;
|
|
30
29
|
try {
|
|
@@ -39,8 +38,7 @@ export async function runAggregatedChecks(prolog, rulesAllowlist, requireAdr = f
|
|
|
39
38
|
violationsDict = parsed;
|
|
40
39
|
}
|
|
41
40
|
catch (parseError) {
|
|
42
|
-
|
|
43
|
-
return [];
|
|
41
|
+
throw new Error(`Failed to parse violations JSON: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
44
42
|
}
|
|
45
43
|
for (const ruleViolations of Object.values(violationsDict)) {
|
|
46
44
|
for (const v of ruleViolations) {
|
|
@@ -59,7 +57,7 @@ export async function runAggregatedChecks(prolog, rulesAllowlist, requireAdr = f
|
|
|
59
57
|
return violations;
|
|
60
58
|
}
|
|
61
59
|
catch (error) {
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
61
|
+
throw new Error(`Error running aggregated checks: ${message}`);
|
|
64
62
|
}
|
|
65
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAgDA,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;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+RvE"}
|
package/dist/commands/check.js
CHANGED
|
@@ -16,21 +16,24 @@
|
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
import * as path from "node:path";
|
|
19
|
+
import { extractFromManifest } from "../extractors/manifest.js";
|
|
19
20
|
import { PrologProcess } from "../prolog.js";
|
|
20
21
|
import { escapeAtom } from "../prolog/codec.js";
|
|
21
22
|
import { getStagedFiles } from "../traceability/git-staged.js";
|
|
22
23
|
import { validateStagedMarkdown } from "../traceability/markdown-validate.js";
|
|
23
|
-
import { extractSymbolsFromStagedFile } from "../traceability/symbol-extract.js";
|
|
24
|
+
import { extractSymbolsFromStagedFile, } from "../traceability/symbol-extract.js";
|
|
24
25
|
import { cleanupTempKb, consultOverlay, createOverlayFacts, createTempKb, } from "../traceability/temp-kb.js";
|
|
25
26
|
import { formatViolations as formatStagedViolations, validateStagedSymbols, } from "../traceability/validate.js";
|
|
26
27
|
import { loadConfig } from "../utils/config.js";
|
|
27
28
|
import { RULES, getEffectiveRules, } from "../utils/rule-registry.js";
|
|
28
29
|
import { runAggregatedChecks } from "./aggregated-checks.js";
|
|
29
30
|
import { getCurrentBranch } from "./init-helpers.js";
|
|
31
|
+
import { discoverSourceFiles } from "./sync/discovery.js";
|
|
32
|
+
// implements REQ-006
|
|
30
33
|
export async function checkCommand(options) {
|
|
34
|
+
let prolog = null;
|
|
35
|
+
let attached = false;
|
|
31
36
|
try {
|
|
32
|
-
// Resolve KB path with priority:
|
|
33
|
-
// --kb-path > git branch --show-current > KIBI_BRANCH env > develop > main
|
|
34
37
|
let resolvedKbPath = "";
|
|
35
38
|
if (options.kbPath) {
|
|
36
39
|
resolvedKbPath = options.kbPath;
|
|
@@ -51,13 +54,32 @@ export async function checkCommand(options) {
|
|
|
51
54
|
// fallback to main if develop isn't present? keep path consistent
|
|
52
55
|
resolvedKbPath = path.join(process.cwd(), ".kb/branches", branch || "main");
|
|
53
56
|
}
|
|
54
|
-
// If --staged mode requested, run staged-symbol traceability gate.
|
|
55
|
-
// We skip creating the main prolog session entirely in this path.
|
|
56
57
|
if (options.staged) {
|
|
57
58
|
const minLinks = options.minLinks ? Number(options.minLinks) : 1;
|
|
58
59
|
let tempCtx = null;
|
|
59
60
|
try {
|
|
60
|
-
|
|
61
|
+
const config = loadConfig(process.cwd());
|
|
62
|
+
const manifestLookup = new Map();
|
|
63
|
+
const { manifestFiles } = await discoverSourceFiles(process.cwd(), config.paths);
|
|
64
|
+
for (const manifestPath of manifestFiles) {
|
|
65
|
+
try {
|
|
66
|
+
const entries = extractFromManifest(manifestPath);
|
|
67
|
+
for (const entry of entries) {
|
|
68
|
+
// Prefer the per-symbol sourceFile; fall back to entity.source or manifest path
|
|
69
|
+
const sourceFile = entry.sourceFile || entry.entity.source || manifestPath;
|
|
70
|
+
const key = `${sourceFile}:${entry.entity.title}`;
|
|
71
|
+
// Extract requirement links (implements relationships to REQ-*)
|
|
72
|
+
const links = entry.relationships
|
|
73
|
+
.filter((r) => r.type === "implements" &&
|
|
74
|
+
r.to.match(/^[A-Z][A-Z0-9\-_]*$/))
|
|
75
|
+
.map((r) => r.to);
|
|
76
|
+
manifestLookup.set(key, { id: entry.entity.id, links });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Ignore manifest parsing errors
|
|
81
|
+
}
|
|
82
|
+
}
|
|
61
83
|
const stagedFiles = getStagedFiles();
|
|
62
84
|
if (!stagedFiles || stagedFiles.length === 0) {
|
|
63
85
|
console.log("No staged files found.");
|
|
@@ -86,7 +108,7 @@ export async function checkCommand(options) {
|
|
|
86
108
|
const allSymbols = [];
|
|
87
109
|
for (const f of codeFiles) {
|
|
88
110
|
try {
|
|
89
|
-
const symbols = extractSymbolsFromStagedFile(f);
|
|
111
|
+
const symbols = extractSymbolsFromStagedFile(f, manifestLookup);
|
|
90
112
|
if (symbols?.length) {
|
|
91
113
|
allSymbols.push(...symbols);
|
|
92
114
|
}
|
|
@@ -105,12 +127,10 @@ export async function checkCommand(options) {
|
|
|
105
127
|
}
|
|
106
128
|
// Create temp KB
|
|
107
129
|
tempCtx = await createTempKb(resolvedKbPath);
|
|
108
|
-
// Write overlay facts THEN consult so Prolog sees the changed_symbol facts
|
|
109
130
|
const overlayFacts = createOverlayFacts(allSymbols);
|
|
110
131
|
const fs = await import("node:fs/promises");
|
|
111
132
|
await fs.writeFile(tempCtx.overlayPath, overlayFacts, "utf8");
|
|
112
133
|
await consultOverlay(tempCtx);
|
|
113
|
-
// Validate staged symbols using the temp KB prolog session
|
|
114
134
|
const violationsRaw = await validateStagedSymbols({
|
|
115
135
|
minLinks,
|
|
116
136
|
prolog: tempCtx.prolog,
|
|
@@ -139,7 +159,7 @@ export async function checkCommand(options) {
|
|
|
139
159
|
process.exit(1);
|
|
140
160
|
}
|
|
141
161
|
}
|
|
142
|
-
|
|
162
|
+
prolog = new PrologProcess({ timeout: 120000 });
|
|
143
163
|
await prolog.start();
|
|
144
164
|
const kbPathEscaped = escapeAtom(resolvedKbPath);
|
|
145
165
|
const attachResult = await prolog.query(`kb_attach('${kbPathEscaped}')`);
|
|
@@ -148,23 +168,29 @@ export async function checkCommand(options) {
|
|
|
148
168
|
console.error(`Error: Failed to attach KB: ${attachResult.error}`);
|
|
149
169
|
process.exit(1);
|
|
150
170
|
}
|
|
171
|
+
attached = true;
|
|
151
172
|
const violations = [];
|
|
152
|
-
// Load config to get rule enablement settings
|
|
153
173
|
const config = loadConfig(process.cwd());
|
|
154
174
|
const checksConfig = config.checks ?? {
|
|
155
175
|
rules: Object.fromEntries(RULES.map((r) => [r.name, true])),
|
|
156
176
|
symbolTraceability: { requireAdr: false },
|
|
157
177
|
};
|
|
158
|
-
// Get effective rules based on config and CLI --rules filter
|
|
159
178
|
const effectiveRules = getEffectiveRules(checksConfig.rules, options.rules);
|
|
160
179
|
// Helper to conditionally run a check by name
|
|
161
180
|
async function runCheck(name, fn, ...args) {
|
|
162
181
|
if (!effectiveRules.has(name))
|
|
163
182
|
return;
|
|
183
|
+
if (!prolog) {
|
|
184
|
+
throw new Error("Prolog process not initialized");
|
|
185
|
+
}
|
|
164
186
|
const res = await fn(prolog, ...args);
|
|
165
187
|
if (res?.length)
|
|
166
188
|
violations.push(...res);
|
|
167
189
|
}
|
|
190
|
+
if (!prolog) {
|
|
191
|
+
throw new Error("Prolog process not initialized");
|
|
192
|
+
}
|
|
193
|
+
const activeProlog = prolog;
|
|
168
194
|
// Use aggregated checks (single Prolog call) when possible for better performance
|
|
169
195
|
// This is significantly faster in Bun/Docker environments where one-shot mode
|
|
170
196
|
// spawns a new Prolog process for each query
|
|
@@ -182,7 +208,7 @@ export async function checkCommand(options) {
|
|
|
182
208
|
if (canUseAggregated) {
|
|
183
209
|
// Fast path: single Prolog call returning all violations
|
|
184
210
|
// Pass the requireAdr option for symbol-traceability
|
|
185
|
-
const aggregatedViolations = await runAggregatedChecks(
|
|
211
|
+
const aggregatedViolations = await runAggregatedChecks(activeProlog, effectiveRules, checksConfig.symbolTraceability?.requireAdr ?? false);
|
|
186
212
|
violations.push(...aggregatedViolations);
|
|
187
213
|
}
|
|
188
214
|
else {
|
|
@@ -192,16 +218,14 @@ export async function checkCommand(options) {
|
|
|
192
218
|
await runCheck("symbol-traceability", (p) => checkSymbolTraceability(p, checksConfig.symbolTraceability?.requireAdr ?? false));
|
|
193
219
|
await runCheck("no-dangling-refs", checkNoDanglingRefs);
|
|
194
220
|
await runCheck("no-cycles", checkNoCycles);
|
|
195
|
-
const allEntityIds = await getAllEntityIds(
|
|
221
|
+
const allEntityIds = await getAllEntityIds(activeProlog);
|
|
196
222
|
if (effectiveRules.has("required-fields")) {
|
|
197
|
-
const requiredViolations = await checkRequiredFields(
|
|
223
|
+
const requiredViolations = await checkRequiredFields(activeProlog, allEntityIds);
|
|
198
224
|
violations.push(...requiredViolations);
|
|
199
225
|
}
|
|
200
226
|
await runCheck("deprecated-adr-no-successor", checkDeprecatedAdrs);
|
|
201
227
|
await runCheck("domain-contradictions", checkDomainContradictions);
|
|
202
228
|
}
|
|
203
|
-
await prolog.query("kb_detach");
|
|
204
|
-
await prolog.terminate();
|
|
205
229
|
if (violations.length === 0) {
|
|
206
230
|
console.log("✓ No violations found. KB is valid.");
|
|
207
231
|
process.exit(0);
|
|
@@ -224,10 +248,23 @@ export async function checkCommand(options) {
|
|
|
224
248
|
console.error(`Error: ${message}`);
|
|
225
249
|
process.exit(1);
|
|
226
250
|
}
|
|
251
|
+
finally {
|
|
252
|
+
if (prolog) {
|
|
253
|
+
if (attached) {
|
|
254
|
+
try {
|
|
255
|
+
await prolog.query("kb_detach");
|
|
256
|
+
}
|
|
257
|
+
catch { }
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
await prolog.terminate();
|
|
261
|
+
}
|
|
262
|
+
catch { }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
227
265
|
}
|
|
228
266
|
async function checkMustPriorityCoverage(prolog) {
|
|
229
267
|
const violations = [];
|
|
230
|
-
// Find all must-priority requirements
|
|
231
268
|
const mustReqs = await findMustPriorityReqs(prolog);
|
|
232
269
|
for (const reqId of mustReqs) {
|
|
233
270
|
const entityResult = await prolog.query(`kb_entity('${reqId}', req, Props)`);
|
|
@@ -301,9 +338,7 @@ async function getAllEntityIds(prolog, type) {
|
|
|
301
338
|
}
|
|
302
339
|
async function checkNoDanglingRefs(prolog) {
|
|
303
340
|
const violations = [];
|
|
304
|
-
// Get all entity IDs once
|
|
305
341
|
const allEntityIds = new Set(await getAllEntityIds(prolog));
|
|
306
|
-
// Get all relationships by querying all known relationship types
|
|
307
342
|
const relTypes = [
|
|
308
343
|
"depends_on",
|
|
309
344
|
"verified_by",
|
|
@@ -356,7 +391,6 @@ async function checkNoDanglingRefs(prolog) {
|
|
|
356
391
|
}
|
|
357
392
|
async function checkNoCycles(prolog) {
|
|
358
393
|
const violations = [];
|
|
359
|
-
// Get all depends_on relationships
|
|
360
394
|
const depsResult = await prolog.query("findall([From,To], kb_relationship(depends_on, From, To), Deps)");
|
|
361
395
|
if (!depsResult.success || !depsResult.bindings.Deps) {
|
|
362
396
|
return violations;
|
|
@@ -370,7 +404,6 @@ async function checkNoCycles(prolog) {
|
|
|
370
404
|
if (!content) {
|
|
371
405
|
return violations;
|
|
372
406
|
}
|
|
373
|
-
// Build adjacency map
|
|
374
407
|
const graph = new Map();
|
|
375
408
|
const depMatches = content.matchAll(/\[([^,]+),([^\]]+)\]/g);
|
|
376
409
|
for (const depMatch of depMatches) {
|
|
@@ -384,7 +417,6 @@ async function checkNoCycles(prolog) {
|
|
|
384
417
|
fromList.push(to);
|
|
385
418
|
}
|
|
386
419
|
}
|
|
387
|
-
// DFS to detect cycles
|
|
388
420
|
const visited = new Set();
|
|
389
421
|
const recStack = new Set();
|
|
390
422
|
function hasCycleDFS(node, path) {
|
|
@@ -406,7 +438,6 @@ async function checkNoCycles(prolog) {
|
|
|
406
438
|
recStack.delete(node);
|
|
407
439
|
return null;
|
|
408
440
|
}
|
|
409
|
-
// Check each node for cycles
|
|
410
441
|
for (const node of graph.keys()) {
|
|
411
442
|
if (!visited.has(node)) {
|
|
412
443
|
const cyclePath = hasCycleDFS(node, []);
|
|
@@ -449,15 +480,12 @@ async function checkRequiredFields(prolog, allEntityIds) {
|
|
|
449
480
|
for (const entityId of allEntityIds) {
|
|
450
481
|
const result = await prolog.query(`kb_entity('${entityId}', Type, Props)`);
|
|
451
482
|
if (result.success && result.bindings.Props) {
|
|
452
|
-
// Parse properties list: [key1=value1, key2=value2, ...]
|
|
453
483
|
const propsStr = result.bindings.Props;
|
|
454
484
|
const propKeys = new Set();
|
|
455
|
-
// Extract keys from Props
|
|
456
485
|
const keyMatches = propsStr.matchAll(/(\w+)\s*=/g);
|
|
457
486
|
for (const match of keyMatches) {
|
|
458
487
|
propKeys.add(match[1]);
|
|
459
488
|
}
|
|
460
|
-
// Check for missing required fields
|
|
461
489
|
for (const field of required) {
|
|
462
490
|
if (!propKeys.has(field)) {
|
|
463
491
|
violations.push({
|
|
@@ -492,7 +520,6 @@ async function checkDeprecatedAdrs(prolog) {
|
|
|
492
520
|
.split(",")
|
|
493
521
|
.map((id) => id.trim().replace(/^'|'$/g, ""));
|
|
494
522
|
for (const adrId of adrIds) {
|
|
495
|
-
// Get source for better error message
|
|
496
523
|
const entityResult = await prolog.query(`kb_entity('${adrId}', adr, Props)`);
|
|
497
524
|
let source = "";
|
|
498
525
|
if (entityResult.success && entityResult.bindings.Props) {
|
|
@@ -562,10 +589,8 @@ async function checkSymbolTraceability(prolog, requireAdr) {
|
|
|
562
589
|
if (!result.success || !result.bindings.Violations) {
|
|
563
590
|
return violations;
|
|
564
591
|
}
|
|
565
|
-
// Parse the violations from Prolog format
|
|
566
592
|
const violationsStr = result.bindings.Violations;
|
|
567
593
|
if (violationsStr && violationsStr !== "[]") {
|
|
568
|
-
// Parse each violation term
|
|
569
594
|
const violationRegex = /violation\(([^,]+),'?([^',]+)'?,([^,]+),([^,]+),'?([^']*)'?\)/g;
|
|
570
595
|
let match;
|
|
571
596
|
do {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AA2CA,UAAU,YAAY;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAyKf"}
|
package/dist/commands/query.js
CHANGED
|
@@ -23,12 +23,14 @@ import relationshipSchema from "../public/schemas/relationship.js";
|
|
|
23
23
|
import { VALID_ENTITY_TYPES } from "../query/service.js";
|
|
24
24
|
import { resolveActiveBranch } from "../utils/branch-resolver.js";
|
|
25
25
|
const REL_TYPES = relationshipSchema.properties.type.enum;
|
|
26
|
+
// implements REQ-003
|
|
26
27
|
export async function queryCommand(type, options) {
|
|
28
|
+
let prolog = null;
|
|
29
|
+
let attached = false;
|
|
27
30
|
try {
|
|
28
|
-
|
|
31
|
+
prolog = new PrologProcess({ timeout: 120000 });
|
|
29
32
|
await prolog.start();
|
|
30
33
|
await prolog.query("set_prolog_flag(answer_write_options, [max_depth(0), spacing(next_argument)])");
|
|
31
|
-
// Resolve branch: allow non-git repos to use default "main" for query
|
|
32
34
|
let currentBranch;
|
|
33
35
|
const branchResult = resolveActiveBranch();
|
|
34
36
|
if ("error" in branchResult) {
|
|
@@ -56,13 +58,13 @@ export async function queryCommand(type, options) {
|
|
|
56
58
|
console.error(`Error: Failed to attach KB: ${attachResult.error || "Unknown error"}`);
|
|
57
59
|
process.exit(1);
|
|
58
60
|
}
|
|
61
|
+
attached = true;
|
|
59
62
|
let results = [];
|
|
60
|
-
// Query relationships mode
|
|
61
63
|
if (options.relationships) {
|
|
62
64
|
const fromId = String(options.relationships);
|
|
63
65
|
const safeFromId = fromId.replace(/'/g, "''");
|
|
64
|
-
|
|
65
|
-
const goal = `findall([Type,From,To], (
|
|
66
|
+
const relTypesList = REL_TYPES.join(", ");
|
|
67
|
+
const goal = `findall([Type,From,To], (member(Type, [${relTypesList}]), kb_relationship(Type, '${safeFromId}', To), From='${safeFromId}'), Results)`;
|
|
66
68
|
const queryResult = await prolog.query(goal);
|
|
67
69
|
if (queryResult.success && queryResult.bindings.Results) {
|
|
68
70
|
const rows = parseListOfLists(queryResult.bindings.Results);
|
|
@@ -81,18 +83,14 @@ export async function queryCommand(type, options) {
|
|
|
81
83
|
REL_TYPES.includes(rel.type));
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
|
-
// Query entities mode
|
|
85
86
|
else if (type || options.source) {
|
|
86
|
-
// Validate type if provided
|
|
87
87
|
if (type && !VALID_ENTITY_TYPES.includes(type)) {
|
|
88
|
-
await prolog.query("kb_detach");
|
|
89
|
-
await prolog.terminate();
|
|
90
88
|
console.error(`Error: Invalid type '${type}'. Valid types: ${VALID_ENTITY_TYPES.join(", ")}`);
|
|
91
|
-
process.
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
92
91
|
}
|
|
93
92
|
let goal;
|
|
94
93
|
if (options.source) {
|
|
95
|
-
// Query by source path (substring match)
|
|
96
94
|
const safeSource = String(options.source).replace(/'/g, "\\'");
|
|
97
95
|
if (type) {
|
|
98
96
|
goal = `findall([Id,'${type}',Props], (kb_entities_by_source('${safeSource}', SourceIds), member(Id, SourceIds), kb_entity(Id, '${type}', Props)), Results)`;
|
|
@@ -134,14 +132,10 @@ export async function queryCommand(type, options) {
|
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
134
|
else {
|
|
137
|
-
await prolog.query("kb_detach");
|
|
138
|
-
await prolog.terminate();
|
|
139
135
|
console.error("Error: Must specify entity type, --source, or --relationships option");
|
|
140
|
-
process.
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
return;
|
|
141
138
|
}
|
|
142
|
-
await prolog.query("kb_detach");
|
|
143
|
-
await prolog.terminate();
|
|
144
|
-
// Apply pagination
|
|
145
139
|
const limit = Number.parseInt(options.limit || "100");
|
|
146
140
|
const offset = Number.parseInt(options.offset || "0");
|
|
147
141
|
const paginated = results.slice(offset, offset + limit);
|
|
@@ -152,7 +146,7 @@ export async function queryCommand(type, options) {
|
|
|
152
146
|
else {
|
|
153
147
|
console.log("No entities found");
|
|
154
148
|
}
|
|
155
|
-
|
|
149
|
+
return;
|
|
156
150
|
}
|
|
157
151
|
// Format output
|
|
158
152
|
if (options.format === "table") {
|
|
@@ -161,12 +155,25 @@ export async function queryCommand(type, options) {
|
|
|
161
155
|
else {
|
|
162
156
|
console.log(JSON.stringify(paginated, null, 2));
|
|
163
157
|
}
|
|
164
|
-
process.exit(0);
|
|
165
158
|
}
|
|
166
159
|
catch (error) {
|
|
167
160
|
const message = error instanceof Error ? error.message : String(error);
|
|
168
161
|
console.error(`Error: ${message}`);
|
|
169
|
-
process.
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
if (prolog) {
|
|
166
|
+
if (attached) {
|
|
167
|
+
try {
|
|
168
|
+
await prolog.query("kb_detach");
|
|
169
|
+
}
|
|
170
|
+
catch { }
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
await prolog.terminate();
|
|
174
|
+
}
|
|
175
|
+
catch { }
|
|
176
|
+
}
|
|
170
177
|
}
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
@@ -183,10 +190,11 @@ function outputTable(items, isRelationships) {
|
|
|
183
190
|
colWidths: [20, 18, 18],
|
|
184
191
|
});
|
|
185
192
|
for (const item of items) {
|
|
193
|
+
const rel = item;
|
|
186
194
|
table.push([
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
195
|
+
rel.type || "N/A",
|
|
196
|
+
rel.from.substring(0, 16) || "N/A",
|
|
197
|
+
rel.to.substring(0, 16) || "N/A",
|
|
190
198
|
]);
|
|
191
199
|
}
|
|
192
200
|
console.log(table.toString());
|
|
@@ -197,12 +205,22 @@ function outputTable(items, isRelationships) {
|
|
|
197
205
|
colWidths: [18, 10, 40, 12, 30],
|
|
198
206
|
});
|
|
199
207
|
for (const entity of items) {
|
|
208
|
+
const record = entity;
|
|
209
|
+
const id = typeof record.id === "string" ? record.id : "N/A";
|
|
210
|
+
const entityType = typeof record.type === "string" ? record.type : "N/A";
|
|
211
|
+
const title = typeof record.title === "string" ? record.title : "N/A";
|
|
212
|
+
const status = typeof record.status === "string" ? record.status : "N/A";
|
|
213
|
+
const tags = Array.isArray(record.tags)
|
|
214
|
+
? record.tags
|
|
215
|
+
.filter((tag) => typeof tag === "string")
|
|
216
|
+
.join(", ")
|
|
217
|
+
: "";
|
|
200
218
|
table.push([
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
219
|
+
id.substring(0, 16),
|
|
220
|
+
entityType,
|
|
221
|
+
title.substring(0, 38),
|
|
222
|
+
status,
|
|
223
|
+
tags.substring(0, 28),
|
|
206
224
|
]);
|
|
207
225
|
}
|
|
208
226
|
console.log(table.toString());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAyCjE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAyCjE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACd,GACL,OAAO,CAAC,WAAW,CAAC,CA4VtB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -35,6 +35,7 @@ export class SyncError extends Error {
|
|
|
35
35
|
this.name = "SyncError";
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
// implements REQ-003, REQ-007
|
|
38
39
|
export async function syncCommand(options = {}) {
|
|
39
40
|
const validateOnly = options.validateOnly ?? false;
|
|
40
41
|
const rebuild = options.rebuild ?? false;
|
|
@@ -73,10 +74,8 @@ export async function syncCommand(options = {}) {
|
|
|
73
74
|
}
|
|
74
75
|
catch { }
|
|
75
76
|
}
|
|
76
|
-
// Load config
|
|
77
77
|
const config = loadSyncConfig(process.cwd());
|
|
78
78
|
const paths = config.paths;
|
|
79
|
-
// File discovery
|
|
80
79
|
const { markdownFiles, manifestFiles, relationshipsDir } = await discoverSourceFiles(process.cwd(), paths);
|
|
81
80
|
if (process.env.KIBI_DEBUG) {
|
|
82
81
|
try {
|
|
@@ -94,21 +93,19 @@ export async function syncCommand(options = {}) {
|
|
|
94
93
|
const nowMs = Date.now();
|
|
95
94
|
const nextHashes = {};
|
|
96
95
|
const nextSeenAt = {};
|
|
97
|
-
// Extract relationships from shard files
|
|
98
96
|
const shardResults = extractFromRelationshipShards(relationshipsDir);
|
|
99
97
|
const allRelationships = flattenRelationships(shardResults);
|
|
100
98
|
const changedMarkdownFiles = [];
|
|
101
99
|
const changedManifestFiles = [];
|
|
102
|
-
// Detect changed files
|
|
103
100
|
for (const file of sourceFiles) {
|
|
104
101
|
try {
|
|
105
102
|
const key = toCacheKey(file);
|
|
106
103
|
const hash = hashFile(file);
|
|
107
104
|
const lastSeen = syncCache.seenAt[key];
|
|
108
105
|
const lastSeenMs = lastSeen ? Date.parse(lastSeen) : Number.NaN;
|
|
109
|
-
const expired =
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
const expired = !lastSeen ||
|
|
107
|
+
Number.isNaN(lastSeenMs) ||
|
|
108
|
+
nowMs - lastSeenMs > SYNC_CACHE_TTL_MS;
|
|
112
109
|
nextHashes[key] = hash;
|
|
113
110
|
nextSeenAt[key] = nowIso;
|
|
114
111
|
const isChanged = expired || syncCache.hashes[key] !== hash || validateOnly || rebuild;
|
|
@@ -126,7 +123,8 @@ export async function syncCommand(options = {}) {
|
|
|
126
123
|
console.warn(`Warning: Failed to hash ${file}: ${message}`);
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
|
-
|
|
126
|
+
const performedFullReindex = changedMarkdownFiles.length === markdownFiles.length &&
|
|
127
|
+
changedManifestFiles.length === manifestFiles.length;
|
|
130
128
|
const { results, failedCacheKeys, errors } = await processExtractions(changedMarkdownFiles, changedManifestFiles, validateOnly);
|
|
131
129
|
// Collect INVALID_AUTHORING diagnostics
|
|
132
130
|
for (const err of errors) {
|
|
@@ -157,7 +155,6 @@ export async function syncCommand(options = {}) {
|
|
|
157
155
|
process.exit(0);
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
|
-
// Refresh symbol manifest coordinates
|
|
161
158
|
for (const file of manifestFiles) {
|
|
162
159
|
try {
|
|
163
160
|
await refreshManifestCoordinates(file, process.cwd());
|
|
@@ -167,7 +164,6 @@ export async function syncCommand(options = {}) {
|
|
|
167
164
|
console.warn(`Warning: Failed to refresh symbol coordinates in ${file}: ${message}`);
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
|
-
// Early exit if no changes
|
|
171
167
|
if (results.length === 0 && allRelationships.length === 0 && !rebuild) {
|
|
172
168
|
const evictedHashes = {};
|
|
173
169
|
const evictedSeenAt = {};
|
|
@@ -176,7 +172,7 @@ export async function syncCommand(options = {}) {
|
|
|
176
172
|
continue;
|
|
177
173
|
}
|
|
178
174
|
evictedHashes[key] = hash;
|
|
179
|
-
evictedSeenAt[key] =
|
|
175
|
+
evictedSeenAt[key] = nextSeenAt[key] ?? nowIso;
|
|
180
176
|
}
|
|
181
177
|
writeSyncCache(cachePath, {
|
|
182
178
|
version: SYNC_CACHE_VERSION,
|
|
@@ -186,7 +182,6 @@ export async function syncCommand(options = {}) {
|
|
|
186
182
|
console.log("✓ Imported 0 entities, 0 relationships (no changes)");
|
|
187
183
|
process.exit(0);
|
|
188
184
|
}
|
|
189
|
-
// Staging setup
|
|
190
185
|
const livePath = path.join(process.cwd(), `.kb/branches/${currentBranch}`);
|
|
191
186
|
const kbExists = existsSync(livePath);
|
|
192
187
|
if (!kbExists && !rebuild) {
|
|
@@ -194,7 +189,6 @@ export async function syncCommand(options = {}) {
|
|
|
194
189
|
}
|
|
195
190
|
const stagingPath = path.join(process.cwd(), `.kb/branches/${currentBranch}.staging`);
|
|
196
191
|
await prepareStagingEnvironment(stagingPath, livePath, rebuild);
|
|
197
|
-
// Persistence to KB
|
|
198
192
|
try {
|
|
199
193
|
const prolog = new PrologProcess({ timeout: 120000 });
|
|
200
194
|
await prolog.start();
|
|
@@ -204,7 +198,10 @@ export async function syncCommand(options = {}) {
|
|
|
204
198
|
throw new SyncError(`Failed to attach to staging KB: ${attachResult.error || "Unknown error"}`);
|
|
205
199
|
}
|
|
206
200
|
const entityIds = new Set();
|
|
207
|
-
|
|
201
|
+
for (const { entity } of results) {
|
|
202
|
+
entityCounts[entity.type] = (entityCounts[entity.type] || 0) + 1;
|
|
203
|
+
}
|
|
204
|
+
const { entityCount, kbModified: entitiesModified } = await persistEntities(prolog, results, entityIds);
|
|
208
205
|
const validationErrors = validateRelationships(allRelationships, entityIds);
|
|
209
206
|
if (validationErrors.length > 0) {
|
|
210
207
|
console.warn(`Warning: ${validationErrors.length} dangling relationship(s) found`);
|
|
@@ -214,24 +211,19 @@ export async function syncCommand(options = {}) {
|
|
|
214
211
|
}
|
|
215
212
|
const danglingKeys = new Set(validationErrors.map(({ relationship: r }) => `${r.type}|${r.from}|${r.to}`));
|
|
216
213
|
const validRelationships = allRelationships.filter((r) => !danglingKeys.has(`${r.type}|${r.from}|${r.to}`));
|
|
217
|
-
// Track entity counts by type
|
|
218
|
-
for (const { entity } of results) {
|
|
219
|
-
entityCounts[entity.type] = (entityCounts[entity.type] || 0) + 1;
|
|
220
|
-
}
|
|
221
|
-
// Persist entities
|
|
222
|
-
const { entityCount, kbModified: entitiesModified } = await persistEntities(prolog, results, entityIds);
|
|
223
214
|
// Persist relationships
|
|
224
215
|
const { relationshipCount, kbModified: relationshipsModified } = await persistRelationships(prolog, results, validRelationships);
|
|
225
216
|
const kbModified = entitiesModified || relationshipsModified;
|
|
226
217
|
if (kbModified) {
|
|
227
218
|
prolog.invalidateCache();
|
|
228
219
|
}
|
|
229
|
-
await prolog.query("kb_save");
|
|
220
|
+
const saveResult = await prolog.query("kb_save");
|
|
221
|
+
if (!saveResult.success) {
|
|
222
|
+
throw new SyncError(`Failed to save staging KB: ${saveResult.error || "Unknown error"}`);
|
|
223
|
+
}
|
|
230
224
|
await prolog.query("kb_detach");
|
|
231
225
|
await prolog.terminate();
|
|
232
|
-
// Publish staging to live
|
|
233
226
|
atomicPublish(stagingPath, livePath);
|
|
234
|
-
// Update cache
|
|
235
227
|
const evictedHashes = {};
|
|
236
228
|
const evictedSeenAt = {};
|
|
237
229
|
for (const [key, hash] of Object.entries(nextHashes)) {
|
|
@@ -239,7 +231,7 @@ export async function syncCommand(options = {}) {
|
|
|
239
231
|
continue;
|
|
240
232
|
}
|
|
241
233
|
evictedHashes[key] = hash;
|
|
242
|
-
evictedSeenAt[key] =
|
|
234
|
+
evictedSeenAt[key] = nextSeenAt[key] ?? nowIso;
|
|
243
235
|
}
|
|
244
236
|
const liveCachePath = path.join(livePath, "sync-cache.json");
|
|
245
237
|
writeSyncCache(liveCachePath, {
|
|
@@ -248,7 +240,9 @@ export async function syncCommand(options = {}) {
|
|
|
248
240
|
seenAt: evictedSeenAt,
|
|
249
241
|
});
|
|
250
242
|
published = true;
|
|
251
|
-
if (
|
|
243
|
+
if (performedFullReindex &&
|
|
244
|
+
markdownFiles.length > 0 &&
|
|
245
|
+
entityCount < markdownFiles.length) {
|
|
252
246
|
diagnostics.push(createDocsNotIndexedDiagnostic(markdownFiles.length, entityCount));
|
|
253
247
|
}
|
|
254
248
|
console.log(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships`);
|
|
@@ -296,5 +290,4 @@ export async function syncCommand(options = {}) {
|
|
|
296
290
|
throw error;
|
|
297
291
|
}
|
|
298
292
|
}
|
|
299
|
-
// Export for use by modules that need these functions
|
|
300
293
|
export { normalizeMarkdownPath } from "./sync/discovery.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,2BAA2B,GAC3B,YAAY,GACZ,kBAAkB,GAClB,mBAAmB,GACnB,YAAY,GACZ,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,eAAe,CAAC;AAEpB;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CASZ;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,UAAU,CAOZ;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,UAAU,CAQZ;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EAAE,GACtB,UAAU,CAQZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,2BAA2B,GAC3B,YAAY,GACZ,kBAAkB,GAClB,mBAAmB,GACnB,YAAY,GACZ,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,eAAe,CAAC;AAEpB;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CASZ;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,UAAU,CAOZ;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,UAAU,CAQZ;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EAAE,GACtB,UAAU,CAQZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAiD9D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAQD"}
|
package/dist/diagnostics.js
CHANGED
|
@@ -77,13 +77,11 @@ export function formatSyncSummary(summary) {
|
|
|
77
77
|
}
|
|
78
78
|
lines.push(`Total Relationships: ${summary.relationshipCount}`);
|
|
79
79
|
lines.push("");
|
|
80
|
-
// Status
|
|
81
80
|
lines.push(`Status: ${summary.success ? "✓ Success" : "✗ Failed"}`);
|
|
82
81
|
lines.push(`Published: ${summary.published ? "Yes" : "No"}`);
|
|
83
82
|
if (summary.durationMs !== undefined) {
|
|
84
83
|
lines.push(`Duration: ${summary.durationMs}ms`);
|
|
85
84
|
}
|
|
86
|
-
// Failures
|
|
87
85
|
if (summary.failures.length > 0) {
|
|
88
86
|
lines.push("");
|
|
89
87
|
lines.push(`Failures (${summary.failures.length}):`);
|
|
@@ -20,6 +20,8 @@ export interface ExtractedRelationship {
|
|
|
20
20
|
export interface ExtractionResult {
|
|
21
21
|
entity: ExtractedEntity;
|
|
22
22
|
relationships: ExtractedRelationship[];
|
|
23
|
+
/** The per-symbol source code file, distinct from the manifest file path. */
|
|
24
|
+
sourceFile?: string;
|
|
23
25
|
}
|
|
24
26
|
export declare class ManifestError extends Error {
|
|
25
27
|
filePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAc,SAAQ,KAAK;IAG7B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAK1B;AAwBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA6FxE"}
|