@vibgrate/cli 2026.4.10 → 2026.4.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +44 -90
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -572,113 +572,61 @@ function validateFactLine(line) {
572
572
  } catch {
573
573
  return { valid: false, error: `Invalid JSON: ${line.substring(0, 80)}...` };
574
574
  }
575
- const envelope = parsed;
576
- if (typeof envelope.factId !== "string" || !envelope.factId) {
575
+ const obj = parsed;
576
+ if (obj.factType === "Models" || obj.factType === "References") {
577
+ if (obj.payload === void 0 || obj.payload === null) {
578
+ return { valid: false, error: `Preamble ${obj.factType} missing payload` };
579
+ }
580
+ return { valid: true };
581
+ }
582
+ if (typeof obj.factId !== "string" || !obj.factId) {
577
583
  return { valid: false, error: "Missing or invalid factId" };
578
584
  }
579
- if (typeof envelope.factType !== "string" || !envelope.factType) {
585
+ if (typeof obj.m === "string") {
586
+ if (obj.payload === void 0 || obj.payload === null) {
587
+ return { valid: false, error: "Compressed fact missing payload" };
588
+ }
589
+ return { valid: true };
590
+ }
591
+ if (typeof obj.factType !== "string" || !obj.factType) {
580
592
  return { valid: false, error: "Missing or invalid factType" };
581
593
  }
582
- if (typeof envelope.language !== "string") {
594
+ if (typeof obj.language !== "string") {
583
595
  return { valid: false, error: "Missing or invalid language" };
584
596
  }
585
- if (typeof envelope.scanner !== "string") {
597
+ if (typeof obj.scanner !== "string") {
586
598
  return { valid: false, error: "Missing or invalid scanner" };
587
599
  }
588
- if (typeof envelope.scannerVersion !== "string") {
600
+ if (typeof obj.scannerVersion !== "string") {
589
601
  return { valid: false, error: "Missing or invalid scannerVersion" };
590
602
  }
591
- if (typeof envelope.emittedAt !== "string") {
603
+ if (typeof obj.emittedAt !== "string") {
592
604
  return { valid: false, error: "Missing or invalid emittedAt" };
593
605
  }
594
- if (envelope.payload === void 0 || envelope.payload === null) {
606
+ if (obj.payload === void 0 || obj.payload === null) {
595
607
  return { valid: false, error: "Missing payload" };
596
608
  }
597
- return { valid: true, fact: envelope };
609
+ return { valid: true };
598
610
  }
599
- function decompressHcsLines(lines) {
600
- if (lines.length === 0) return lines;
601
- let modelsLine = null;
602
- let refsLine = null;
603
- const contentLines = [];
611
+ function splitHcsOutput(lines) {
612
+ const preamble = [];
613
+ const facts = [];
604
614
  for (const line of lines) {
605
615
  let parsed;
606
616
  try {
607
617
  parsed = JSON.parse(line);
608
618
  } catch {
609
- contentLines.push(line);
619
+ facts.push(line);
610
620
  continue;
611
621
  }
612
622
  const obj = parsed;
613
- if (obj.factType === "Models" && !modelsLine) {
614
- modelsLine = obj;
615
- } else if (obj.factType === "References" && !refsLine) {
616
- refsLine = obj;
623
+ if (obj.factType === "Models" || obj.factType === "References") {
624
+ preamble.push(line);
617
625
  } else {
618
- contentLines.push(line);
619
- }
620
- }
621
- if (!modelsLine) return lines;
622
- const emittedAt = typeof modelsLine.emittedAt === "string" ? modelsLine.emittedAt : (/* @__PURE__ */ new Date()).toISOString();
623
- const modelsPayload = modelsLine.payload;
624
- const modelMap = /* @__PURE__ */ new Map();
625
- for (const m of modelsPayload?.models ?? []) {
626
- if (m.id) modelMap.set(m.id, m);
627
- }
628
- const refsPayload = refsLine?.payload;
629
- const refMap = /* @__PURE__ */ new Map();
630
- for (const r of refsPayload?.references ?? []) {
631
- if (r.id && r.value) refMap.set(r.id, r.value);
632
- }
633
- const sortedRefs = [...refMap.entries()].sort((a, b) => b[0].length - a[0].length);
634
- function expandRefs(text) {
635
- for (const [token, value] of sortedRefs) {
636
- text = text.split(token).join(value);
637
- }
638
- return text;
639
- }
640
- const expanded = [];
641
- for (const line of contentLines) {
642
- let parsed;
643
- try {
644
- parsed = JSON.parse(line);
645
- } catch {
646
- expanded.push(line);
647
- continue;
648
- }
649
- const obj = parsed;
650
- if (typeof obj.factType === "string") {
651
- expanded.push(line);
652
- continue;
626
+ facts.push(line);
653
627
  }
654
- if (typeof obj.factId !== "string" || typeof obj.m !== "string") {
655
- expanded.push(line);
656
- continue;
657
- }
658
- const model = modelMap.get(obj.m);
659
- if (!model) {
660
- expanded.push(line);
661
- continue;
662
- }
663
- const payloadJson = expandRefs(JSON.stringify(obj.payload));
664
- let payload;
665
- try {
666
- payload = JSON.parse(payloadJson);
667
- } catch {
668
- payload = obj.payload;
669
- }
670
- const fullEnvelope = {
671
- factId: obj.factId,
672
- factType: model.factType ?? "",
673
- language: model.language ?? "",
674
- scanner: model.scanner ?? "",
675
- scannerVersion: model.scannerVersion ?? "",
676
- emittedAt: model.emittedAt ?? emittedAt,
677
- payload
678
- };
679
- expanded.push(JSON.stringify(fullEnvelope));
680
628
  }
681
- return expanded;
629
+ return { preamble, facts };
682
630
  }
683
631
  function resolveHcsWorkerBin() {
684
632
  const base = import.meta.dirname ?? path6.dirname(new URL(import.meta.url).pathname);
@@ -1296,6 +1244,7 @@ var extractCommand = new Command5("extract").description("Analyze source code an
1296
1244
  );
1297
1245
  const progress = new ProgressTracker(runnableLanguages);
1298
1246
  const sem = new Semaphore(concurrency);
1247
+ const allPreamble = [];
1299
1248
  const allFacts = [];
1300
1249
  const allErrors = [];
1301
1250
  let hasSchemaFailure = false;
@@ -1321,15 +1270,12 @@ var extractCommand = new Command5("extract").description("Analyze source code an
1321
1270
  if (result.exitCode === EXIT_TIMEOUT) {
1322
1271
  hasTimeout = true;
1323
1272
  }
1324
- const decompressedFacts = decompressHcsLines(result.facts);
1273
+ const { preamble, facts } = splitHcsOutput(result.facts);
1274
+ allPreamble.push(...preamble);
1325
1275
  let langFactCount = 0;
1326
- for (const line of decompressedFacts) {
1276
+ for (const line of [...preamble, ...facts]) {
1327
1277
  const validation = validateFactLine(line);
1328
- if (validation.valid) {
1329
- allFacts.push(line);
1330
- langFactCount++;
1331
- progress.onFact();
1332
- } else {
1278
+ if (!validation.valid) {
1333
1279
  hasSchemaFailure = true;
1334
1280
  allErrors.push(`[${language}] Schema validation: ${validation.error}`);
1335
1281
  if (opts.verbose) {
@@ -1338,6 +1284,13 @@ var extractCommand = new Command5("extract").description("Analyze source code an
1338
1284
  }
1339
1285
  }
1340
1286
  }
1287
+ for (const line of facts) {
1288
+ if (validateFactLine(line).valid) {
1289
+ allFacts.push(line);
1290
+ langFactCount++;
1291
+ progress.onFact();
1292
+ }
1293
+ }
1341
1294
  progress.setLanguageFactCount(language, langFactCount);
1342
1295
  if (result.errors.length > 0) {
1343
1296
  allErrors.push(...result.errors.map((e) => `[${language}] ${e}`));
@@ -1351,7 +1304,8 @@ var extractCommand = new Command5("extract").description("Analyze source code an
1351
1304
  const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
1352
1305
  progress.finish(elapsed);
1353
1306
  allFacts.sort();
1354
- const ndjsonOutput = allFacts.map((f) => f).join("\n") + (allFacts.length > 0 ? "\n" : "");
1307
+ const allLines = [...allPreamble, ...allFacts];
1308
+ const ndjsonOutput = allLines.join("\n") + (allLines.length > 0 ? "\n" : "");
1355
1309
  if (opts.out) {
1356
1310
  const outPath = path6.resolve(opts.out);
1357
1311
  await fs2.writeFile(outPath, ndjsonOutput, "utf-8");
@@ -1361,7 +1315,7 @@ var extractCommand = new Command5("extract").description("Analyze source code an
1361
1315
  process.stdout.write(ndjsonOutput);
1362
1316
  }
1363
1317
  if (opts.push && dsn && allFacts.length > 0) {
1364
- const pushOk = await pushFacts(allFacts, dsn, opts.verbose ?? false);
1318
+ const pushOk = await pushFacts(allLines, dsn, opts.verbose ?? false);
1365
1319
  if (!pushOk) {
1366
1320
  process.exit(EXIT_PUSH_FAILURE);
1367
1321
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibgrate/cli",
3
- "version": "2026.4.10",
3
+ "version": "2026.4.30",
4
4
  "description": "CLI for measuring upgrade drift across Node, .NET, Python & Java projects",
5
5
  "type": "module",
6
6
  "bin": {