technical-debt-radar 1.0.8 → 1.1.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.
Files changed (2) hide show
  1. package/dist/index.js +72 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18204,6 +18204,16 @@ var require_dead_code_detector = __commonJS({
18204
18204
  if (project.getSourceFile("/" + indexPath))
18205
18205
  return indexPath;
18206
18206
  }
18207
+ const suffix = "/" + resolved;
18208
+ for (const sf of project.getSourceFiles()) {
18209
+ const fp = sf.getFilePath();
18210
+ if (fp.endsWith(suffix))
18211
+ return normalizeFilePath(fp);
18212
+ for (const ext of extensions) {
18213
+ if (fp.endsWith(suffix + ext))
18214
+ return normalizeFilePath(fp);
18215
+ }
18216
+ }
18207
18217
  return void 0;
18208
18218
  }
18209
18219
  function posixDirname(filePath) {
@@ -19200,6 +19210,9 @@ function buildEnhancedPRCommentMarkdown(data) {
19200
19210
  return lines.join("\n");
19201
19211
  }
19202
19212
 
19213
+ // src/commands/scan.ts
19214
+ var import_child_process = require("child_process");
19215
+
19203
19216
  // src/auth/config.ts
19204
19217
  var fs = __toESM(require("fs"));
19205
19218
  var path = __toESM(require("path"));
@@ -19283,6 +19296,30 @@ var RadarApiClient = class _RadarApiClient {
19283
19296
  };
19284
19297
 
19285
19298
  // src/commands/scan.ts
19299
+ function getGitBranch() {
19300
+ try {
19301
+ return (0, import_child_process.execSync)("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
19302
+ } catch {
19303
+ return "unknown";
19304
+ }
19305
+ }
19306
+ function getGitCommit() {
19307
+ try {
19308
+ return (0, import_child_process.execSync)("git rev-parse HEAD", { encoding: "utf-8" }).trim();
19309
+ } catch {
19310
+ return "unknown";
19311
+ }
19312
+ }
19313
+ function buildTopHotspots(violations) {
19314
+ const byFile = /* @__PURE__ */ new Map();
19315
+ for (const v of violations) {
19316
+ const entry = byFile.get(v.file) ?? { violations: 0, debtPoints: 0 };
19317
+ entry.violations++;
19318
+ entry.debtPoints += v.debtPoints;
19319
+ byFile.set(v.file, entry);
19320
+ }
19321
+ return Array.from(byFile.entries()).map(([file, data]) => ({ file, ...data })).sort((a, b) => b.debtPoints - a.debtPoints).slice(0, 10);
19322
+ }
19286
19323
  var ANON_SCAN_DIR = path2.join(os2.homedir(), ".radar");
19287
19324
  var ANON_SCAN_FILE = path2.join(ANON_SCAN_DIR, ".anonymous-scan");
19288
19325
  function checkAnonymousScanAllowed() {
@@ -19341,16 +19378,15 @@ async function enforceAuth(allowAnonymous = false) {
19341
19378
  try {
19342
19379
  scanCheck = await client.checkScanQuota();
19343
19380
  } catch {
19344
- console.error(import_chalk.default.red("Cannot verify scan quota. Check your internet connection.\n"));
19345
- process.exit(1);
19381
+ return { client, isAnonymous: false };
19346
19382
  }
19347
19383
  if (!scanCheck.allowed) {
19348
- console.error(import_chalk.default.red(`${scanCheck.message}
19349
- `));
19350
- if (scanCheck.upgradeUrl) {
19351
- console.error(`Upgrade: ${import_chalk.default.cyan(scanCheck.upgradeUrl)}
19384
+ const resetInfo = scanCheck.resetsAt ? ` Resets ${scanCheck.resetsAt}.` : "";
19385
+ console.error(import_chalk.default.red(
19386
+ `\u274C Monthly scan limit reached (${scanCheck.scansUsed}/${scanCheck.scanLimit}).${resetInfo}`
19387
+ ));
19388
+ console.error(`Upgrade: ${import_chalk.default.cyan("radar upgrade")}
19352
19389
  `);
19353
- }
19354
19390
  process.exit(1);
19355
19391
  }
19356
19392
  return { client, isAnonymous: false };
@@ -19467,15 +19503,39 @@ async function scanCommand(targetPath, options) {
19467
19503
  printAnonymousScanCTA();
19468
19504
  }
19469
19505
  if (client) {
19470
- client.reportScan({
19506
+ const blocking = result.violations.filter((v) => v.gateAction === "block");
19507
+ const warns = result.violations.filter((v) => v.gateAction === "warn");
19508
+ const byCat = countByCategory(result.violations);
19509
+ const reportData = {
19471
19510
  repoName: path2.basename(path2.resolve(targetPath)),
19472
- violations: result.violations.length,
19473
- score: breakdown.total,
19511
+ violations: result.violations.map((v) => ({
19512
+ file: v.file,
19513
+ line: v.line,
19514
+ ruleId: v.ruleId,
19515
+ message: v.message,
19516
+ severity: v.severity,
19517
+ category: v.category,
19518
+ debtPoints: v.debtPoints,
19519
+ gateAction: v.gateAction
19520
+ })),
19521
+ debtScore: breakdown.total,
19522
+ filesScanned: files.length,
19523
+ blocking: blocking.length,
19524
+ warnings: warns.length,
19525
+ categoryBreakdown: byCat,
19526
+ topHotspots: buildTopHotspots(result.violations),
19527
+ branch: getGitBranch(),
19528
+ commit: getGitCommit(),
19474
19529
  duration: Date.now() - scanStart,
19475
19530
  usedAi: shouldRunAi,
19476
19531
  aiCreditsUsed: 0
19477
- }).catch(() => {
19478
- });
19532
+ };
19533
+ try {
19534
+ await client.reportScan(reportData);
19535
+ console.log(import_chalk.default.green(" \u2713 Results synced to dashboard: https://www.technicaldebtradar.com/dashboard"));
19536
+ } catch {
19537
+ console.log(import_chalk.default.yellow(" \u26A0\uFE0F Could not sync results to dashboard. Check your connection."));
19538
+ }
19479
19539
  }
19480
19540
  if (mode === "warn") {
19481
19541
  if (gateEval.gateWouldFail) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "Stop Node.js production crashes before merge. 47 detection patterns across 5 categories.",
5
5
  "bin": {
6
6
  "radar": "dist/index.js",