kibi-cli 0.5.1 → 0.6.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/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +3 -2
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +64 -53
- package/dist/commands/discovery-shared.d.ts +12 -5
- package/dist/commands/discovery-shared.d.ts.map +1 -1
- package/dist/commands/discovery-shared.js +21 -13
- package/dist/commands/doctor.js +9 -1
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +2 -3
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +15 -5
- package/dist/commands/search.js +1 -1
- package/dist/commands/sync/cache.d.ts +14 -4
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +36 -14
- package/dist/commands/sync/extraction.d.ts.map +1 -1
- package/dist/commands/sync/extraction.js +4 -9
- package/dist/commands/sync/manifest.d.ts +14 -3
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +29 -10
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +9 -5
- package/dist/commands/sync/staging.d.ts +19 -3
- package/dist/commands/sync/staging.d.ts.map +1 -1
- package/dist/commands/sync/staging.js +50 -27
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +16 -20
- package/dist/diagnostics.d.ts +1 -10
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +6 -12
- package/dist/env.d.ts +7 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +41 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +17 -15
- package/dist/extractors/markdown.d.ts +2 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +124 -30
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +10 -4
- package/dist/extractors/symbols-coordinator.d.ts +5 -2
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +5 -2
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +56 -10
- package/dist/prolog/codec.d.ts +0 -43
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +68 -74
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +39 -25
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -0
- package/dist/query/service.d.ts +9 -0
- package/dist/query/service.d.ts.map +1 -1
- package/dist/query/service.js +27 -10
- package/dist/schemas/entity.schema.json +22 -0
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +19 -3
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +22 -6
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +10 -4
- package/dist/traceability/temp-kb.d.ts +12 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +42 -8
- package/dist/traceability/validate.d.ts.map +1 -1
- package/dist/traceability/validate.js +11 -2
- package/dist/utils/branch-resolver.d.ts +4 -0
- package/dist/utils/branch-resolver.d.ts.map +1 -1
- package/dist/utils/branch-resolver.js +29 -12
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +8 -2
- package/dist/utils/rule-registry.js +2 -2
- package/package.json +3 -9
- package/src/public/schemas/relationship.ts +1 -0
- package/src/schemas/entity.schema.json +22 -0
- package/src/schemas/relationship.schema.json +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregated-checks.d.ts","sourceRoot":"","sources":["../../src/commands/aggregated-checks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,cAAc,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAU5C;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAClC,UAAU,UAAQ,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"aggregated-checks.d.ts","sourceRoot":"","sources":["../../src/commands/aggregated-checks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,cAAc,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAU5C;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAClC,UAAU,UAAQ,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC,CA4DtB"}
|
|
@@ -10,6 +10,7 @@ import { escapeAtom } from "../prolog/codec.js";
|
|
|
10
10
|
* @param requireAdr - Whether to require ADR constraints for symbol-traceability
|
|
11
11
|
*/
|
|
12
12
|
export async function runAggregatedChecks(prolog, rulesAllowlist, requireAdr = false) {
|
|
13
|
+
// implements REQ-003
|
|
13
14
|
const violations = [];
|
|
14
15
|
const checksPlPath = path.join(path.dirname(resolveKbPlPath()), "checks.pl");
|
|
15
16
|
const checksPlPathEscaped = escapeAtom(checksPlPath);
|
|
@@ -48,8 +49,8 @@ export async function runAggregatedChecks(prolog, rulesAllowlist, requireAdr = f
|
|
|
48
49
|
rule: v.rule,
|
|
49
50
|
entityId: v.entityId,
|
|
50
51
|
description: v.description,
|
|
51
|
-
suggestion: v.suggestion
|
|
52
|
-
source: v.source
|
|
52
|
+
...(v.suggestion ? { suggestion: v.suggestion } : {}),
|
|
53
|
+
...(v.source ? { source: v.source } : {}),
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -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":"AAuDA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+GD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgR/B"}
|
package/dist/commands/check.js
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { existsSync } from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
-
import {
|
|
20
|
+
import { getBranchOverride, isCliTraceOrDebugEnabled } from "../env.js";
|
|
21
|
+
import { extractFromManifest, extractFromManifestString, } from "../extractors/manifest.js";
|
|
21
22
|
import { extractFromMarkdownString, } from "../extractors/markdown.js";
|
|
22
23
|
import { PrologProcess } from "../prolog.js";
|
|
23
24
|
import { escapeAtom, parseTriples, parseViolationRows, } from "../prolog/codec.js";
|
|
@@ -31,6 +32,10 @@ import { safeCleanupProlog } from "../utils/prolog-cleanup.js";
|
|
|
31
32
|
import { RULES, getEffectiveRules, } from "../utils/rule-registry.js";
|
|
32
33
|
import { runAggregatedChecks } from "./aggregated-checks.js";
|
|
33
34
|
import { getCurrentBranch } from "./init-helpers.js";
|
|
35
|
+
function getMatchGroup(match, index = 1) {
|
|
36
|
+
const value = match?.[index];
|
|
37
|
+
return typeof value === "string" ? value : null;
|
|
38
|
+
}
|
|
34
39
|
function buildManifestLookup(stagedFiles) {
|
|
35
40
|
const manifestLookup = new Map();
|
|
36
41
|
const manifestResults = [];
|
|
@@ -51,7 +56,8 @@ function buildManifestLookup(stagedFiles) {
|
|
|
51
56
|
id: entry.entity.id,
|
|
52
57
|
relationships: entry.relationships
|
|
53
58
|
.filter((relationship) => relationship.type === "implements" ||
|
|
54
|
-
relationship.type === "covered_by"
|
|
59
|
+
relationship.type === "covered_by" ||
|
|
60
|
+
relationship.type === "executable_for")
|
|
55
61
|
.map((relationship) => ({
|
|
56
62
|
type: relationship.type,
|
|
57
63
|
to: relationship.to,
|
|
@@ -61,7 +67,7 @@ function buildManifestLookup(stagedFiles) {
|
|
|
61
67
|
}
|
|
62
68
|
catch (e) {
|
|
63
69
|
// Ignore working-tree manifest parsing errors; staged-only fallback still applies
|
|
64
|
-
if (
|
|
70
|
+
if (isCliTraceOrDebugEnabled()) {
|
|
65
71
|
const msg = e instanceof Error ? e.message : String(e);
|
|
66
72
|
console.debug(`[kibi] skipping working-tree manifest ${absSymbolsPath}: ${msg}`);
|
|
67
73
|
}
|
|
@@ -91,7 +97,8 @@ function buildManifestLookup(stagedFiles) {
|
|
|
91
97
|
id: entry.entity.id,
|
|
92
98
|
relationships: entry.relationships
|
|
93
99
|
.filter((relationship) => relationship.type === "implements" ||
|
|
94
|
-
relationship.type === "covered_by"
|
|
100
|
+
relationship.type === "covered_by" ||
|
|
101
|
+
relationship.type === "executable_for")
|
|
95
102
|
.map((relationship) => ({
|
|
96
103
|
type: relationship.type,
|
|
97
104
|
to: relationship.to,
|
|
@@ -115,7 +122,7 @@ export async function checkCommand(options) {
|
|
|
115
122
|
resolvedKbPath = options.kbPath;
|
|
116
123
|
}
|
|
117
124
|
else {
|
|
118
|
-
const envBranch =
|
|
125
|
+
const envBranch = getBranchOverride();
|
|
119
126
|
let branch = envBranch || undefined;
|
|
120
127
|
if (!branch) {
|
|
121
128
|
try {
|
|
@@ -329,8 +336,9 @@ async function checkMustPriorityCoverage(prolog) {
|
|
|
329
336
|
if (entityResult.success && entityResult.bindings.Props) {
|
|
330
337
|
const propsStr = entityResult.bindings.Props;
|
|
331
338
|
const sourceMatch = propsStr.match(/source\s*=\s*\^\^?\("([^"]+)"/);
|
|
332
|
-
|
|
333
|
-
|
|
339
|
+
const sourceValue = getMatchGroup(sourceMatch);
|
|
340
|
+
if (sourceValue) {
|
|
341
|
+
source = sourceValue;
|
|
334
342
|
}
|
|
335
343
|
}
|
|
336
344
|
const scenarioResult = await prolog.query(`kb_relationship(specified_by, '${reqId}', ScenarioId)`);
|
|
@@ -366,10 +374,7 @@ async function findMustPriorityReqs(prolog) {
|
|
|
366
374
|
}
|
|
367
375
|
const idsStr = result.bindings.Ids;
|
|
368
376
|
const match = idsStr.match(/\[(.*)\]/);
|
|
369
|
-
|
|
370
|
-
return [];
|
|
371
|
-
}
|
|
372
|
-
const content = match[1].trim();
|
|
377
|
+
const content = getMatchGroup(match)?.trim();
|
|
373
378
|
if (!content) {
|
|
374
379
|
return [];
|
|
375
380
|
}
|
|
@@ -384,10 +389,7 @@ async function getAllEntityIds(prolog, type) {
|
|
|
384
389
|
}
|
|
385
390
|
const idsStr = result.bindings.Ids;
|
|
386
391
|
const match = idsStr.match(/\[(.*)\]/);
|
|
387
|
-
|
|
388
|
-
return [];
|
|
389
|
-
}
|
|
390
|
-
const content = match[1].trim();
|
|
392
|
+
const content = getMatchGroup(match)?.trim();
|
|
391
393
|
if (!content) {
|
|
392
394
|
return [];
|
|
393
395
|
}
|
|
@@ -412,15 +414,17 @@ async function checkNoDanglingRefs(prolog) {
|
|
|
412
414
|
if (relsResult.success && relsResult.bindings.Rels) {
|
|
413
415
|
const relsStr = relsResult.bindings.Rels;
|
|
414
416
|
const match = relsStr.match(/\[(.*)\]/);
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
417
|
+
const content = getMatchGroup(match)?.trim();
|
|
418
|
+
if (content) {
|
|
419
|
+
const relMatches = content.matchAll(/\[([^,]+),([^\]]+)\]/g);
|
|
420
|
+
for (const relMatch of relMatches) {
|
|
421
|
+
const fromValue = getMatchGroup(relMatch);
|
|
422
|
+
const toValue = getMatchGroup(relMatch, 2);
|
|
423
|
+
if (!fromValue || !toValue)
|
|
424
|
+
continue;
|
|
425
|
+
const fromId = fromValue.trim().replace(/^'|'$/g, "");
|
|
426
|
+
const toId = toValue.trim().replace(/^'|'$/g, "");
|
|
427
|
+
allRels.push({ from: fromId, to: toId });
|
|
424
428
|
}
|
|
425
429
|
}
|
|
426
430
|
}
|
|
@@ -454,18 +458,19 @@ async function checkNoCycles(prolog) {
|
|
|
454
458
|
}
|
|
455
459
|
const depsStr = depsResult.bindings.Deps;
|
|
456
460
|
const match = depsStr.match(/\[(.*)\]/);
|
|
457
|
-
|
|
458
|
-
return violations;
|
|
459
|
-
}
|
|
460
|
-
const content = match[1].trim();
|
|
461
|
+
const content = getMatchGroup(match)?.trim();
|
|
461
462
|
if (!content) {
|
|
462
463
|
return violations;
|
|
463
464
|
}
|
|
464
465
|
const graph = new Map();
|
|
465
466
|
const depMatches = content.matchAll(/\[([^,]+),([^\]]+)\]/g);
|
|
466
467
|
for (const depMatch of depMatches) {
|
|
467
|
-
const
|
|
468
|
-
const
|
|
468
|
+
const fromValue = getMatchGroup(depMatch);
|
|
469
|
+
const toValue = getMatchGroup(depMatch, 2);
|
|
470
|
+
if (!fromValue || !toValue)
|
|
471
|
+
continue;
|
|
472
|
+
const from = fromValue.trim().replace(/^'|'$/g, "");
|
|
473
|
+
const to = toValue.trim().replace(/^'|'$/g, "");
|
|
469
474
|
if (!graph.has(from)) {
|
|
470
475
|
graph.set(from, []);
|
|
471
476
|
}
|
|
@@ -499,6 +504,10 @@ async function checkNoCycles(prolog) {
|
|
|
499
504
|
if (!visited.has(node)) {
|
|
500
505
|
const cyclePath = hasCycleDFS(node, []);
|
|
501
506
|
if (cyclePath) {
|
|
507
|
+
const cycleEntityId = cyclePath[0];
|
|
508
|
+
if (!cycleEntityId) {
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
502
511
|
const cycleWithSources = [];
|
|
503
512
|
for (const entityId of cyclePath) {
|
|
504
513
|
const entityResult = await prolog.query(`kb_entity('${entityId}', _, Props)`);
|
|
@@ -506,15 +515,16 @@ async function checkNoCycles(prolog) {
|
|
|
506
515
|
if (entityResult.success && entityResult.bindings.Props) {
|
|
507
516
|
const propsStr = entityResult.bindings.Props;
|
|
508
517
|
const sourceMatch = propsStr.match(/source\s*=\s*\^\^?\("([^"]+)"/);
|
|
509
|
-
|
|
510
|
-
|
|
518
|
+
const sourceValue = getMatchGroup(sourceMatch);
|
|
519
|
+
if (sourceValue) {
|
|
520
|
+
sourceName = path.basename(sourceValue, ".md");
|
|
511
521
|
}
|
|
512
522
|
}
|
|
513
523
|
cycleWithSources.push(sourceName);
|
|
514
524
|
}
|
|
515
525
|
violations.push({
|
|
516
526
|
rule: "no-cycles",
|
|
517
|
-
entityId:
|
|
527
|
+
entityId: cycleEntityId,
|
|
518
528
|
description: `Circular dependency detected: ${cycleWithSources.join(" → ")}`,
|
|
519
529
|
suggestion: "Break cycle by removing one of the depends_on relationships",
|
|
520
530
|
});
|
|
@@ -541,7 +551,10 @@ async function checkRequiredFields(prolog, allEntityIds) {
|
|
|
541
551
|
const propKeys = new Set();
|
|
542
552
|
const keyMatches = propsStr.matchAll(/(\w+)\s*=/g);
|
|
543
553
|
for (const match of keyMatches) {
|
|
544
|
-
|
|
554
|
+
const key = getMatchGroup(match);
|
|
555
|
+
if (key) {
|
|
556
|
+
propKeys.add(key);
|
|
557
|
+
}
|
|
545
558
|
}
|
|
546
559
|
for (const field of required) {
|
|
547
560
|
if (!propKeys.has(field)) {
|
|
@@ -566,10 +579,7 @@ async function checkDeprecatedAdrs(prolog) {
|
|
|
566
579
|
}
|
|
567
580
|
const idsStr = result.bindings.Ids;
|
|
568
581
|
const match = idsStr.match(/\[(.*)\]/);
|
|
569
|
-
|
|
570
|
-
return violations;
|
|
571
|
-
}
|
|
572
|
-
const content = match[1].trim();
|
|
582
|
+
const content = getMatchGroup(match)?.trim();
|
|
573
583
|
if (!content) {
|
|
574
584
|
return violations;
|
|
575
585
|
}
|
|
@@ -582,8 +592,9 @@ async function checkDeprecatedAdrs(prolog) {
|
|
|
582
592
|
if (entityResult.success && entityResult.bindings.Props) {
|
|
583
593
|
const propsStr = entityResult.bindings.Props;
|
|
584
594
|
const sourceMatch = propsStr.match(/source\s*=\s*\^\^?\("([^"]+)"/);
|
|
585
|
-
|
|
586
|
-
|
|
595
|
+
const sourceValue = getMatchGroup(sourceMatch);
|
|
596
|
+
if (sourceValue) {
|
|
597
|
+
source = sourceValue;
|
|
587
598
|
}
|
|
588
599
|
}
|
|
589
600
|
violations.push({
|
|
@@ -635,19 +646,19 @@ async function checkSymbolCoverage(prolog) {
|
|
|
635
646
|
if (uncoveredResult.success && uncoveredResult.bindings.Symbols) {
|
|
636
647
|
const symbolsStr = uncoveredResult.bindings.Symbols;
|
|
637
648
|
const match = symbolsStr.match(/\[(.*)\]/);
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
}
|
|
649
|
+
const content = getMatchGroup(match)?.trim();
|
|
650
|
+
if (content) {
|
|
651
|
+
const symbolMatches = content.matchAll(/'([^']+)'/g);
|
|
652
|
+
for (const symbolMatch of symbolMatches) {
|
|
653
|
+
const symbolId = getMatchGroup(symbolMatch);
|
|
654
|
+
if (!symbolId)
|
|
655
|
+
continue;
|
|
656
|
+
violations.push({
|
|
657
|
+
rule: "symbol-coverage",
|
|
658
|
+
entityId: symbolId,
|
|
659
|
+
description: "Code symbol is not traceable to any functional requirement.",
|
|
660
|
+
suggestion: "Update symbols.yaml to link this symbol to a related requirement.",
|
|
661
|
+
});
|
|
651
662
|
}
|
|
652
663
|
}
|
|
653
664
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { PrologProcess } from "../prolog.js";
|
|
1
|
+
import { PrologProcess, resolveKbPlPath } from "../prolog.js";
|
|
2
2
|
export interface DiscoveryCommandOptions {
|
|
3
3
|
format?: "json" | "table";
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
export
|
|
5
|
+
/** Dependencies that can be injected for testing. */
|
|
6
|
+
export interface DiscoveryDeps {
|
|
7
|
+
createProlog: (opts: {
|
|
8
|
+
timeout: number;
|
|
9
|
+
}) => PrologProcess;
|
|
10
|
+
resolveKbPl: typeof resolveKbPlPath;
|
|
11
|
+
}
|
|
12
|
+
export declare function withAttachedBranchProlog<T>(callback: (prolog: PrologProcess) => Promise<T>, deps?: Partial<DiscoveryDeps>): Promise<T>;
|
|
13
|
+
export declare function withPrologProcess<T>(callback: (prolog: PrologProcess) => Promise<T>, deps?: Partial<DiscoveryDeps>): Promise<T>;
|
|
7
14
|
export declare function resolveCurrentKbPath(): Promise<string>;
|
|
8
|
-
export declare function resolveCoreModulePath(fileName: string): string;
|
|
9
|
-
export declare function runJsonModuleQuery<T>(prolog: PrologProcess, fileName: string, goal: string, errorLabel: string, kbPath?: string): Promise<T>;
|
|
15
|
+
export declare function resolveCoreModulePath(fileName: string, deps?: Partial<DiscoveryDeps>): string;
|
|
16
|
+
export declare function runJsonModuleQuery<T>(prolog: PrologProcess, fileName: string, goal: string, errorLabel: string, kbPath?: string, deps?: Partial<DiscoveryDeps>): Promise<T>;
|
|
10
17
|
export declare function printDiscoveryResult(format: "json" | "table" | undefined, structured: unknown, fallbackText: string): void;
|
|
11
18
|
//# sourceMappingURL=discovery-shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-shared.d.ts","sourceRoot":"","sources":["../../src/commands/discovery-shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"discovery-shared.d.ts","sourceRoot":"","sources":["../../src/commands/discovery-shared.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAK9D,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC3D,WAAW,EAAE,OAAO,eAAe,CAAC;CACrC;AAGD,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/C,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAGD,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/C,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAGD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAS5D;AAGD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CAGR;AAGD,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAGD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,EACpC,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,MAAM,GACnB,IAAI,CAQN"}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import Table from "cli-table3";
|
|
3
|
+
import { getBranchOverride } from "../env.js";
|
|
3
4
|
import { PrologProcess, resolveKbPlPath } from "../prolog.js";
|
|
4
5
|
import { escapeAtom } from "../prolog/codec.js";
|
|
5
6
|
import { safeCleanupProlog } from "../utils/prolog-cleanup.js";
|
|
6
7
|
import { getCurrentBranch } from "./init-helpers.js";
|
|
7
8
|
// implements REQ-003
|
|
8
|
-
export async function withAttachedBranchProlog(callback) {
|
|
9
|
+
export async function withAttachedBranchProlog(callback, deps) {
|
|
10
|
+
const createProlog = deps?.createProlog ?? ((opts) => new PrologProcess(opts));
|
|
9
11
|
let prolog = null;
|
|
10
12
|
let attached = false;
|
|
11
13
|
try {
|
|
12
|
-
prolog =
|
|
14
|
+
prolog = createProlog({ timeout: 120000 });
|
|
13
15
|
await prolog.start();
|
|
14
16
|
await prolog.query("set_prolog_flag(answer_write_options, [max_depth(0), spacing(next_argument)])");
|
|
15
17
|
let branch;
|
|
16
18
|
try {
|
|
17
|
-
branch =
|
|
18
|
-
process.env.KIBI_BRANCH || (await getCurrentBranch(process.cwd()));
|
|
19
|
+
branch = getBranchOverride() || (await getCurrentBranch(process.cwd()));
|
|
19
20
|
}
|
|
20
21
|
catch {
|
|
21
|
-
branch =
|
|
22
|
+
branch = getBranchOverride() || "main";
|
|
22
23
|
}
|
|
23
24
|
const kbPath = path.join(process.cwd(), ".kb/branches", branch);
|
|
24
25
|
const attachResult = await prolog.query(`kb_attach('${escapeAtom(kbPath)}')`);
|
|
@@ -33,10 +34,16 @@ export async function withAttachedBranchProlog(callback) {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
// implements REQ-003
|
|
36
|
-
export async function withPrologProcess(callback) {
|
|
37
|
-
const
|
|
37
|
+
export async function withPrologProcess(callback, deps) {
|
|
38
|
+
const createProlog = deps?.createProlog ?? ((opts) => new PrologProcess(opts));
|
|
39
|
+
const prolog = createProlog({ timeout: 120000 });
|
|
38
40
|
try {
|
|
39
41
|
await prolog.start();
|
|
42
|
+
// NOTE: useOneShotMode is an internal optimization flag on PrologProcess that
|
|
43
|
+
// forces single-query mode (start → query → terminate per call) instead of the
|
|
44
|
+
// default interactive session. It is not exposed in the public PrologProcess
|
|
45
|
+
// type because callers should not set it directly — only internal discovery
|
|
46
|
+
// helpers use it for lightweight one-shot queries that don't need session state.
|
|
40
47
|
prolog.useOneShotMode = true;
|
|
41
48
|
await prolog.query("set_prolog_flag(answer_write_options, [max_depth(0), spacing(next_argument)])");
|
|
42
49
|
return await callback(prolog);
|
|
@@ -49,20 +56,21 @@ export async function withPrologProcess(callback) {
|
|
|
49
56
|
export async function resolveCurrentKbPath() {
|
|
50
57
|
let branch;
|
|
51
58
|
try {
|
|
52
|
-
branch =
|
|
59
|
+
branch = getBranchOverride() || (await getCurrentBranch(process.cwd()));
|
|
53
60
|
}
|
|
54
61
|
catch {
|
|
55
|
-
branch =
|
|
62
|
+
branch = getBranchOverride() || "main";
|
|
56
63
|
}
|
|
57
64
|
return path.join(process.cwd(), ".kb/branches", branch);
|
|
58
65
|
}
|
|
59
66
|
// implements REQ-003
|
|
60
|
-
export function resolveCoreModulePath(fileName) {
|
|
61
|
-
|
|
67
|
+
export function resolveCoreModulePath(fileName, deps) {
|
|
68
|
+
const resolve = deps?.resolveKbPl ?? resolveKbPlPath;
|
|
69
|
+
return path.join(path.dirname(resolve()), fileName);
|
|
62
70
|
}
|
|
63
71
|
// implements REQ-003
|
|
64
|
-
export async function runJsonModuleQuery(prolog, fileName, goal, errorLabel, kbPath) {
|
|
65
|
-
const modulePath = escapeAtom(resolveCoreModulePath(fileName).replace(/\\/g, "/"));
|
|
72
|
+
export async function runJsonModuleQuery(prolog, fileName, goal, errorLabel, kbPath, deps) {
|
|
73
|
+
const modulePath = escapeAtom(resolveCoreModulePath(fileName, deps).replace(/\\/g, "/"));
|
|
66
74
|
const wrappedGoal = kbPath
|
|
67
75
|
? `(use_module('${modulePath}'), kb_attach('${escapeAtom(kbPath)}'), ${goal}, kb_detach)`
|
|
68
76
|
: `(use_module('${modulePath}'), ${goal})`;
|
package/dist/commands/doctor.js
CHANGED
|
@@ -82,7 +82,15 @@ function checkSWIProlog() {
|
|
|
82
82
|
remediation: "Reinstall SWI-Prolog from https://www.swi-prolog.org/",
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
const
|
|
85
|
+
const majorText = versionMatch[1];
|
|
86
|
+
if (!majorText) {
|
|
87
|
+
return {
|
|
88
|
+
passed: false,
|
|
89
|
+
message: "Unable to parse major version",
|
|
90
|
+
remediation: "Reinstall SWI-Prolog from https://www.swi-prolog.org/",
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const major = Number.parseInt(majorText, 10);
|
|
86
94
|
if (major < 9) {
|
|
87
95
|
return {
|
|
88
96
|
passed: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AAuFA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAajD;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AAuFA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAajD;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAkCnE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiBpD"}
|
|
@@ -121,6 +121,7 @@ function escapeRegex(s) {
|
|
|
121
121
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
122
122
|
}
|
|
123
123
|
export function installHook(hookPath, content) {
|
|
124
|
+
// implements REQ-008
|
|
124
125
|
const kibiSection = `${KIBI_HOOK_BEGIN}\n${content}\n${KIBI_HOOK_END}`;
|
|
125
126
|
if (existsSync(hookPath)) {
|
|
126
127
|
const existing = readFileSync(hookPath, "utf8");
|
|
@@ -130,12 +131,10 @@ export function installHook(hookPath, content) {
|
|
|
130
131
|
const updated = existing.replace(new RegExp(`${escapeRegex(KIBI_HOOK_BEGIN)}[\\s\\S]*?${escapeRegex(KIBI_HOOK_END)}`), kibiSection);
|
|
131
132
|
writeFileSync(hookPath, updated, { mode: 0o755 });
|
|
132
133
|
}
|
|
133
|
-
else if (existing.
|
|
134
|
-
// Legacy format: already has the complete kibi logic, skip
|
|
134
|
+
else if (existing.trim().length > 0) {
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
else {
|
|
138
|
-
// Hook exists with user content (no kibi section) - append kibi section
|
|
139
138
|
const shebang = existing.startsWith("#!/") ? "" : "#!/bin/sh\n";
|
|
140
139
|
writeFileSync(hookPath, `${shebang}${existing.trimEnd()}\n${kibiSection}\n`, { mode: 0o755 });
|
|
141
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AA4CA,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;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AA4CA,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;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA4K/B"}
|
package/dist/commands/query.js
CHANGED
|
@@ -71,11 +71,21 @@ export async function queryCommand(type, options) {
|
|
|
71
71
|
const rows = parseListOfLists(queryResult.bindings.Results);
|
|
72
72
|
const parsed = rows
|
|
73
73
|
.filter((r) => r.length >= 3)
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
.flatMap((r) => {
|
|
75
|
+
const [typeValue, fromValue, toValue] = r;
|
|
76
|
+
if (typeValue === undefined ||
|
|
77
|
+
fromValue === undefined ||
|
|
78
|
+
toValue === undefined) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
type: parsePrologValue(typeValue),
|
|
84
|
+
from: parsePrologValue(fromValue),
|
|
85
|
+
to: parsePrologValue(toValue),
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
});
|
|
79
89
|
results = parsed.filter((rel) => rel &&
|
|
80
90
|
typeof rel.type === "string" &&
|
|
81
91
|
typeof rel.from === "string" &&
|
package/dist/commands/search.js
CHANGED
|
@@ -22,7 +22,7 @@ export async function searchCommand(query, options) {
|
|
|
22
22
|
}
|
|
23
23
|
async function executeSearch(prolog, query, type, limit, offset) {
|
|
24
24
|
const entitiesResult = await queryEntities(prolog, {
|
|
25
|
-
type,
|
|
25
|
+
...(type !== undefined ? { type } : {}),
|
|
26
26
|
limit: 100000,
|
|
27
27
|
offset: 0,
|
|
28
28
|
});
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
interface SyncCacheDeps {
|
|
4
|
+
createHash: typeof createHash;
|
|
5
|
+
existsSync: typeof existsSync;
|
|
6
|
+
mkdirSync: typeof mkdirSync;
|
|
7
|
+
readFileSync: typeof readFileSync;
|
|
8
|
+
writeFileSync: typeof writeFileSync;
|
|
9
|
+
}
|
|
1
10
|
export type SyncCache = {
|
|
2
11
|
version: number;
|
|
3
12
|
hashes: Record<string, string>;
|
|
@@ -6,8 +15,9 @@ export type SyncCache = {
|
|
|
6
15
|
export declare const SYNC_CACHE_VERSION = 1;
|
|
7
16
|
export declare const SYNC_CACHE_TTL_MS: number;
|
|
8
17
|
export declare function toCacheKey(filePath: string): string;
|
|
9
|
-
export declare function hashFile(filePath: string): string;
|
|
10
|
-
export declare function readSyncCache(cachePath: string): SyncCache;
|
|
11
|
-
export declare function writeSyncCache(cachePath: string, cache: SyncCache): void;
|
|
12
|
-
export declare function copySyncCache(livePath: string, stagingPath: string): void;
|
|
18
|
+
export declare function hashFile(filePath: string, deps?: Partial<SyncCacheDeps>): string;
|
|
19
|
+
export declare function readSyncCache(cachePath: string, deps?: Partial<SyncCacheDeps>): SyncCache;
|
|
20
|
+
export declare function writeSyncCache(cachePath: string, cache: SyncCache, deps?: Partial<SyncCacheDeps>): void;
|
|
21
|
+
export declare function copySyncCache(livePath: string, stagingPath: string, deps?: Partial<SyncCacheDeps>): void;
|
|
22
|
+
export {};
|
|
13
23
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7E,UAAU,aAAa;IACrB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;AAaD,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,QAA2B,CAAC;AAE1D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,QAAQ,CAEtB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CAIR;AAED,wBAAgB,aAAa,CAE3B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,SAAS,CAkCX;AAED,wBAAgB,cAAc,CAE5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,IAAI,CAaN;AAED,wBAAgB,aAAa,CAE3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,IAAI,CASN"}
|
|
@@ -18,17 +18,33 @@
|
|
|
18
18
|
import { createHash } from "node:crypto";
|
|
19
19
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
20
20
|
import * as path from "node:path";
|
|
21
|
+
function resolveDeps(overrides) {
|
|
22
|
+
return {
|
|
23
|
+
createHash,
|
|
24
|
+
existsSync,
|
|
25
|
+
mkdirSync,
|
|
26
|
+
readFileSync,
|
|
27
|
+
writeFileSync,
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
21
31
|
export const SYNC_CACHE_VERSION = 1;
|
|
22
32
|
export const SYNC_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
23
33
|
export function toCacheKey(filePath) {
|
|
24
34
|
return path.relative(process.cwd(), filePath).split(path.sep).join("/");
|
|
25
35
|
}
|
|
26
|
-
export function hashFile(
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
export function hashFile(
|
|
37
|
+
// implements REQ-003
|
|
38
|
+
filePath, deps) {
|
|
39
|
+
const resolved = resolveDeps(deps);
|
|
40
|
+
const content = resolved.readFileSync(filePath);
|
|
41
|
+
return resolved.createHash("sha256").update(content).digest("hex");
|
|
29
42
|
}
|
|
30
|
-
export function readSyncCache(
|
|
31
|
-
|
|
43
|
+
export function readSyncCache(
|
|
44
|
+
// implements REQ-003
|
|
45
|
+
cachePath, deps) {
|
|
46
|
+
const resolved = resolveDeps(deps);
|
|
47
|
+
if (!resolved.existsSync(cachePath)) {
|
|
32
48
|
return {
|
|
33
49
|
version: SYNC_CACHE_VERSION,
|
|
34
50
|
hashes: {},
|
|
@@ -36,7 +52,7 @@ export function readSyncCache(cachePath) {
|
|
|
36
52
|
};
|
|
37
53
|
}
|
|
38
54
|
try {
|
|
39
|
-
const parsed = JSON.parse(readFileSync(cachePath, "utf8"));
|
|
55
|
+
const parsed = JSON.parse(resolved.readFileSync(cachePath, "utf8"));
|
|
40
56
|
if (parsed.version !== SYNC_CACHE_VERSION) {
|
|
41
57
|
return {
|
|
42
58
|
version: SYNC_CACHE_VERSION,
|
|
@@ -58,19 +74,25 @@ export function readSyncCache(cachePath) {
|
|
|
58
74
|
};
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
|
-
export function writeSyncCache(
|
|
77
|
+
export function writeSyncCache(
|
|
78
|
+
// implements REQ-003
|
|
79
|
+
cachePath, cache, deps) {
|
|
80
|
+
const resolved = resolveDeps(deps);
|
|
62
81
|
const cacheDir = path.dirname(cachePath);
|
|
63
|
-
if (!existsSync(cacheDir)) {
|
|
64
|
-
mkdirSync(cacheDir, { recursive: true });
|
|
82
|
+
if (!resolved.existsSync(cacheDir)) {
|
|
83
|
+
resolved.mkdirSync(cacheDir, { recursive: true });
|
|
65
84
|
}
|
|
66
|
-
writeFileSync(cachePath, `${JSON.stringify(cache, null, 2)}
|
|
85
|
+
resolved.writeFileSync(cachePath, `${JSON.stringify(cache, null, 2)}
|
|
67
86
|
`, "utf8");
|
|
68
87
|
}
|
|
69
|
-
export function copySyncCache(
|
|
88
|
+
export function copySyncCache(
|
|
89
|
+
// implements REQ-003
|
|
90
|
+
livePath, stagingPath, deps) {
|
|
91
|
+
const resolved = resolveDeps(deps);
|
|
70
92
|
const liveCachePath = path.join(livePath, "sync-cache.json");
|
|
71
93
|
const stagingCachePath = path.join(stagingPath, "sync-cache.json");
|
|
72
|
-
if (existsSync(liveCachePath)) {
|
|
73
|
-
const cacheContent = readFileSync(liveCachePath, "utf8");
|
|
74
|
-
writeFileSync(stagingCachePath, cacheContent, "utf8");
|
|
94
|
+
if (resolved.existsSync(liveCachePath)) {
|
|
95
|
+
const cacheContent = resolved.readFileSync(liveCachePath, "utf8");
|
|
96
|
+
resolved.writeFileSync(stagingCachePath, cacheContent, "utf8");
|
|
75
97
|
}
|
|
76
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,wBAAsB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,wBAAsB,kBAAkB,CAEtC,oBAAoB,EAAE,MAAM,EAAE,EAC9B,oBAAoB,EAAE,MAAM,EAAE,EAC9B,YAAY,EAAE,OAAO,GACpB,OAAO,CAAC,gBAAgB,CAAC,CA4C3B"}
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
import { extractFromManifest } from "../../extractors/manifest.js";
|
|
19
19
|
import { FrontmatterError, extractFromMarkdown, } from "../../extractors/markdown.js";
|
|
20
20
|
import { toCacheKey } from "./cache.js";
|
|
21
|
-
export async function processExtractions(
|
|
21
|
+
export async function processExtractions(
|
|
22
|
+
// implements REQ-003
|
|
23
|
+
changedMarkdownFiles, changedManifestFiles, validateOnly) {
|
|
22
24
|
const results = [];
|
|
23
25
|
const failedCacheKeys = new Set();
|
|
24
26
|
const errors = [];
|
|
@@ -31,14 +33,7 @@ export async function processExtractions(changedMarkdownFiles, changedManifestFi
|
|
|
31
33
|
// Handle INVALID_AUTHORING diagnostics for embedded entities
|
|
32
34
|
if (error instanceof FrontmatterError &&
|
|
33
35
|
error.classification === "Embedded Entity Violation") {
|
|
34
|
-
|
|
35
|
-
? ["scenario", "test"]
|
|
36
|
-
: message.includes("scenario")
|
|
37
|
-
? ["scenario"]
|
|
38
|
-
: message.includes("test")
|
|
39
|
-
? ["test"]
|
|
40
|
-
: ["entity"];
|
|
41
|
-
// Note: diagnostics are created by the caller
|
|
36
|
+
// Note: diagnostics with embeddedTypes are created by the caller (sync.ts)
|
|
42
37
|
}
|
|
43
38
|
if (validateOnly) {
|
|
44
39
|
errors.push({ file, message });
|