sickbay 1.12.0 → 1.13.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Header
3
- } from "./chunk-YAGUN3VM.js";
3
+ } from "./chunk-KMO5PHVP.js";
4
4
  import "./chunk-JSBRDJBE.js";
5
5
 
6
6
  // src/components/DiffApp.tsx
@@ -120,7 +120,7 @@ function DiffApp({ projectPath, branch, jsonOutput, checks, verbose }) {
120
120
  useEffect(() => {
121
121
  (async () => {
122
122
  try {
123
- const { runSickbay } = await import("./dist-FNOE2KCN.js");
123
+ const { runSickbay } = await import("./dist-6ZVGDRA5.js");
124
124
  const currentReport = await runSickbay({
125
125
  projectPath,
126
126
  checks,
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  shortName
3
- } from "./chunk-FEM4GJAY.js";
3
+ } from "./chunk-S5UHV6SX.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-YAGUN3VM.js";
6
+ } from "./chunk-KMO5PHVP.js";
7
7
  import {
8
8
  detectPackageManager,
9
9
  detectProject
10
- } from "./chunk-YHFU2XTS.js";
10
+ } from "./chunk-QZHCVNMM.js";
11
11
  import "./chunk-JSBRDJBE.js";
12
12
 
13
13
  // src/components/DoctorApp.tsx
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  shortName
3
- } from "./chunk-FEM4GJAY.js";
3
+ } from "./chunk-S5UHV6SX.js";
4
4
  import {
5
5
  ProgressList
6
6
  } from "./chunk-MBVA75EM.js";
7
7
  import {
8
8
  Header
9
- } from "./chunk-YAGUN3VM.js";
9
+ } from "./chunk-KMO5PHVP.js";
10
10
  import {
11
11
  runSickbay
12
- } from "./chunk-YHFU2XTS.js";
12
+ } from "./chunk-QZHCVNMM.js";
13
13
  import "./chunk-JSBRDJBE.js";
14
14
 
15
15
  // src/components/FixApp.tsx
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  shortName
3
- } from "./chunk-FEM4GJAY.js";
3
+ } from "./chunk-S5UHV6SX.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-YAGUN3VM.js";
6
+ } from "./chunk-KMO5PHVP.js";
7
7
  import {
8
8
  detectProject
9
- } from "./chunk-YHFU2XTS.js";
9
+ } from "./chunk-QZHCVNMM.js";
10
10
  import "./chunk-JSBRDJBE.js";
11
11
 
12
12
  // src/components/StatsApp.tsx
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-SHO3ZXTH.js";
5
5
  import {
6
6
  shortName
7
- } from "./chunk-FEM4GJAY.js";
7
+ } from "./chunk-S5UHV6SX.js";
8
8
  import {
9
9
  Header
10
- } from "./chunk-YAGUN3VM.js";
11
- import "./chunk-YHFU2XTS.js";
10
+ } from "./chunk-KMO5PHVP.js";
11
+ import "./chunk-QZHCVNMM.js";
12
12
  import {
13
13
  detectRegressions,
14
14
  loadHistory
@@ -14,7 +14,7 @@ import {
14
14
  detectMonorepo,
15
15
  runSickbay,
16
16
  runSickbayMonorepo
17
- } from "./chunk-YHFU2XTS.js";
17
+ } from "./chunk-QZHCVNMM.js";
18
18
  import {
19
19
  loadHistory
20
20
  } from "./chunk-3OR2GFVE.js";
@@ -690,7 +690,7 @@ function TuiApp({
690
690
  return () => timers.forEach(clearTimeout);
691
691
  }, []);
692
692
  useEffect7(() => {
693
- checkForUpdate("1.11.0").then((info) => {
693
+ checkForUpdate("1.12.0").then((info) => {
694
694
  if (info) setUpdateInfo(info);
695
695
  });
696
696
  }, []);
@@ -716,7 +716,7 @@ function TuiApp({
716
716
  } catch {
717
717
  }
718
718
  try {
719
- const { getDependencyTree } = await import("./dist-FNOE2KCN.js");
719
+ const { getDependencyTree } = await import("./dist-6ZVGDRA5.js");
720
720
  const { saveDepTree } = await import("./history-KXLC45VS.js");
721
721
  const tree = await getDependencyTree(projectPath, result.projectInfo.packageManager);
722
722
  saveDepTree(projectPath, tree);
@@ -820,7 +820,7 @@ function TuiApp({
820
820
  const webReport = monorepoReportRef.current ?? reportRef.current;
821
821
  if (!webReport) return;
822
822
  try {
823
- const { serveWeb } = await import("./web-T63BRGAM.js");
823
+ const { serveWeb } = await import("./web-MOY3FJJU.js");
824
824
  const { default: openBrowser } = await import("open");
825
825
  let aiService;
826
826
  if (withAI && process.env.ANTHROPIC_API_KEY && !monorepoReportRef.current) {
@@ -11,7 +11,7 @@ var ASCII_ART = `
11
11
  A vitals health check for your app
12
12
  `.trim();
13
13
  function Header({ projectName }) {
14
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.11.0")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, projectName)));
14
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.12.0")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, projectName)));
15
15
  }
16
16
 
17
17
  export {
@@ -2796,6 +2796,7 @@ var AngularChangeDetectionRunner = class extends BaseRunner {
2796
2796
  severity: "warning",
2797
2797
  message: `${file} \u2014 component missing OnPush change detection`,
2798
2798
  file,
2799
+ suppressMatch: file,
2799
2800
  fix: {
2800
2801
  description: "Add `changeDetection: ChangeDetectionStrategy.OnPush` to the @Component decorator to prevent unnecessary re-renders."
2801
2802
  },
@@ -2902,6 +2903,7 @@ var AngularLazyRoutesRunner = class extends BaseRunner {
2902
2903
  severity: "warning",
2903
2904
  message: `${relPath}:${i + 1} \u2014 static route component import; consider lazy loading`,
2904
2905
  file: relPath,
2906
+ suppressMatch: relPath,
2905
2907
  fix: {
2906
2908
  description: "Replace `component: MyComponent` with `loadComponent: () => import('./my.component').then(m => m.MyComponent)` to enable route-level code splitting."
2907
2909
  },
@@ -2996,6 +2998,7 @@ var AngularSecurityRunner = class extends BaseRunner {
2996
2998
  severity: "warning",
2997
2999
  message: `${relPath}:${i + 1} \u2014 DomSanitizer ${method.slice(0, -1)}() bypasses XSS protection`,
2998
3000
  file: relPath,
3001
+ suppressMatch: relPath,
2999
3002
  fix: {
3000
3003
  description: "Avoid bypassing Angular's built-in sanitization. Use safe values or sanitize input before rendering."
3001
3004
  },
@@ -3008,6 +3011,7 @@ var AngularSecurityRunner = class extends BaseRunner {
3008
3011
  severity: "warning",
3009
3012
  message: `${relPath}:${i + 1} \u2014 [innerHTML] binding is a potential XSS vector if content is user-controlled`,
3010
3013
  file: relPath,
3014
+ suppressMatch: relPath,
3011
3015
  fix: {
3012
3016
  description: "Prefer Angular's built-in text interpolation or use DomSanitizer explicitly when innerHTML is required."
3013
3017
  },
@@ -3189,6 +3193,7 @@ var AngularSubscriptionsRunner = class extends BaseRunner {
3189
3193
  severity: "warning",
3190
3194
  message: `${file} \u2014 possible unguarded subscription (no takeUntilDestroyed, takeUntil, or ngOnDestroy found)`,
3191
3195
  file,
3196
+ suppressMatch: file,
3192
3197
  fix: {
3193
3198
  description: "Use `takeUntilDestroyed()` from `@angular/core/rxjs-interop` or call `.unsubscribe()` in `ngOnDestroy` to prevent memory leaks."
3194
3199
  },
@@ -3311,6 +3316,7 @@ function checkNgForTrackBy(template, relPath, issues) {
3311
3316
  severity: "warning",
3312
3317
  message: `${relPath} \u2014 *ngFor without trackBy causes full list re-renders on any array change`,
3313
3318
  file: relPath,
3319
+ suppressMatch: relPath,
3314
3320
  fix: {
3315
3321
  description: 'Add a trackBy function to the *ngFor directive (e.g. *ngFor="let item of items; trackBy: trackById").'
3316
3322
  },
@@ -3329,6 +3335,7 @@ function checkForTrack(template, relPath, issues) {
3329
3335
  severity: "warning",
3330
3336
  message: `${relPath} \u2014 @for without track expression causes full list re-renders`,
3331
3337
  file: relPath,
3338
+ suppressMatch: relPath,
3332
3339
  fix: {
3333
3340
  description: "Add a track expression to the @for block (e.g. @for (item of items; track item.id))."
3334
3341
  },
@@ -3345,8 +3352,9 @@ function checkFunctionCalls(template, relPath, issues) {
3345
3352
  if (fnName === "$any" || fnName === "$event") continue;
3346
3353
  issues.push({
3347
3354
  severity: "warning",
3348
- message: `${relPath} \u2014 function call {{ ${fnName}() }} in template re-runs on every change detection cycle`,
3355
+ message: `${relPath} \u2014 function call \`${fnName}()\` in template re-runs on every change detection cycle`,
3349
3356
  file: relPath,
3357
+ suppressMatch: relPath,
3350
3358
  fix: {
3351
3359
  description: "Replace the function call with a pre-computed property, a pipe, or use memoization to avoid re-execution on every change detection cycle."
3352
3360
  },
@@ -3359,8 +3367,9 @@ function checkFunctionCalls(template, relPath, issues) {
3359
3367
  if (fnName === "$any" || fnName === "$event") continue;
3360
3368
  issues.push({
3361
3369
  severity: "warning",
3362
- message: `${relPath} \u2014 function call ${fnName}() in property binding re-runs on every change detection cycle`,
3370
+ message: `${relPath} \u2014 function call \`${fnName}()\` in property binding re-runs on every change detection cycle`,
3363
3371
  file: relPath,
3372
+ suppressMatch: relPath,
3364
3373
  fix: {
3365
3374
  description: "Replace the function call with a pre-computed property, a pipe, or use memoization to avoid re-execution on every change detection cycle."
3366
3375
  },
@@ -3437,6 +3446,7 @@ var AssetSizeRunner = class extends BaseRunner {
3437
3446
  issues.push({
3438
3447
  severity: "critical",
3439
3448
  message: `${asset.path} \u2014 ${sizeMB}MB image (exceeds 2MB)`,
3449
+ suppressMatch: asset.path,
3440
3450
  file: asset.path,
3441
3451
  fix: {
3442
3452
  description: "Compress with tools like squoosh.app, tinypng.com, or convert to WebP/AVIF format"
@@ -3447,6 +3457,7 @@ var AssetSizeRunner = class extends BaseRunner {
3447
3457
  issues.push({
3448
3458
  severity: "warning",
3449
3459
  message: `${asset.path} \u2014 ${sizeKB}KB image (exceeds 500KB)`,
3460
+ suppressMatch: asset.path,
3450
3461
  file: asset.path,
3451
3462
  fix: { description: "Compress or convert to a more efficient format (WebP, AVIF)" },
3452
3463
  reportedBy: ["asset-size"]
@@ -3457,6 +3468,7 @@ var AssetSizeRunner = class extends BaseRunner {
3457
3468
  issues.push({
3458
3469
  severity: "warning",
3459
3470
  message: `${asset.path} \u2014 ${sizeKB}KB SVG (exceeds 100KB, likely unoptimized)`,
3471
+ suppressMatch: asset.path,
3460
3472
  file: asset.path,
3461
3473
  fix: {
3462
3474
  description: "Optimize with SVGO or svgomg.net \u2014 remove metadata, simplify paths"
@@ -3469,6 +3481,7 @@ var AssetSizeRunner = class extends BaseRunner {
3469
3481
  issues.push({
3470
3482
  severity: "warning",
3471
3483
  message: `${asset.path} \u2014 ${sizeKB}KB font (exceeds 500KB)`,
3484
+ suppressMatch: asset.path,
3472
3485
  file: asset.path,
3473
3486
  fix: {
3474
3487
  description: "Subset the font to include only needed characters, or use WOFF2 format"
@@ -3673,6 +3686,7 @@ var ComplexityRunner = class extends BaseRunner {
3673
3686
  issues.push({
3674
3687
  severity: f.lines >= critical ? "warning" : "info",
3675
3688
  message: `${f.path} (${label}): ${f.lines} lines \u2014 consider splitting (threshold: ${warn})`,
3689
+ suppressMatch: f.path,
3676
3690
  fix: { description: "Extract concerns into smaller, focused files" },
3677
3691
  reportedBy: ["complexity"]
3678
3692
  });
@@ -4146,6 +4160,7 @@ var DepcheckRunner = class extends BaseRunner {
4146
4160
  issues.push({
4147
4161
  severity: "critical",
4148
4162
  message: `Missing dependency: ${dep} (used in ${files.length} file${files.length > 1 ? "s" : ""})`,
4163
+ suppressMatch: dep,
4149
4164
  fix: { description: `Install ${dep}` },
4150
4165
  reportedBy: ["depcheck"]
4151
4166
  });
@@ -4219,6 +4234,7 @@ var ESLintRunner = class extends BaseRunner {
4219
4234
  issues.push({
4220
4235
  severity: file.errorCount > 0 ? "warning" : "info",
4221
4236
  message: `${relPath}: ${parts.join(", ")}`,
4237
+ suppressMatch: relPath,
4222
4238
  fix: {
4223
4239
  description: `Fix ESLint issues in ${relPath}`,
4224
4240
  command: `eslint ${relPath} --fix`,
@@ -4447,6 +4463,7 @@ var HeavyDepsRunner = class extends BaseRunner {
4447
4463
  const issues = found.map((f) => ({
4448
4464
  severity: f.info.severity,
4449
4465
  message: `${f.name} \u2014 ${f.info.reason}`,
4466
+ suppressMatch: f.name,
4450
4467
  fix: {
4451
4468
  description: `Consider replacing with ${f.info.alternative}`
4452
4469
  },
@@ -4604,6 +4621,7 @@ var KnipRunner = class extends BaseRunner {
4604
4621
  issues.push({
4605
4622
  severity: "warning",
4606
4623
  message: `Unused file: ${filePath}`,
4624
+ suppressMatch: filePath,
4607
4625
  file: filePath,
4608
4626
  fix: { description: `Remove ${filePath}` },
4609
4627
  reportedBy: ["knip"]
@@ -4626,6 +4644,7 @@ var KnipRunner = class extends BaseRunner {
4626
4644
  (dep) => issues.push({
4627
4645
  severity: "warning",
4628
4646
  message: `Unused dependency: ${dep}`,
4647
+ suppressMatch: dep,
4629
4648
  fix: { description: `Remove ${dep}` },
4630
4649
  reportedBy: ["knip"]
4631
4650
  })
@@ -4634,6 +4653,7 @@ var KnipRunner = class extends BaseRunner {
4634
4653
  (dep) => issues.push({
4635
4654
  severity: "info",
4636
4655
  message: `Unused devDependency: ${dep}`,
4656
+ suppressMatch: dep,
4637
4657
  fix: { description: `Remove ${dep}` },
4638
4658
  reportedBy: ["knip"]
4639
4659
  })
@@ -4642,6 +4662,7 @@ var KnipRunner = class extends BaseRunner {
4642
4662
  (exp) => issues.push({
4643
4663
  severity: "info",
4644
4664
  message: `Unused export: ${exp}`,
4665
+ suppressMatch: exp,
4645
4666
  reportedBy: ["knip"]
4646
4667
  })
4647
4668
  );
@@ -4711,6 +4732,7 @@ var LicenseCheckerRunner = class extends BaseRunner {
4711
4732
  issues.push({
4712
4733
  severity: "warning",
4713
4734
  message: `${pkg} uses ${license} license \u2014 may be incompatible with commercial use`,
4735
+ suppressMatch: pkg.lastIndexOf("@") > 0 ? pkg.slice(0, pkg.lastIndexOf("@")) : pkg,
4714
4736
  fix: { description: `Review or replace ${pkg.split("@")[0]}` },
4715
4737
  reportedBy: ["license-checker"]
4716
4738
  });
@@ -4812,6 +4834,7 @@ var MadgeRunner = class extends BaseRunner {
4812
4834
  const issues = circles.map((cycle) => ({
4813
4835
  severity: "warning",
4814
4836
  message: `Circular dependency: ${cycle.join(" \u2192 ")}`,
4837
+ suppressMatch: cycle[0],
4815
4838
  fix: { description: "Refactor to break the circular dependency cycle" },
4816
4839
  reportedBy: ["madge"]
4817
4840
  }));
@@ -4871,6 +4894,7 @@ var NextClientComponentsRunner = class extends BaseRunner {
4871
4894
  severity: "warning",
4872
4895
  message: `${file} \u2014 may not need 'use client' (no hooks or event handlers detected)`,
4873
4896
  file,
4897
+ suppressMatch: file,
4874
4898
  fix: {
4875
4899
  description: "This component may not need 'use client' \u2014 it contains no hooks or event handlers. Moving it to a Server Component reduces client bundle size."
4876
4900
  },
@@ -4970,6 +4994,7 @@ var NextFontsRunner = class extends BaseRunner {
4970
4994
  severity: "warning",
4971
4995
  message: `${layoutPath} \u2014 Google Fonts loaded via external stylesheet; use next/font/google`,
4972
4996
  file: layoutPath,
4997
+ suppressMatch: layoutPath,
4973
4998
  fix: {
4974
4999
  description: "Use next/font/google instead of a <link> stylesheet to self-host fonts and improve Core Web Vitals (eliminates render-blocking request)."
4975
5000
  },
@@ -5030,6 +5055,7 @@ var NextImagesRunner = class extends BaseRunner {
5030
5055
  severity: "warning",
5031
5056
  message: `${file} \u2014 raw image element; use next/image for automatic optimization`,
5032
5057
  file,
5058
+ suppressMatch: file,
5033
5059
  fix: {
5034
5060
  description: "Replace <img> with the <Image> component from next/image for automatic optimization, lazy loading, and Core Web Vitals improvements."
5035
5061
  },
@@ -5116,6 +5142,7 @@ var NextLinkRunner = class extends BaseRunner {
5116
5142
  severity: "warning",
5117
5143
  message: `${file} \u2014 raw anchor tag for internal navigation; use next/link`,
5118
5144
  file,
5145
+ suppressMatch: file,
5119
5146
  fix: {
5120
5147
  description: 'Replace <a href="/path"> with <Link href="/path"> from next/link to enable client-side navigation and prefetching.'
5121
5148
  },
@@ -5203,6 +5230,7 @@ var NextMissingBoundariesRunner = class extends BaseRunner {
5203
5230
  issues.push({
5204
5231
  severity: "info",
5205
5232
  message: `${relDir} \u2014 missing loading.tsx (Suspense boundary for this route segment)`,
5233
+ suppressMatch: relDir,
5206
5234
  fix: {
5207
5235
  description: "Add loading.tsx to show a skeleton UI while this route's data loads (App Router Suspense boundary)."
5208
5236
  },
@@ -5214,6 +5242,7 @@ var NextMissingBoundariesRunner = class extends BaseRunner {
5214
5242
  issues.push({
5215
5243
  severity: "info",
5216
5244
  message: `${relDir} \u2014 missing error.tsx (error boundary for this route segment)`,
5245
+ suppressMatch: relDir,
5217
5246
  fix: {
5218
5247
  description: "Add error.tsx with 'use client' to gracefully handle errors in this route segment."
5219
5248
  },
@@ -5783,6 +5812,7 @@ function parseNpmAudit(data) {
5783
5812
  issues.push({
5784
5813
  severity: vuln.severity === "critical" || vuln.severity === "high" ? "critical" : "warning",
5785
5814
  message: formatAuditMessage(vuln.name, title, url),
5815
+ suppressMatch: vuln.name,
5786
5816
  fix: typeof vuln.fixAvailable === "object" ? { description: `Upgrade to ${vuln.fixAvailable.name}@${vuln.fixAvailable.version}` } : { description: "No automatic fix available" },
5787
5817
  reportedBy: ["npm-audit"],
5788
5818
  ...url && { file: url }
@@ -5805,6 +5835,7 @@ function parsePnpmAudit(data, projectPath) {
5805
5835
  advisory.title || `Vulnerability in ${pkgName}`,
5806
5836
  advisory.url
5807
5837
  ),
5838
+ suppressMatch: pkgName,
5808
5839
  fix: advisory.recommendation ? { description: advisory.recommendation } : { description: "No automatic fix available" },
5809
5840
  reportedBy: ["npm-audit"],
5810
5841
  ...advisory.url && { file: advisory.url }
@@ -5867,6 +5898,7 @@ var OutdatedRunner = class extends BaseRunner {
5867
5898
  return {
5868
5899
  severity: isMajor ? "warning" : "info",
5869
5900
  message: `${e.name}: ${e.current} \u2192 ${e.latest} (${updateType})`,
5901
+ suppressMatch: e.name,
5870
5902
  fix: isMajor ? {
5871
5903
  description: `Update ${e.name} to ${e.latest} (major \u2014 review changelog before upgrading)`
5872
5904
  } : {
@@ -5960,6 +5992,7 @@ var ReactPerfRunner = class extends BaseRunner {
5960
5992
  severity: f.severity,
5961
5993
  message: f.line > 0 ? `${f.file}:${f.line} \u2014 ${f.pattern}` : `${f.file} \u2014 ${f.pattern}`,
5962
5994
  file: f.file,
5995
+ suppressMatch: f.file,
5963
5996
  fix: { description: getFixDescription(f.pattern) },
5964
5997
  reportedBy: ["react-perf"]
5965
5998
  }));
@@ -6190,6 +6223,7 @@ var SecretsRunner = class extends BaseRunner {
6190
6223
  const issues = findings.map((f) => ({
6191
6224
  severity: "critical",
6192
6225
  message: f.line > 0 ? `${f.file}:${f.line} \u2014 ${f.pattern} detected` : `${f.file} \u2014 ${f.pattern}`,
6226
+ suppressMatch: f.pattern,
6193
6227
  file: f.file,
6194
6228
  fix: {
6195
6229
  description: "Move secrets to environment variables",
@@ -6488,6 +6522,7 @@ var TodoScannerRunner = class extends BaseRunner {
6488
6522
  const issues = todos.map((t) => ({
6489
6523
  severity: t.kind === "FIXME" || t.kind === "HACK" ? "warning" : "info",
6490
6524
  message: `${t.file}:${t.line} \u2014 ${t.kind}: ${t.text || "(no description)"}`,
6525
+ suppressMatch: t.file,
6491
6526
  reportedBy: ["todo-scanner"]
6492
6527
  }));
6493
6528
  const fixmeCount = todos.filter((t) => t.kind === "FIXME" || t.kind === "HACK").length;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  detectMonorepo
3
- } from "./chunk-YHFU2XTS.js";
3
+ } from "./chunk-QZHCVNMM.js";
4
4
 
5
5
  // src/lib/resolve-package.ts
6
6
  import { readFileSync } from "fs";
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineConfig
3
- } from "./chunk-YHFU2XTS.js";
3
+ } from "./chunk-QZHCVNMM.js";
4
4
  import "./chunk-JSBRDJBE.js";
5
5
  export {
6
6
  defineConfig
@@ -29,7 +29,7 @@ import {
29
29
  runSickbay,
30
30
  runSickbayMonorepo,
31
31
  validateConfig
32
- } from "./chunk-YHFU2XTS.js";
32
+ } from "./chunk-QZHCVNMM.js";
33
33
  import "./chunk-JSBRDJBE.js";
34
34
  export {
35
35
  BaseAdvisor,
package/dist/index.js CHANGED
@@ -8,12 +8,12 @@ import {
8
8
  } from "./chunk-TYG7ZQBP.js";
9
9
  import {
10
10
  Header
11
- } from "./chunk-YAGUN3VM.js";
11
+ } from "./chunk-KMO5PHVP.js";
12
12
  import {
13
13
  getScoreEmoji,
14
14
  runSickbay,
15
15
  runSickbayMonorepo
16
- } from "./chunk-YHFU2XTS.js";
16
+ } from "./chunk-QZHCVNMM.js";
17
17
  import "./chunk-JSBRDJBE.js";
18
18
 
19
19
  // src/index.ts
@@ -177,7 +177,7 @@ function App({
177
177
  setMonorepoReport(r);
178
178
  setProjectName(`monorepo (${r.packages.length} packages)`);
179
179
  try {
180
- const { getDependencyTree } = await import("./dist-FNOE2KCN.js");
180
+ const { getDependencyTree } = await import("./dist-6ZVGDRA5.js");
181
181
  const { saveDepTree } = await import("./history-KXLC45VS.js");
182
182
  const packages = {};
183
183
  for (const pkg of r.packages) {
@@ -189,7 +189,7 @@ function App({
189
189
  if (openWeb) {
190
190
  setPhase("opening-web");
191
191
  try {
192
- const { serveWeb } = await import("./web-T63BRGAM.js");
192
+ const { serveWeb } = await import("./web-MOY3FJJU.js");
193
193
  const { default: openBrowser } = await import("open");
194
194
  let aiService;
195
195
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -246,7 +246,7 @@ function App({
246
246
  } catch {
247
247
  }
248
248
  try {
249
- const { getDependencyTree } = await import("./dist-FNOE2KCN.js");
249
+ const { getDependencyTree } = await import("./dist-6ZVGDRA5.js");
250
250
  const { saveDepTree } = await import("./history-KXLC45VS.js");
251
251
  const tree = await getDependencyTree(projectPath, r.projectInfo.packageManager);
252
252
  saveDepTree(projectPath, tree);
@@ -255,7 +255,7 @@ function App({
255
255
  if (openWeb) {
256
256
  setPhase("opening-web");
257
257
  try {
258
- const { serveWeb } = await import("./web-T63BRGAM.js");
258
+ const { serveWeb } = await import("./web-MOY3FJJU.js");
259
259
  const { default: openBrowser } = await import("open");
260
260
  let aiService;
261
261
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -304,7 +304,7 @@ if (existsSync(globalConfigPath)) {
304
304
  }
305
305
  config({ debug: false, quiet: true });
306
306
  var program = new Command();
307
- program.name("sickbay").description("React project health check CLI").version("1.11.0", "-v, --version").enablePositionalOptions().passThroughOptions().option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single named package (monorepo only)").option("--json", "output raw JSON report").option("--web", "open web dashboard after scan").option("--no-ai", "disable AI features").option("--no-quotes", "suppress personality quotes in output").option("--verbose", "show verbose output").action(async (options) => {
307
+ program.name("sickbay").description("React project health check CLI").version("1.12.0", "-v, --version").enablePositionalOptions().passThroughOptions().option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single named package (monorepo only)").option("--json", "output raw JSON report").option("--web", "open web dashboard after scan").option("--no-ai", "disable AI features").option("--no-quotes", "suppress personality quotes in output").option("--verbose", "show verbose output").action(async (options) => {
308
308
  if (options.path && options.path !== process.cwd()) {
309
309
  const projectEnvPath = join(options.path, ".env");
310
310
  if (existsSync(projectEnvPath)) {
@@ -314,13 +314,13 @@ program.name("sickbay").description("React project health check CLI").version("1
314
314
  const updatePromise = (async () => {
315
315
  try {
316
316
  const { checkForUpdate } = await import("./update-check-QLG6GA4Z.js");
317
- return await checkForUpdate("1.11.0");
317
+ return await checkForUpdate("1.12.0");
318
318
  } catch {
319
319
  return null;
320
320
  }
321
321
  })();
322
322
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
323
- const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2 } = await import("./dist-FNOE2KCN.js");
323
+ const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2 } = await import("./dist-6ZVGDRA5.js");
324
324
  const monorepoInfo = await detectMonorepo(options.path);
325
325
  if (options.package && monorepoInfo.isMonorepo) {
326
326
  const { readFileSync } = await import("fs");
@@ -384,7 +384,7 @@ program.name("sickbay").description("React project health check CLI").version("1
384
384
  } catch {
385
385
  }
386
386
  try {
387
- const { getDependencyTree } = await import("./dist-FNOE2KCN.js");
387
+ const { getDependencyTree } = await import("./dist-6ZVGDRA5.js");
388
388
  const { saveDepTree } = await import("./history-KXLC45VS.js");
389
389
  const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);
390
390
  saveDepTree(options.path, tree);
@@ -411,16 +411,16 @@ program.command("init").description("Initialize .sickbay/ folder and run an init
411
411
  "add newly available checks to existing config without touching existing entries"
412
412
  ).option("--reset-config", "regenerate config from scratch (overwrites existing)").action(async (options) => {
413
413
  if (options.resetConfig) {
414
- const { generateConfigFile } = await import("./init-JY7XQS3Q.js");
414
+ const { generateConfigFile } = await import("./init-WZUCGPVX.js");
415
415
  await generateConfigFile(options.path, { force: true });
416
416
  return;
417
417
  }
418
418
  if (options.sync) {
419
- const { syncConfigFile } = await import("./init-JY7XQS3Q.js");
419
+ const { syncConfigFile } = await import("./init-WZUCGPVX.js");
420
420
  await syncConfigFile(options.path);
421
421
  return;
422
422
  }
423
- const { initSickbay } = await import("./init-JY7XQS3Q.js");
423
+ const { initSickbay } = await import("./init-WZUCGPVX.js");
424
424
  await initSickbay(options.path);
425
425
  });
426
426
  program.command("fix").description("Interactively fix issues found by sickbay scan").option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single package (monorepo only)").option("--all", "apply all available fixes without prompting").option("--dry-run", "show what would be fixed without executing").option("--verbose", "show verbose output").action(async (options) => {
@@ -430,9 +430,9 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
430
430
  config({ path: projectEnvPath, override: true });
431
431
  }
432
432
  }
433
- const { resolveProject } = await import("./resolve-package-U5UYD7TW.js");
433
+ const { resolveProject } = await import("./resolve-package-D6EHBJ5J.js");
434
434
  const resolution = await resolveProject(options.path, options.package);
435
- const { FixApp } = await import("./FixApp-P2FHGJKZ.js");
435
+ const { FixApp } = await import("./FixApp-47DDF2OF.js");
436
436
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
437
437
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
438
438
  render(
@@ -455,10 +455,10 @@ program.command("trend").description("Show score history and trends over time").
455
455
  config({ path: projectEnvPath, override: true });
456
456
  }
457
457
  }
458
- const { resolveProject } = await import("./resolve-package-U5UYD7TW.js");
458
+ const { resolveProject } = await import("./resolve-package-D6EHBJ5J.js");
459
459
  const resolution = await resolveProject(options.path, options.package);
460
460
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
461
- const { TrendApp } = await import("./TrendApp-OXM6QDE5.js");
461
+ const { TrendApp } = await import("./TrendApp-J2GF5A2Y.js");
462
462
  render(
463
463
  React6.createElement(TrendApp, {
464
464
  projectPath,
@@ -477,10 +477,10 @@ program.command("stats").description("Show a quick codebase overview and project
477
477
  config({ path: projectEnvPath, override: true });
478
478
  }
479
479
  }
480
- const { resolveProject } = await import("./resolve-package-U5UYD7TW.js");
480
+ const { resolveProject } = await import("./resolve-package-D6EHBJ5J.js");
481
481
  const resolution = await resolveProject(options.path, options.package);
482
482
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
483
- const { StatsApp } = await import("./StatsApp-ONUVROC5.js");
483
+ const { StatsApp } = await import("./StatsApp-F3CQ6W26.js");
484
484
  render(
485
485
  React6.createElement(StatsApp, {
486
486
  projectPath,
@@ -492,7 +492,7 @@ program.command("stats").description("Show a quick codebase overview and project
492
492
  );
493
493
  });
494
494
  program.command("tui").description("Launch the persistent developer dashboard").option("-p, --path <path>", "project path to monitor", process.cwd()).option("--no-watch", "disable file-watching auto-refresh").option("--no-quotes", "suppress personality quotes in output").option("--refresh <seconds>", "auto-refresh interval in seconds", "300").option("-c, --checks <checks>", "comma-separated list of checks to run").action(async (options) => {
495
- const { TuiApp } = await import("./TuiApp-6MPPK4JT.js");
495
+ const { TuiApp } = await import("./TuiApp-PD3L2N5U.js");
496
496
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
497
497
  render(
498
498
  React6.createElement(TuiApp, {
@@ -512,10 +512,10 @@ program.command("doctor").description("Diagnose project setup and configuration
512
512
  config({ path: projectEnvPath, override: true });
513
513
  }
514
514
  }
515
- const { resolveProject } = await import("./resolve-package-U5UYD7TW.js");
515
+ const { resolveProject } = await import("./resolve-package-D6EHBJ5J.js");
516
516
  const resolution = await resolveProject(options.path, options.package);
517
517
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
518
- const { DoctorApp } = await import("./DoctorApp-T45ZNMZQ.js");
518
+ const { DoctorApp } = await import("./DoctorApp-7MSN36GO.js");
519
519
  render(
520
520
  React6.createElement(DoctorApp, {
521
521
  projectPath,
@@ -528,13 +528,13 @@ program.command("doctor").description("Diagnose project setup and configuration
528
528
  );
529
529
  });
530
530
  program.command("badge").description("Generate a health score badge for your README").option("-p, --path <path>", "project path", process.cwd()).option("--package <name>", "scope to a single package (monorepo only)").option("--html", "output HTML <img> tag instead of markdown").option("--url", "output bare badge URL only").option("--label <text>", "custom badge label", "sickbay").option("--scan", "run a fresh scan instead of using last report").action(async (options) => {
531
- const { resolveProject } = await import("./resolve-package-U5UYD7TW.js");
531
+ const { resolveProject } = await import("./resolve-package-D6EHBJ5J.js");
532
532
  const resolution = await resolveProject(options.path, options.package);
533
533
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
534
534
  const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-AO2FZVHJ.js");
535
535
  let score = options.scan ? null : loadScoreFromLastReport(projectPath);
536
536
  if (score === null) {
537
- const { runSickbay: runSickbay2 } = await import("./dist-FNOE2KCN.js");
537
+ const { runSickbay: runSickbay2 } = await import("./dist-6ZVGDRA5.js");
538
538
  const report = await runSickbay2({ projectPath, quotes: false });
539
539
  try {
540
540
  const { saveEntry, saveLastReport } = await import("./history-KXLC45VS.js");
@@ -563,7 +563,7 @@ program.command("diff <branch>").description("Compare health score against anoth
563
563
  }
564
564
  }
565
565
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
566
- const { DiffApp } = await import("./DiffApp-QTG772WX.js");
566
+ const { DiffApp } = await import("./DiffApp-RFUMM4XU.js");
567
567
  render(
568
568
  React6.createElement(DiffApp, {
569
569
  projectPath: options.path,
@@ -4,7 +4,7 @@ import {
4
4
  getAvailableChecks,
5
5
  runSickbay,
6
6
  runSickbayMonorepo
7
- } from "./chunk-YHFU2XTS.js";
7
+ } from "./chunk-QZHCVNMM.js";
8
8
  import {
9
9
  saveEntry
10
10
  } from "./chunk-3OR2GFVE.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  resolveProject,
3
3
  shortName
4
- } from "./chunk-FEM4GJAY.js";
5
- import "./chunk-YHFU2XTS.js";
4
+ } from "./chunk-S5UHV6SX.js";
5
+ import "./chunk-QZHCVNMM.js";
6
6
  import "./chunk-JSBRDJBE.js";
7
7
  export {
8
8
  resolveProject,