@vibgrate/cli 1.0.34 → 1.0.36

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.
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  baselineCommand,
3
3
  runBaseline
4
- } from "./chunk-QTXDBNC3.js";
5
- import "./chunk-6ZVFF5SX.js";
4
+ } from "./chunk-WTDN6R27.js";
5
+ import "./chunk-CQZ7XQQJ.js";
6
6
  export {
7
7
  baselineCommand,
8
8
  runBaseline
@@ -462,6 +462,32 @@ async function quickTreeCount(rootDir, excludePatterns) {
462
462
  await count(rootDir);
463
463
  return { totalFiles, totalDirs };
464
464
  }
465
+ async function countFilesInDir(dir, recursive = true) {
466
+ let count = 0;
467
+ const extraSkip = /* @__PURE__ */ new Set(["obj", "bin", "Debug", "Release", "TestResults"]);
468
+ async function walk(currentDir) {
469
+ let entries;
470
+ try {
471
+ entries = await fs.readdir(currentDir, { withFileTypes: true });
472
+ } catch {
473
+ return;
474
+ }
475
+ const subs = [];
476
+ for (const e of entries) {
477
+ if (e.isDirectory()) {
478
+ if (!recursive) continue;
479
+ if (SKIP_DIRS.has(e.name) || extraSkip.has(e.name)) continue;
480
+ subs.push(walk(path2.join(currentDir, e.name)));
481
+ } else if (e.isFile()) {
482
+ const ext = path2.extname(e.name).toLowerCase();
483
+ if (!SKIP_EXTENSIONS.has(ext)) count++;
484
+ }
485
+ }
486
+ await Promise.all(subs);
487
+ }
488
+ await walk(dir);
489
+ return count;
490
+ }
465
491
  async function findFiles(rootDir, predicate) {
466
492
  const results = [];
467
493
  const cores = typeof os.availableParallelism === "function" ? os.availableParallelism() : os.cpus().length || 4;
@@ -1866,6 +1892,7 @@ var KNOWN_FRAMEWORKS = {
1866
1892
  async function scanNodeProjects(rootDir, npmCache, cache) {
1867
1893
  const packageJsonFiles = cache ? await cache.findPackageJsonFiles(rootDir) : await findPackageJsonFiles(rootDir);
1868
1894
  const results = [];
1895
+ const packageNameToPath = /* @__PURE__ */ new Map();
1869
1896
  const STUCK_TIMEOUT_MS = 6e4;
1870
1897
  for (const pjPath of packageJsonFiles) {
1871
1898
  try {
@@ -1873,6 +1900,7 @@ async function scanNodeProjects(rootDir, npmCache, cache) {
1873
1900
  const result = await withTimeout(scanPromise, STUCK_TIMEOUT_MS);
1874
1901
  if (result.ok) {
1875
1902
  results.push(result.value);
1903
+ packageNameToPath.set(result.value.name, result.value.path);
1876
1904
  } else {
1877
1905
  const relPath = path5.relative(rootDir, path5.dirname(pjPath));
1878
1906
  if (cache) {
@@ -1885,6 +1913,22 @@ async function scanNodeProjects(rootDir, npmCache, cache) {
1885
1913
  console.error(`Error scanning ${pjPath}: ${msg}`);
1886
1914
  }
1887
1915
  }
1916
+ for (const project of results) {
1917
+ const workspaceRefs = [];
1918
+ for (const dep of project.dependencies) {
1919
+ const depPath = packageNameToPath.get(dep.package);
1920
+ if (depPath && depPath !== project.path) {
1921
+ workspaceRefs.push({
1922
+ path: depPath,
1923
+ name: dep.package,
1924
+ refType: "workspace"
1925
+ });
1926
+ }
1927
+ }
1928
+ if (workspaceRefs.length > 0) {
1929
+ project.projectReferences = workspaceRefs;
1930
+ }
1931
+ }
1888
1932
  return results;
1889
1933
  }
1890
1934
  async function scanOnePackageJson(packageJsonPath, rootDir, npmCache, cache) {
@@ -1969,6 +2013,11 @@ async function scanOnePackageJson(packageJsonPath, rootDir, npmCache, cache) {
1969
2013
  if (diff !== 0) return diff;
1970
2014
  return a.package.localeCompare(b.package);
1971
2015
  });
2016
+ let fileCount;
2017
+ try {
2018
+ fileCount = await countFilesInDir(absProjectPath);
2019
+ } catch {
2020
+ }
1972
2021
  return {
1973
2022
  type: "node",
1974
2023
  path: projectPath,
@@ -1978,7 +2027,8 @@ async function scanOnePackageJson(packageJsonPath, rootDir, npmCache, cache) {
1978
2027
  runtimeMajorsBehind,
1979
2028
  frameworks,
1980
2029
  dependencies,
1981
- dependencyAgeBuckets: buckets
2030
+ dependencyAgeBuckets: buckets,
2031
+ fileCount
1982
2032
  };
1983
2033
  }
1984
2034
 
@@ -2184,7 +2234,7 @@ function parseCsproj(xml, filePath) {
2184
2234
  const parsed = parser.parse(xml);
2185
2235
  const project = parsed?.Project;
2186
2236
  if (!project) {
2187
- return { targetFrameworks: [], packageReferences: [], projectName: path6.basename(filePath, ".csproj") };
2237
+ return { targetFrameworks: [], packageReferences: [], projectReferences: [], projectName: path6.basename(filePath, ".csproj") };
2188
2238
  }
2189
2239
  const propertyGroups = Array.isArray(project.PropertyGroup) ? project.PropertyGroup : project.PropertyGroup ? [project.PropertyGroup] : [];
2190
2240
  const targetFrameworks = [];
@@ -2199,19 +2249,28 @@ function parseCsproj(xml, filePath) {
2199
2249
  }
2200
2250
  const itemGroups = Array.isArray(project.ItemGroup) ? project.ItemGroup : project.ItemGroup ? [project.ItemGroup] : [];
2201
2251
  const packageReferences = [];
2252
+ const projectReferences = [];
2202
2253
  for (const ig of itemGroups) {
2203
- const refs = Array.isArray(ig.PackageReference) ? ig.PackageReference : ig.PackageReference ? [ig.PackageReference] : [];
2204
- for (const ref of refs) {
2254
+ const pkgRefs = Array.isArray(ig.PackageReference) ? ig.PackageReference : ig.PackageReference ? [ig.PackageReference] : [];
2255
+ for (const ref of pkgRefs) {
2205
2256
  const name = ref["@_Include"] ?? ref["@_include"] ?? "";
2206
2257
  const version = ref["@_Version"] ?? ref["@_version"] ?? ref.Version ?? "";
2207
2258
  if (name && version) {
2208
2259
  packageReferences.push({ name: String(name), version: String(version) });
2209
2260
  }
2210
2261
  }
2262
+ const projRefs = Array.isArray(ig.ProjectReference) ? ig.ProjectReference : ig.ProjectReference ? [ig.ProjectReference] : [];
2263
+ for (const ref of projRefs) {
2264
+ const include = ref["@_Include"] ?? ref["@_include"] ?? "";
2265
+ if (include) {
2266
+ projectReferences.push(String(include).replace(/\\/g, "/"));
2267
+ }
2268
+ }
2211
2269
  }
2212
2270
  return {
2213
2271
  targetFrameworks: [...new Set(targetFrameworks)],
2214
2272
  packageReferences,
2273
+ projectReferences,
2215
2274
  projectName: path6.basename(filePath, ".csproj")
2216
2275
  };
2217
2276
  }
@@ -2260,6 +2319,7 @@ async function scanDotnetProjects(rootDir, cache) {
2260
2319
  async function scanOneCsproj(csprojPath, rootDir, cache) {
2261
2320
  const xml = cache ? await cache.readTextFile(csprojPath) : await readTextFile(csprojPath);
2262
2321
  const data = parseCsproj(xml, csprojPath);
2322
+ const csprojDir = path6.dirname(csprojPath);
2263
2323
  const primaryTfm = data.targetFrameworks[0];
2264
2324
  let runtimeMajorsBehind;
2265
2325
  let targetFramework = primaryTfm;
@@ -2290,10 +2350,25 @@ async function scanOneCsproj(csprojPath, rootDir, cache) {
2290
2350
  });
2291
2351
  }
2292
2352
  }
2353
+ const projectReferences = data.projectReferences.map((refPath) => {
2354
+ const absRefPath = path6.resolve(csprojDir, refPath);
2355
+ const relRefPath = path6.relative(rootDir, path6.dirname(absRefPath));
2356
+ const refName = path6.basename(absRefPath, ".csproj");
2357
+ return {
2358
+ path: relRefPath || ".",
2359
+ name: refName,
2360
+ refType: "project"
2361
+ };
2362
+ });
2363
+ let fileCount;
2364
+ try {
2365
+ fileCount = await countFilesInDir(csprojDir);
2366
+ } catch {
2367
+ }
2293
2368
  const buckets = { current: 0, oneBehind: 0, twoPlusBehind: 0, unknown: dependencies.length };
2294
2369
  return {
2295
2370
  type: "dotnet",
2296
- path: path6.relative(rootDir, path6.dirname(csprojPath)) || ".",
2371
+ path: path6.relative(rootDir, csprojDir) || ".",
2297
2372
  name: data.projectName,
2298
2373
  targetFramework,
2299
2374
  runtime: primaryTfm,
@@ -2301,7 +2376,9 @@ async function scanOneCsproj(csprojPath, rootDir, cache) {
2301
2376
  runtimeMajorsBehind,
2302
2377
  frameworks,
2303
2378
  dependencies,
2304
- dependencyAgeBuckets: buckets
2379
+ dependencyAgeBuckets: buckets,
2380
+ projectReferences: projectReferences.length > 0 ? projectReferences : void 0,
2381
+ fileCount
2305
2382
  };
2306
2383
  }
2307
2384
 
@@ -2684,6 +2761,9 @@ var ScanProgress = class {
2684
2761
 
2685
2762
  `)
2686
2763
  );
2764
+ if (this.isTTY && process.platform === "win32") {
2765
+ process.stdout.write("\x1B[0G\x1B[K");
2766
+ }
2687
2767
  }
2688
2768
  // ── Internal rendering ──
2689
2769
  startSpinner() {
@@ -6540,12 +6620,13 @@ async function autoPush(artifact, rootDir, opts) {
6540
6620
  console.log(chalk6.green("\u2714") + ` Uploaded successfully (${result.ingestId ?? "ok"})`);
6541
6621
  if (result.ingestId) {
6542
6622
  const dashUrl = `https://dash.vibgrate.com/${parsed.workspaceId}/scan/${result.ingestId}`;
6623
+ const CR = process.platform === "win32" ? "\r" : "";
6543
6624
  console.log("");
6544
6625
  console.log("");
6545
- console.log(chalk6.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
6546
- console.log(chalk6.cyan("\u2551") + chalk6.bold(" \u{1F4CA} View Scan Report ") + chalk6.cyan("\u2551"));
6547
- console.log(chalk6.cyan("\u2551") + " " + chalk6.underline.cyan(dashUrl) + " ".repeat(Math.max(0, 67 - dashUrl.length)) + chalk6.cyan("\u2551"));
6548
- console.log(chalk6.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
6626
+ console.log(CR + chalk6.cyan("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
6627
+ console.log(CR + chalk6.bold(" \u{1F4CA} View Scan Report"));
6628
+ console.log(CR + " " + chalk6.underline.cyan(dashUrl));
6629
+ console.log(CR + chalk6.cyan("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
6549
6630
  console.log("");
6550
6631
  console.log("");
6551
6632
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  runScan,
3
3
  writeJsonFile
4
- } from "./chunk-6ZVFF5SX.js";
4
+ } from "./chunk-CQZ7XQQJ.js";
5
5
 
6
6
  // src/commands/baseline.ts
7
7
  import * as path from "path";
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-GN3IWKSY.js";
5
5
  import {
6
6
  baselineCommand
7
- } from "./chunk-QTXDBNC3.js";
7
+ } from "./chunk-WTDN6R27.js";
8
8
  import {
9
9
  VERSION,
10
10
  dsnCommand,
@@ -15,7 +15,7 @@ import {
15
15
  readJsonFile,
16
16
  scanCommand,
17
17
  writeDefaultConfig
18
- } from "./chunk-6ZVFF5SX.js";
18
+ } from "./chunk-CQZ7XQQJ.js";
19
19
 
20
20
  // src/cli.ts
21
21
  import { Command as Command4 } from "commander";
@@ -38,7 +38,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
38
38
  console.log(chalk.green("\u2714") + ` Created ${chalk.bold("vibgrate.config.ts")}`);
39
39
  }
40
40
  if (opts.baseline) {
41
- const { runBaseline } = await import("./baseline-VJRWLSAP.js");
41
+ const { runBaseline } = await import("./baseline-LK4IPTNC.js");
42
42
  await runBaseline(rootDir);
43
43
  }
44
44
  console.log("");
package/dist/index.d.ts CHANGED
@@ -17,6 +17,14 @@ interface DetectedFramework {
17
17
  latestVersion: string | null;
18
18
  majorsBehind: number | null;
19
19
  }
20
+ interface ProjectReference {
21
+ /** Relative path to the referenced project from the root */
22
+ path: string;
23
+ /** Project name (derived from path or manifest) */
24
+ name: string;
25
+ /** Type of reference: 'project' for .NET ProjectReference, 'workspace' for npm workspace dep */
26
+ refType: 'project' | 'workspace';
27
+ }
20
28
  interface ProjectScan {
21
29
  type: ProjectType;
22
30
  path: string;
@@ -37,6 +45,10 @@ interface ProjectScan {
37
45
  };
38
46
  /** Individual project drift score (computed per-project, then aggregated into artifact.drift) */
39
47
  drift?: DriftScore;
48
+ /** References to other projects in the same repository (internal dependencies) */
49
+ projectReferences?: ProjectReference[];
50
+ /** Number of source files in the project directory */
51
+ fileCount?: number;
40
52
  }
41
53
  interface DriftScore {
42
54
  score: number;
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  formatText,
8
8
  generateFindings,
9
9
  runScan
10
- } from "./chunk-6ZVFF5SX.js";
10
+ } from "./chunk-CQZ7XQQJ.js";
11
11
  export {
12
12
  computeDriftScore,
13
13
  formatMarkdown,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibgrate/cli",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "description": "CLI for measuring upgrade drift across Node & .NET projects",
5
5
  "type": "module",
6
6
  "bin": {