@vibgrate/cli 2026.613.1 → 2026.615.2

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.
@@ -2507,7 +2507,7 @@ var require_typescript = __commonJS({
2507
2507
  SymbolDisplayPartKind: () => SymbolDisplayPartKind,
2508
2508
  SymbolFlags: () => SymbolFlags,
2509
2509
  SymbolFormatFlags: () => SymbolFormatFlags,
2510
- SyntaxKind: () => SyntaxKind18,
2510
+ SyntaxKind: () => SyntaxKind20,
2511
2511
  Ternary: () => Ternary,
2512
2512
  ThrottledCancellationToken: () => ThrottledCancellationToken,
2513
2513
  TokenClass: () => TokenClass,
@@ -6398,7 +6398,7 @@ Node ${formatSyntaxKind(node.kind)} was unexpected.`,
6398
6398
  function formatSyntaxKind(kind) {
6399
6399
  return formatEnum(
6400
6400
  kind,
6401
- SyntaxKind18,
6401
+ SyntaxKind20,
6402
6402
  /*isFlags*/
6403
6403
  false
6404
6404
  );
@@ -7846,7 +7846,7 @@ ${lanes.join("\n")}
7846
7846
  })(tracingEnabled || (tracingEnabled = {}));
7847
7847
  var startTracing = tracingEnabled.startTracing;
7848
7848
  var dumpTracingLegend = tracingEnabled.dumpLegend;
7849
- var SyntaxKind18 = /* @__PURE__ */ ((SyntaxKind52) => {
7849
+ var SyntaxKind20 = /* @__PURE__ */ ((SyntaxKind52) => {
7850
7850
  SyntaxKind52[SyntaxKind52["Unknown"] = 0] = "Unknown";
7851
7851
  SyntaxKind52[SyntaxKind52["EndOfFileToken"] = 1] = "EndOfFileToken";
7852
7852
  SyntaxKind52[SyntaxKind52["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
@@ -8352,7 +8352,7 @@ ${lanes.join("\n")}
8352
8352
  /* LastKeyword */
8353
8353
  ] = "LastContextualKeyword";
8354
8354
  return SyntaxKind52;
8355
- })(SyntaxKind18 || {});
8355
+ })(SyntaxKind20 || {});
8356
8356
  var NodeFlags = /* @__PURE__ */ ((NodeFlags3) => {
8357
8357
  NodeFlags3[NodeFlags3["None"] = 0] = "None";
8358
8358
  NodeFlags3[NodeFlags3["Let"] = 1] = "Let";
@@ -198758,7 +198758,7 @@ ${options.prefix}` : "\n" : options.prefix
198758
198758
  SymbolDisplayPartKind: () => SymbolDisplayPartKind,
198759
198759
  SymbolFlags: () => SymbolFlags,
198760
198760
  SymbolFormatFlags: () => SymbolFormatFlags,
198761
- SyntaxKind: () => SyntaxKind18,
198761
+ SyntaxKind: () => SyntaxKind20,
198762
198762
  Ternary: () => Ternary,
198763
198763
  ThrottledCancellationToken: () => ThrottledCancellationToken,
198764
198764
  TokenClass: () => TokenClass,
@@ -293077,7 +293077,7 @@ function useColor() {
293077
293077
  var program = new Command();
293078
293078
 
293079
293079
  // src/main.ts
293080
- var import_ts_morph18 = __toESM(require_ts_morph(), 1);
293080
+ var import_ts_morph20 = __toESM(require_ts_morph(), 1);
293081
293081
 
293082
293082
  // src/facts/fact-emitter.ts
293083
293083
  init_esm_shims();
@@ -293206,6 +293206,21 @@ var NdjsonFactEmitter = class {
293206
293206
  emitHookDeclared(p) {
293207
293207
  this.emit("HookDeclared", p.hookId, p);
293208
293208
  }
293209
+ // ── Behavioural specification facts (Phase 0) ────────────
293210
+ // Seeded by the assertion/spec content hash so identical code + identical
293211
+ // corpus yield identical factIds — the predictability guarantee.
293212
+ emitBehaviouralAssertion(p) {
293213
+ this.emit("BehaviouralAssertion", p.assertionId, p);
293214
+ }
293215
+ emitBehaviouralSpec(p) {
293216
+ this.emit("BehaviouralSpec", p.specId, p);
293217
+ }
293218
+ emitValidationRuleObserved(p) {
293219
+ this.emit("ValidationRuleObserved", p.ruleId, p);
293220
+ }
293221
+ emitMethodLogicObserved(p) {
293222
+ this.emit("MethodLogicObserved", p.logicId, p);
293223
+ }
293209
293224
  emitCopybookResolved(p) {
293210
293225
  this.emit("CopybookResolved", p.copybookId, p);
293211
293226
  }
@@ -293598,6 +293613,7 @@ var RouteExtractor = class _RouteExtractor {
293598
293613
  }
293599
293614
  }
293600
293615
  this.extractExpressRoutes(sf, filePath, emitter);
293616
+ this.extractArrayRegisteredRoutes(sf, filePath, emitter);
293601
293617
  }
293602
293618
  }
293603
293619
  extractNestJsController(cls, filePath, emitter) {
@@ -293618,9 +293634,12 @@ var RouteExtractor = class _RouteExtractor {
293618
293634
  httpMethod,
293619
293635
  routePath: fullRoute,
293620
293636
  handlerType: controllerName,
293621
- handlerName: method.getName(),
293637
+ // Qualified so it matches the method-logic container and DAO callerSymbol.
293638
+ handlerName: `${controllerName}.${method.getName()}`,
293622
293639
  filePath,
293623
- startLine: method.getStartLineNumber()
293640
+ startLine: method.getStartLineNumber(),
293641
+ handlerStartLine: method.getStartLineNumber(),
293642
+ handlerEndLine: method.getEndLineNumber()
293624
293643
  });
293625
293644
  const requiresAuth = this.hasDecorator(method, "UseGuards") || this.hasDecorator(cls, "UseGuards");
293626
293645
  emitter.emitEndpointMetadata({
@@ -293675,6 +293694,9 @@ var RouteExtractor = class _RouteExtractor {
293675
293694
  if (httpMethod === "USE" || httpMethod === "ROUTE") continue;
293676
293695
  const fullRoute = this.normalisePath(routePath);
293677
293696
  const routeId = `route:${httpMethod.toLowerCase()}:${fullRoute}`;
293697
+ const handlerArg = args[args.length - 1];
293698
+ const hk = handlerArg.getKind();
293699
+ const inlineHandler = hk === import_ts_morph2.SyntaxKind.ArrowFunction || hk === import_ts_morph2.SyntaxKind.FunctionExpression;
293678
293700
  emitter.emitRouteDeclared({
293679
293701
  routeId,
293680
293702
  httpMethod,
@@ -293682,7 +293704,9 @@ var RouteExtractor = class _RouteExtractor {
293682
293704
  handlerType: "Express",
293683
293705
  handlerName: `${httpMethod.toLowerCase()}:${fullRoute}`,
293684
293706
  filePath,
293685
- startLine: call.getStartLineNumber()
293707
+ startLine: call.getStartLineNumber(),
293708
+ handlerStartLine: inlineHandler ? handlerArg.getStartLineNumber() : void 0,
293709
+ handlerEndLine: inlineHandler ? handlerArg.getEndLineNumber() : void 0
293686
293710
  });
293687
293711
  emitter.emitEndpointMetadata({
293688
293712
  routeId,
@@ -293724,6 +293748,92 @@ var RouteExtractor = class _RouteExtractor {
293724
293748
  }
293725
293749
  return text;
293726
293750
  }
293751
+ /**
293752
+ * Routes registered by iterating an array of paths:
293753
+ * const paths = ['/a','/b']; paths.forEach((p) => router.get(p, handler));
293754
+ * The per-element `router.get(p, …)` calls are skipped by extractExpressRoutes
293755
+ * (the path arg is a variable, not a literal), so resolve them here.
293756
+ */
293757
+ extractArrayRegisteredRoutes(sf, filePath, emitter) {
293758
+ for (const call of sf.getDescendantsOfKind(import_ts_morph2.SyntaxKind.CallExpression)) {
293759
+ const expr = call.getExpression();
293760
+ if (!import_ts_morph2.Node.isPropertyAccessExpression(expr)) continue;
293761
+ const iter = expr.getName();
293762
+ if (iter !== "forEach" && iter !== "map") continue;
293763
+ const cb = call.getArguments()[0];
293764
+ const cbk = cb?.getKind?.();
293765
+ if (cbk !== import_ts_morph2.SyntaxKind.ArrowFunction && cbk !== import_ts_morph2.SyntaxKind.FunctionExpression) continue;
293766
+ const params = cb.getParameters?.() ?? [];
293767
+ if (params.length === 0) continue;
293768
+ const loopVar = params[0].getName();
293769
+ const body = cb.getBody?.();
293770
+ if (!body) continue;
293771
+ const calls = [];
293772
+ if (body.getKind?.() === import_ts_morph2.SyntaxKind.CallExpression) calls.push(body);
293773
+ calls.push(...body.getDescendantsOfKind?.(import_ts_morph2.SyntaxKind.CallExpression) ?? []);
293774
+ let method = null;
293775
+ for (const ic of calls) {
293776
+ const ie = ic.getExpression();
293777
+ if (!import_ts_morph2.Node.isPropertyAccessExpression(ie)) continue;
293778
+ const m = ie.getName();
293779
+ if (!_RouteExtractor.EXPRESS_METHODS.has(m)) continue;
293780
+ const recv = ie.getExpression().getText();
293781
+ if (!recv.includes("app") && !recv.includes("router") && !recv.includes("server")) continue;
293782
+ const iargs = ic.getArguments();
293783
+ if (iargs.length < 1 || iargs[0].getText() !== loopVar) continue;
293784
+ method = m;
293785
+ break;
293786
+ }
293787
+ if (!method) continue;
293788
+ const httpMethod = method.toUpperCase();
293789
+ if (httpMethod === "USE" || httpMethod === "ROUTE") continue;
293790
+ for (const raw of this.resolveStringArray(expr.getExpression())) {
293791
+ const fullRoute = this.normalisePath(raw);
293792
+ const routeId = `route:${httpMethod.toLowerCase()}:${fullRoute}`;
293793
+ emitter.emitRouteDeclared({
293794
+ routeId,
293795
+ httpMethod,
293796
+ routePath: fullRoute,
293797
+ handlerType: "Express",
293798
+ handlerName: `${httpMethod.toLowerCase()}:${fullRoute}`,
293799
+ filePath,
293800
+ startLine: call.getStartLineNumber()
293801
+ });
293802
+ emitter.emitEndpointMetadata({
293803
+ routeId,
293804
+ operationId: null,
293805
+ tags: [],
293806
+ summary: null,
293807
+ responseTypes: [],
293808
+ requiresAuth: false,
293809
+ producesProblems: false
293810
+ });
293811
+ }
293812
+ }
293813
+ }
293814
+ /** Resolve an array expression (literal or a const-bound identifier) to its string elements. */
293815
+ resolveStringArray(node) {
293816
+ let arr = node;
293817
+ if (node?.getKind?.() === import_ts_morph2.SyntaxKind.Identifier) {
293818
+ const decls = node.getSymbol?.()?.getDeclarations?.() ?? [];
293819
+ for (const d of decls) {
293820
+ if (d.getKind?.() === import_ts_morph2.SyntaxKind.VariableDeclaration) {
293821
+ const init = d.getInitializer?.();
293822
+ if (init?.getKind?.() === import_ts_morph2.SyntaxKind.ArrayLiteralExpression) {
293823
+ arr = init;
293824
+ break;
293825
+ }
293826
+ }
293827
+ }
293828
+ }
293829
+ if (arr?.getKind?.() !== import_ts_morph2.SyntaxKind.ArrayLiteralExpression) return [];
293830
+ const out = [];
293831
+ for (const el of arr.getElements?.() ?? []) {
293832
+ const s = this.extractStringLiteral(el);
293833
+ if (s !== null) out.push(s);
293834
+ }
293835
+ return out;
293836
+ }
293727
293837
  extractStringLiteral(node) {
293728
293838
  const text = node.getText();
293729
293839
  if (text.startsWith("'") && text.endsWith("'") || text.startsWith('"') && text.endsWith('"')) {
@@ -295388,6 +295498,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
295388
295498
  if (paramFlows.length > 0) {
295389
295499
  this.applyParameterFlows(steps, paramFlows);
295390
295500
  }
295501
+ steps.push(...this.extractGuards(method, steps.length + 1));
295391
295502
  const payload = {
295392
295503
  operationId: `dao:${filePath}:${line}`,
295393
295504
  callerSymbol,
@@ -295414,6 +295525,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
295414
295525
  const steps = this.extractSteps(ormCalls, filePath);
295415
295526
  const semanticKind = this.inferSemanticKind(steps);
295416
295527
  const targetEntity = this.inferTargetEntity(ormCalls);
295528
+ steps.push(...this.extractGuards(func, steps.length + 1));
295417
295529
  const returnType = func.getReturnType()?.getText() ?? null;
295418
295530
  const returnsCollection = returnType ? /\[\]|Array/.test(returnType) : null;
295419
295531
  const transactionScope = this.detectFunctionTransactionScope(func);
@@ -295442,6 +295554,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
295442
295554
  const steps = this.extractSteps(ormCalls, filePath);
295443
295555
  const semanticKind = this.inferSemanticKind(steps);
295444
295556
  const targetEntity = this.inferTargetEntity(ormCalls);
295557
+ steps.push(...this.extractGuards(arrow, steps.length + 1));
295445
295558
  const payload = {
295446
295559
  operationId: `dao:${filePath}:${line}`,
295447
295560
  callerSymbol: name,
@@ -295495,6 +295608,39 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
295495
295608
  }
295496
295609
  return steps;
295497
295610
  }
295611
+ // ── Guard extraction (Phase 1.5: feeds HXL invariants) ────────────
295612
+ // Capture `if (cond) throw|return` early-exit guards inside a data-access
295613
+ // body as guard steps carrying the condition text. The deriver lowers each
295614
+ // predicateExpression through HXL into a static invariant.
295615
+ extractGuards(node, startOrder) {
295616
+ const out = [];
295617
+ let order = startOrder;
295618
+ let ifs = [];
295619
+ try {
295620
+ ifs = node.getDescendantsOfKind(import_ts_morph6.SyntaxKind.IfStatement);
295621
+ } catch {
295622
+ return out;
295623
+ }
295624
+ for (const ifStmt of ifs) {
295625
+ const then = ifStmt.getThenStatement?.();
295626
+ if (!then) continue;
295627
+ const stmts = then.getKind?.() === import_ts_morph6.SyntaxKind.Block ? then.getStatements() : [then];
295628
+ const exit = stmts.find(
295629
+ (s) => s.getKind() === import_ts_morph6.SyntaxKind.ThrowStatement || s.getKind() === import_ts_morph6.SyntaxKind.ReturnStatement
295630
+ );
295631
+ if (!exit) continue;
295632
+ const cond = ifStmt.getExpression?.()?.getText?.();
295633
+ if (!cond) continue;
295634
+ const isThrow = exit.getKind() === import_ts_morph6.SyntaxKind.ThrowStatement;
295635
+ let thrown = null;
295636
+ if (isThrow) {
295637
+ const e = exit.getExpression?.();
295638
+ thrown = e ? e.getText() : null;
295639
+ }
295640
+ out.push({ order: order++, kind: "guard", predicateExpression: cond, throwsOnFail: isThrow, sourceExpression: thrown });
295641
+ }
295642
+ return out;
295643
+ }
295498
295644
  mapMethodToStep(method, call, order, filePath) {
295499
295645
  const args = call.getArguments();
295500
295646
  const firstArgText = args.length > 0 ? args[0].getText() : null;
@@ -298112,6 +298258,169 @@ var SqlObjectDeclaredExtractor = class {
298112
298258
  }
298113
298259
  };
298114
298260
 
298261
+ // src/extractors/validation-schema.ts
298262
+ init_esm_shims();
298263
+ var import_ts_morph18 = __toESM(require_ts_morph(), 1);
298264
+ var ValidationSchemaExtractor = class {
298265
+ async extract(sourceFiles, emitter) {
298266
+ const seen = /* @__PURE__ */ new Set();
298267
+ for (const sf of sourceFiles) {
298268
+ const filePath = sf.getFilePath();
298269
+ const calls = sf.getDescendantsOfKind(import_ts_morph18.SyntaxKind.CallExpression);
298270
+ for (const call of calls) {
298271
+ const exprText = call.getExpression().getText();
298272
+ if (exprText !== "z.object" && exprText !== "zod.object") continue;
298273
+ const args = call.getArguments();
298274
+ if (args.length === 0 || args[0].getKind() !== import_ts_morph18.SyntaxKind.ObjectLiteralExpression) continue;
298275
+ const schemaName = this.resolveSchemaName(call);
298276
+ const obj = args[0];
298277
+ for (const prop of obj.getProperties()) {
298278
+ if (prop.getKind() !== import_ts_morph18.SyntaxKind.PropertyAssignment) continue;
298279
+ const fieldName = prop.getName?.();
298280
+ const init = prop.getInitializer?.();
298281
+ if (!fieldName || !init) continue;
298282
+ const parsed = this.parseZodChain(init);
298283
+ if (!parsed) continue;
298284
+ const line = prop.getStartLineNumber();
298285
+ for (const r of parsed.rules) {
298286
+ const ruleId = `${schemaName}:${fieldName}:${r.rule}:${r.arg ?? ""}`;
298287
+ if (seen.has(ruleId)) continue;
298288
+ seen.add(ruleId);
298289
+ emitter.emitValidationRuleObserved({
298290
+ ruleId,
298291
+ schemaName,
298292
+ fieldName,
298293
+ fieldType: parsed.baseType,
298294
+ rule: r.rule,
298295
+ arg: r.arg,
298296
+ framework: "zod",
298297
+ filePath,
298298
+ line
298299
+ });
298300
+ }
298301
+ }
298302
+ }
298303
+ }
298304
+ }
298305
+ /** Walk up to the VariableDeclaration holding the z.object, for a schema name. */
298306
+ resolveSchemaName(call) {
298307
+ let node = call;
298308
+ for (let i = 0; i < 8 && node; i++) {
298309
+ node = node.getParent?.();
298310
+ if (node?.getKind?.() === import_ts_morph18.SyntaxKind.VariableDeclaration) {
298311
+ return node.getName?.() ?? "<anonymous>";
298312
+ }
298313
+ }
298314
+ return "<anonymous>";
298315
+ }
298316
+ /** Peel a zod method chain into a base type + ordered rules. */
298317
+ parseZodChain(node) {
298318
+ const rules = [];
298319
+ let baseType = "unknown";
298320
+ let cur = node;
298321
+ for (let guard = 0; guard < 50 && cur; guard++) {
298322
+ if (cur.getKind?.() !== import_ts_morph18.SyntaxKind.CallExpression) break;
298323
+ const callExpr = cur.getExpression?.();
298324
+ if (!callExpr || callExpr.getKind() !== import_ts_morph18.SyntaxKind.PropertyAccessExpression) break;
298325
+ const method = callExpr.getName();
298326
+ const obj = callExpr.getExpression();
298327
+ const objText = obj.getText?.();
298328
+ if (obj.getKind() === import_ts_morph18.SyntaxKind.Identifier && (objText === "z" || objText === "zod")) {
298329
+ baseType = method;
298330
+ break;
298331
+ }
298332
+ const args = cur.getArguments?.() ?? [];
298333
+ const arg = args.length > 0 ? args[0].getText().replace(/_/g, "") : null;
298334
+ rules.push({ rule: method, arg });
298335
+ cur = obj;
298336
+ }
298337
+ rules.reverse();
298338
+ return { baseType, rules };
298339
+ }
298340
+ };
298341
+
298342
+ // src/extractors/method-logic.ts
298343
+ init_esm_shims();
298344
+ var import_ts_morph19 = __toESM(require_ts_morph(), 1);
298345
+ var MethodLogicExtractor = class {
298346
+ async extract(sourceFiles, emitter) {
298347
+ for (const sf of sourceFiles) {
298348
+ const filePath = sf.getFilePath();
298349
+ const seen = /* @__PURE__ */ new Set();
298350
+ for (const ifStmt of sf.getDescendantsOfKind(import_ts_morph19.SyntaxKind.IfStatement)) {
298351
+ const then = ifStmt.getThenStatement();
298352
+ if (!then) continue;
298353
+ const stmts = then.getKind() === import_ts_morph19.SyntaxKind.Block ? then.getStatements() : [then];
298354
+ const exit = stmts.find(
298355
+ (s) => s.getKind() === import_ts_morph19.SyntaxKind.ThrowStatement || s.getKind() === import_ts_morph19.SyntaxKind.ReturnStatement
298356
+ );
298357
+ if (!exit) continue;
298358
+ const cond = ifStmt.getExpression()?.getText();
298359
+ if (!cond) continue;
298360
+ const isThrow = exit.getKind() === import_ts_morph19.SyntaxKind.ThrowStatement;
298361
+ const container = this.containerOf(ifStmt);
298362
+ const line = ifStmt.getStartLineNumber();
298363
+ const logicId = `${container}:guard:${line}`;
298364
+ if (seen.has(logicId)) continue;
298365
+ seen.add(logicId);
298366
+ emitter.emitMethodLogicObserved({
298367
+ logicId,
298368
+ containerSymbol: container,
298369
+ kind: "guard",
298370
+ expression: cond,
298371
+ effect: isThrow ? "throw" : "return",
298372
+ throwsType: isThrow ? exit.getExpression?.()?.getText() ?? null : null,
298373
+ filePath,
298374
+ line
298375
+ });
298376
+ }
298377
+ for (const ret of sf.getDescendantsOfKind(import_ts_morph19.SyntaxKind.ReturnStatement)) {
298378
+ const expr = ret.getExpression();
298379
+ if (!expr) continue;
298380
+ const k = expr.getKind();
298381
+ if (k !== import_ts_morph19.SyntaxKind.BinaryExpression && k !== import_ts_morph19.SyntaxKind.ConditionalExpression) continue;
298382
+ const container = this.containerOf(ret);
298383
+ const line = ret.getStartLineNumber();
298384
+ const logicId = `${container}:return:${line}`;
298385
+ if (seen.has(logicId)) continue;
298386
+ seen.add(logicId);
298387
+ emitter.emitMethodLogicObserved({
298388
+ logicId,
298389
+ containerSymbol: container,
298390
+ kind: "return",
298391
+ expression: expr.getText(),
298392
+ effect: null,
298393
+ throwsType: null,
298394
+ filePath,
298395
+ line
298396
+ });
298397
+ }
298398
+ }
298399
+ }
298400
+ /** Resolve the qualified symbol of the enclosing function/method. */
298401
+ containerOf(node) {
298402
+ let n = node;
298403
+ for (let i = 0; i < 30 && n; i++) {
298404
+ n = n.getParent?.();
298405
+ if (!n) break;
298406
+ const k = n.getKind?.();
298407
+ if (k === import_ts_morph19.SyntaxKind.MethodDeclaration) {
298408
+ const cls = n.getFirstAncestorByKind?.(import_ts_morph19.SyntaxKind.ClassDeclaration);
298409
+ const clsName = cls?.getName?.() ?? "<anon>";
298410
+ return `${clsName}.${n.getName?.() ?? "<anon>"}`;
298411
+ }
298412
+ if (k === import_ts_morph19.SyntaxKind.FunctionDeclaration) {
298413
+ return n.getName?.() ?? "<anon>";
298414
+ }
298415
+ if (k === import_ts_morph19.SyntaxKind.ArrowFunction || k === import_ts_morph19.SyntaxKind.FunctionExpression) {
298416
+ const vd = n.getFirstAncestorByKind?.(import_ts_morph19.SyntaxKind.VariableDeclaration);
298417
+ if (vd) return vd.getName?.() ?? "<anon>";
298418
+ }
298419
+ }
298420
+ return "<module>";
298421
+ }
298422
+ };
298423
+
298115
298424
  // src/extractors/swift-api-calls.ts
298116
298425
  init_esm_shims();
298117
298426
  var SwiftApiCallExtractor = class {
@@ -373173,13 +373482,13 @@ function emitProgress(event) {
373173
373482
  }
373174
373483
  function createProject(projectPath) {
373175
373484
  if (projectPath.endsWith("tsconfig.json")) {
373176
- return new import_ts_morph18.Project({ tsConfigFilePath: projectPath });
373485
+ return new import_ts_morph20.Project({ tsConfigFilePath: projectPath });
373177
373486
  }
373178
373487
  const tsconfigPath = resolve2(projectPath, "tsconfig.json");
373179
373488
  if (existsSync3(tsconfigPath)) {
373180
- return new import_ts_morph18.Project({ tsConfigFilePath: tsconfigPath });
373489
+ return new import_ts_morph20.Project({ tsConfigFilePath: tsconfigPath });
373181
373490
  }
373182
- const project = new import_ts_morph18.Project({
373491
+ const project = new import_ts_morph20.Project({
373183
373492
  compilerOptions: {
373184
373493
  allowJs: true,
373185
373494
  checkJs: false,
@@ -373223,6 +373532,8 @@ async function runExtractors(sourceFiles, emitter) {
373223
373532
  new EventConsumedExtractor(),
373224
373533
  new ExternalServiceCallExtractor(),
373225
373534
  new SqlObjectDeclaredExtractor(),
373535
+ new ValidationSchemaExtractor(),
373536
+ new MethodLogicExtractor(),
373226
373537
  // Frontend / UI extractors
373227
373538
  new ComponentExtractor(),
373228
373539
  new ClientRouteExtractor(),
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  formatText,
6
6
  generateFindings,
7
7
  runScan
8
- } from "./chunk-RPI2K62L.js";
9
- import "./chunk-74ZJFYEM.js";
8
+ } from "./chunk-BOGC5GYS.js";
9
+ import "./chunk-5IXVOEZN.js";
10
10
  import "./chunk-C7LU6YIL.js";
11
11
  import "./chunk-JSBRDJBE.js";
12
12
  export {
@@ -1,5 +1,5 @@
1
1
  import {
2
2
  require_semver
3
- } from "./chunk-74ZJFYEM.js";
3
+ } from "./chunk-5IXVOEZN.js";
4
4
  import "./chunk-JSBRDJBE.js";
5
5
  export default require_semver();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibgrate/cli",
3
- "version": "2026.613.1",
3
+ "version": "2026.615.2",
4
4
  "description": "CLI for measuring upgrade drift across Node, .NET, Python & Java projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,11 +47,11 @@
47
47
  "license": "SEE LICENSE IN LICENSE",
48
48
  "homepage": "https://vibgrate.com",
49
49
  "devDependencies": {
50
- "@types/node": "^25.9.2",
50
+ "@types/node": "^25.9.3",
51
51
  "@types/semver": "^7.5.0",
52
- "eslint": "^9.0.0",
53
- "fast-xml-parser": "^4.3.0",
54
- "semver": "^7.6.0",
52
+ "eslint": "^10.5.0",
53
+ "fast-xml-parser": "^5.9.0",
54
+ "semver": "^7.8.4",
55
55
  "tsup": "^8.0.0",
56
56
  "tsx": "^4.22.4",
57
57
  "vitest": "^2.0.0"