sickbay 1.15.3 → 1.15.5
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.
- package/README.md +2 -2
- package/dist/{DiffApp-M3D3HGI4.js → DiffApp-27FEBRY2.js} +2 -2
- package/dist/{DoctorApp-VIDISA3A.js → DoctorApp-AID5U7MJ.js} +3 -3
- package/dist/{FixApp-HT7PHJKO.js → FixApp-KXL3C4WC.js} +3 -3
- package/dist/{StatsApp-GOCP43YN.js → StatsApp-UZU3OXQE.js} +3 -3
- package/dist/{TrendApp-CB7CNPZI.js → TrendApp-HW3GJVOM.js} +3 -3
- package/dist/{TuiApp-SX22YRN7.js → TuiApp-26Q2ECKP.js} +4 -4
- package/dist/{chunk-O23F4LLA.js → chunk-GTTSACT6.js} +1 -1
- package/dist/{chunk-QAVKOJFG.js → chunk-LDUN7XJS.js} +1 -1
- package/dist/{chunk-BI2RMQIV.js → chunk-RRLMUX6E.js} +103 -46
- package/dist/config.js +1 -1
- package/dist/{dist-CEJKDCQM.js → dist-CH3OBHPD.js} +1 -1
- package/dist/index.js +25 -25
- package/dist/{init-WGMAAQSO.js → init-ASV2KR4C.js} +1 -1
- package/dist/{resolve-package-FYX3J6PS.js → resolve-package-DS44CNYU.js} +2 -2
- package/dist/{web-KRYFOBSH.js → web-CP4PSUZM.js} +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# sickbay
|
|
2
2
|
|
|
3
|
-
The terminal interface for Sickbay. Built with [Ink](https://github.com/vadimdemedes/ink) (React for terminals) and [Commander](https://github.com/tj/commander.js).
|
|
3
|
+
The terminal interface for Sickbay. Published to npm as the unscoped `sickbay` package. Built with [Ink](https://github.com/vadimdemedes/ink) (React for terminals) and [Commander](https://github.com/tj/commander.js).
|
|
4
4
|
|
|
5
5
|
## Quickstart
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Header
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GTTSACT6.js";
|
|
4
4
|
|
|
5
5
|
// src/components/DiffApp.tsx
|
|
6
6
|
import React, { useState, useEffect } from "react";
|
|
@@ -119,7 +119,7 @@ function DiffApp({ projectPath, branch, jsonOutput, checks, verbose }) {
|
|
|
119
119
|
useEffect(() => {
|
|
120
120
|
(async () => {
|
|
121
121
|
try {
|
|
122
|
-
const { runSickbay } = await import("./dist-
|
|
122
|
+
const { runSickbay } = await import("./dist-CH3OBHPD.js");
|
|
123
123
|
const currentReport = await runSickbay({
|
|
124
124
|
projectPath,
|
|
125
125
|
checks,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LDUN7XJS.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GTTSACT6.js";
|
|
7
7
|
import {
|
|
8
8
|
detectPackageManager,
|
|
9
9
|
detectProject
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RRLMUX6E.js";
|
|
11
11
|
|
|
12
12
|
// src/components/DoctorApp.tsx
|
|
13
13
|
import React, { useState, useEffect } from "react";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LDUN7XJS.js";
|
|
4
4
|
import {
|
|
5
5
|
ProgressList
|
|
6
6
|
} from "./chunk-MBVA75EM.js";
|
|
7
7
|
import {
|
|
8
8
|
Header
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-GTTSACT6.js";
|
|
10
10
|
import {
|
|
11
11
|
runSickbay
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RRLMUX6E.js";
|
|
13
13
|
|
|
14
14
|
// src/components/FixApp.tsx
|
|
15
15
|
import React, { useState, useEffect, useCallback } from "react";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LDUN7XJS.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GTTSACT6.js";
|
|
7
7
|
import {
|
|
8
8
|
detectProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RRLMUX6E.js";
|
|
10
10
|
|
|
11
11
|
// src/components/StatsApp.tsx
|
|
12
12
|
import React, { useState, useEffect } from "react";
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-SHO3ZXTH.js";
|
|
5
5
|
import {
|
|
6
6
|
shortName
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LDUN7XJS.js";
|
|
8
8
|
import {
|
|
9
9
|
Header
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-GTTSACT6.js";
|
|
11
|
+
import "./chunk-RRLMUX6E.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-
|
|
17
|
+
} from "./chunk-RRLMUX6E.js";
|
|
18
18
|
import {
|
|
19
19
|
loadHistory
|
|
20
20
|
} from "./chunk-3OR2GFVE.js";
|
|
@@ -689,7 +689,7 @@ function TuiApp({
|
|
|
689
689
|
return () => timers.forEach(clearTimeout);
|
|
690
690
|
}, []);
|
|
691
691
|
useEffect7(() => {
|
|
692
|
-
checkForUpdate("1.15.
|
|
692
|
+
checkForUpdate("1.15.4").then((info) => {
|
|
693
693
|
if (info) setUpdateInfo(info);
|
|
694
694
|
});
|
|
695
695
|
}, []);
|
|
@@ -715,7 +715,7 @@ function TuiApp({
|
|
|
715
715
|
} catch {
|
|
716
716
|
}
|
|
717
717
|
try {
|
|
718
|
-
const { getDependencyTree } = await import("./dist-
|
|
718
|
+
const { getDependencyTree } = await import("./dist-CH3OBHPD.js");
|
|
719
719
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
720
720
|
const tree = await getDependencyTree(projectPath, result.projectInfo.packageManager);
|
|
721
721
|
saveDepTree(projectPath, tree);
|
|
@@ -819,7 +819,7 @@ function TuiApp({
|
|
|
819
819
|
const webReport = monorepoReportRef.current ?? reportRef.current;
|
|
820
820
|
if (!webReport) return;
|
|
821
821
|
try {
|
|
822
|
-
const { serveWeb } = await import("./web-
|
|
822
|
+
const { serveWeb } = await import("./web-CP4PSUZM.js");
|
|
823
823
|
const { default: openBrowser } = await import("open");
|
|
824
824
|
let aiService;
|
|
825
825
|
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.15.
|
|
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.15.4")), 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 {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// ../../packages/core/dist/index.js
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
|
|
3
|
+
import { basename as basename3, join as join38, relative as relative3 } from "path";
|
|
3
4
|
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
4
5
|
import { join, extname } from "path";
|
|
5
6
|
import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
|
|
@@ -13,7 +14,7 @@ import { join as join5, resolve } from "path";
|
|
|
13
14
|
import { readFileSync as readFileSync6, existsSync as existsSync7 } from "fs";
|
|
14
15
|
import { join as join7 } from "path";
|
|
15
16
|
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
16
|
-
import { join as join6,
|
|
17
|
+
import { dirname, join as join6, relative, sep } from "path";
|
|
17
18
|
import { fileURLToPath } from "url";
|
|
18
19
|
import { execa } from "execa";
|
|
19
20
|
import { readdirSync as readdirSync4, statSync as statSync3, readFileSync as readFileSync7 } from "fs";
|
|
@@ -74,23 +75,23 @@ import { join as join29 } from "path";
|
|
|
74
75
|
import { readFileSync as readFileSync25, existsSync as existsSync20 } from "fs";
|
|
75
76
|
import { join as join30 } from "path";
|
|
76
77
|
import { existsSync as existsSync21 } from "fs";
|
|
77
|
-
import { dirname as dirname4, join as join31, relative } from "path";
|
|
78
|
+
import { dirname as dirname4, join as join31, relative as relative2 } from "path";
|
|
78
79
|
import { execa as execa10 } from "execa";
|
|
79
80
|
import { execa as execa11 } from "execa";
|
|
80
|
-
import { readFileSync as readFileSync26, readdirSync as readdirSync16, statSync as statSync15 } from "fs";
|
|
81
|
+
import { existsSync as existsSync22, readFileSync as readFileSync26, readdirSync as readdirSync16, statSync as statSync15 } from "fs";
|
|
81
82
|
import { join as join32, extname as extname7 } from "path";
|
|
82
|
-
import { readFileSync as readFileSync27, readdirSync as readdirSync17, statSync as statSync16, existsSync as
|
|
83
|
+
import { readFileSync as readFileSync27, readdirSync as readdirSync17, statSync as statSync16, existsSync as existsSync23 } from "fs";
|
|
83
84
|
import { join as join33, extname as extname8, basename as basename2 } from "path";
|
|
84
85
|
import { statSync as statSync17, readFileSync as readFileSync28 } from "fs";
|
|
85
86
|
import { join as join34 } from "path";
|
|
86
87
|
import { execa as execa12 } from "execa";
|
|
87
88
|
import { globby } from "globby";
|
|
88
|
-
import { readFileSync as readFileSync29, readdirSync as readdirSync18, statSync as statSync18, existsSync as
|
|
89
|
+
import { readFileSync as readFileSync29, readdirSync as readdirSync18, statSync as statSync18, existsSync as existsSync24 } from "fs";
|
|
89
90
|
import { join as join35, extname as extname9 } from "path";
|
|
90
|
-
import { existsSync as
|
|
91
|
+
import { existsSync as existsSync25 } from "fs";
|
|
91
92
|
import { join as join36 } from "path";
|
|
92
93
|
import { execa as execa13 } from "execa";
|
|
93
|
-
import { existsSync as
|
|
94
|
+
import { existsSync as existsSync26, readFileSync as readFileSync30 } from "fs";
|
|
94
95
|
import { join as join37, resolve as resolve2 } from "path";
|
|
95
96
|
import { globby as globby2 } from "globby";
|
|
96
97
|
import picomatch2 from "picomatch";
|
|
@@ -842,6 +843,9 @@ async function isCommandAvailable(cmd) {
|
|
|
842
843
|
function fileExists(projectPath, ...parts) {
|
|
843
844
|
return existsSync6(join6(projectPath, ...parts));
|
|
844
845
|
}
|
|
846
|
+
function relativeFromRoot(projectRoot, fullPath) {
|
|
847
|
+
return relative(projectRoot, fullPath).split(sep).join("/");
|
|
848
|
+
}
|
|
845
849
|
function timer() {
|
|
846
850
|
const start = Date.now();
|
|
847
851
|
return () => Date.now() - start;
|
|
@@ -1094,7 +1098,7 @@ function findComponentFiles(dir, projectRoot, isRoot = true) {
|
|
|
1094
1098
|
if (stat.isDirectory()) {
|
|
1095
1099
|
files.push(...findComponentFiles(fullPath, projectRoot, false));
|
|
1096
1100
|
} else if (entry.endsWith(".component.ts")) {
|
|
1097
|
-
files.push({ relPath:
|
|
1101
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
1098
1102
|
}
|
|
1099
1103
|
}
|
|
1100
1104
|
} catch (err) {
|
|
@@ -1216,7 +1220,7 @@ function findRouteFiles(dir, projectRoot, topLevel = true) {
|
|
|
1216
1220
|
if (stat.isDirectory()) {
|
|
1217
1221
|
files.push(...findRouteFiles(fullPath, projectRoot, false));
|
|
1218
1222
|
} else if (entry.endsWith(".routes.ts") || entry === "app.config.ts") {
|
|
1219
|
-
files.push({ relPath:
|
|
1223
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
1220
1224
|
}
|
|
1221
1225
|
}
|
|
1222
1226
|
return files;
|
|
@@ -1312,7 +1316,7 @@ function findSourceFiles(dir, projectRoot, isRoot = true) {
|
|
|
1312
1316
|
if (stat.isDirectory()) {
|
|
1313
1317
|
files.push(...findSourceFiles(fullPath, projectRoot, false));
|
|
1314
1318
|
} else if (entry.endsWith(".ts") || entry.endsWith(".html")) {
|
|
1315
|
-
files.push({ relPath:
|
|
1319
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
1316
1320
|
}
|
|
1317
1321
|
}
|
|
1318
1322
|
} catch (err) {
|
|
@@ -1496,7 +1500,7 @@ function findComponentFiles2(dir, projectRoot, isRoot = true) {
|
|
|
1496
1500
|
if (stat.isDirectory()) {
|
|
1497
1501
|
files.push(...findComponentFiles2(fullPath, projectRoot, false));
|
|
1498
1502
|
} else if (entry.endsWith(".component.ts")) {
|
|
1499
|
-
files.push({ relPath:
|
|
1503
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
1500
1504
|
}
|
|
1501
1505
|
}
|
|
1502
1506
|
} catch (err) {
|
|
@@ -1637,7 +1641,7 @@ function findComponentFiles3(dir, projectRoot, isRoot = true) {
|
|
|
1637
1641
|
if (stat.isDirectory()) {
|
|
1638
1642
|
files.push(...findComponentFiles3(fullPath, projectRoot, false));
|
|
1639
1643
|
} else if (entry.endsWith(".component.ts")) {
|
|
1640
|
-
files.push({ relPath:
|
|
1644
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
1641
1645
|
}
|
|
1642
1646
|
}
|
|
1643
1647
|
} catch (err) {
|
|
@@ -1803,7 +1807,7 @@ function scanAssets(dir, projectRoot, assets, isExcluded) {
|
|
|
1803
1807
|
for (const entry of readdirSync9(dir)) {
|
|
1804
1808
|
if (entry.startsWith(".") || entry === "node_modules") continue;
|
|
1805
1809
|
const fullPath = join14(dir, entry);
|
|
1806
|
-
const relPath =
|
|
1810
|
+
const relPath = relativeFromRoot(projectRoot, fullPath);
|
|
1807
1811
|
if (isExcluded(relPath)) continue;
|
|
1808
1812
|
const stat = statSync8(fullPath);
|
|
1809
1813
|
if (stat.isDirectory()) {
|
|
@@ -1817,7 +1821,7 @@ function scanAssets(dir, projectRoot, assets, isExcluded) {
|
|
|
1817
1821
|
else if (FONT_EXTENSIONS.has(ext)) type = "font";
|
|
1818
1822
|
else continue;
|
|
1819
1823
|
assets.push({
|
|
1820
|
-
path:
|
|
1824
|
+
path: relativeFromRoot(projectRoot, fullPath),
|
|
1821
1825
|
size: stat.size,
|
|
1822
1826
|
type
|
|
1823
1827
|
});
|
|
@@ -1997,7 +2001,7 @@ function scanDirectory(dir, projectRoot, isExcluded) {
|
|
|
1997
2001
|
if (stat.isDirectory()) {
|
|
1998
2002
|
files.push(...scanDirectory(fullPath, projectRoot, isExcluded));
|
|
1999
2003
|
} else if (SOURCE_EXTENSIONS.has(extname5(entry)) && !isTestFile(entry)) {
|
|
2000
|
-
const relPath =
|
|
2004
|
+
const relPath = relativeFromRoot(projectRoot, fullPath);
|
|
2001
2005
|
if (isExcluded(relPath)) continue;
|
|
2002
2006
|
try {
|
|
2003
2007
|
const lines = readFileSync13(fullPath, "utf-8").split("\n").filter((l) => l.trim()).length;
|
|
@@ -2049,6 +2053,7 @@ async function detectProject(projectPath) {
|
|
|
2049
2053
|
}
|
|
2050
2054
|
function detectFramework(deps) {
|
|
2051
2055
|
if ("next" in deps) return "next";
|
|
2056
|
+
if ("@angular/core" in deps) return "angular";
|
|
2052
2057
|
if ("@vitejs/plugin-react" in deps || "vite" in deps) return "vite";
|
|
2053
2058
|
if ("react-scripts" in deps) return "cra";
|
|
2054
2059
|
if ("react" in deps) return "react";
|
|
@@ -2476,7 +2481,7 @@ var ESLintRunner = class extends BaseRunner {
|
|
|
2476
2481
|
totalErrors += file.errorCount;
|
|
2477
2482
|
totalWarnings += file.warningCount;
|
|
2478
2483
|
if (file.errorCount > 0 || file.warningCount > 0) {
|
|
2479
|
-
const relPath =
|
|
2484
|
+
const relPath = relativeFromRoot(projectPath, file.filePath);
|
|
2480
2485
|
const parts = [];
|
|
2481
2486
|
if (file.errorCount > 0)
|
|
2482
2487
|
parts.push(`${file.errorCount} error${file.errorCount > 1 ? "s" : ""}`);
|
|
@@ -2554,7 +2559,8 @@ var GitRunner = class extends BaseRunner {
|
|
|
2554
2559
|
const commitCount = logCountResult.status === "fulfilled" ? parseInt(logCountResult.value.stdout.trim(), 10) : 0;
|
|
2555
2560
|
const contributorCount = contributorsResult.status === "fulfilled" ? contributorsResult.value.stdout.trim().split("\n").filter(Boolean).length : 0;
|
|
2556
2561
|
const issues = [];
|
|
2557
|
-
const
|
|
2562
|
+
const lastCommitMonths = lastCommit.includes("year") ? parseGitRelativeCount(lastCommit) * 12 : lastCommit.includes("month") ? parseGitRelativeCount(lastCommit) : 0;
|
|
2563
|
+
const isStale = lastCommitMonths > staleMonths;
|
|
2558
2564
|
if (isStale) {
|
|
2559
2565
|
issues.push({
|
|
2560
2566
|
severity: "warning",
|
|
@@ -2597,6 +2603,12 @@ var GitRunner = class extends BaseRunner {
|
|
|
2597
2603
|
}
|
|
2598
2604
|
}
|
|
2599
2605
|
};
|
|
2606
|
+
function parseGitRelativeCount(s) {
|
|
2607
|
+
const trimmed = s.trim().toLowerCase();
|
|
2608
|
+
if (trimmed.startsWith("a ") || trimmed.startsWith("an ")) return 1;
|
|
2609
|
+
const match = trimmed.match(/^(\d+)\b/);
|
|
2610
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
2611
|
+
}
|
|
2600
2612
|
var HEAVY_DEPS = {
|
|
2601
2613
|
moment: {
|
|
2602
2614
|
alternative: "dayjs or date-fns",
|
|
@@ -3202,7 +3214,7 @@ function findJsxFiles(dir, projectRoot, isRoot = true) {
|
|
|
3202
3214
|
if (stat.isDirectory()) {
|
|
3203
3215
|
files.push(...findJsxFiles(fullPath, projectRoot, false));
|
|
3204
3216
|
} else if (entry.endsWith(".tsx") || entry.endsWith(".jsx")) {
|
|
3205
|
-
files.push({ relPath:
|
|
3217
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
3206
3218
|
}
|
|
3207
3219
|
}
|
|
3208
3220
|
} catch (err) {
|
|
@@ -3359,7 +3371,7 @@ function findJsxFiles2(dir, projectRoot, isRoot = true) {
|
|
|
3359
3371
|
if (stat.isDirectory()) {
|
|
3360
3372
|
files.push(...findJsxFiles2(fullPath, projectRoot, false));
|
|
3361
3373
|
} else if (entry.endsWith(".tsx") || entry.endsWith(".jsx")) {
|
|
3362
|
-
files.push({ relPath:
|
|
3374
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
3363
3375
|
}
|
|
3364
3376
|
}
|
|
3365
3377
|
} catch (err) {
|
|
@@ -3446,7 +3458,7 @@ function findJsxFiles3(dir, projectRoot, isRoot = true) {
|
|
|
3446
3458
|
if (stat.isDirectory()) {
|
|
3447
3459
|
files.push(...findJsxFiles3(fullPath, projectRoot, false));
|
|
3448
3460
|
} else if (entry.endsWith(".tsx") || entry.endsWith(".jsx")) {
|
|
3449
|
-
files.push({ relPath:
|
|
3461
|
+
files.push({ relPath: relativeFromRoot(projectRoot, fullPath), fullPath });
|
|
3450
3462
|
}
|
|
3451
3463
|
}
|
|
3452
3464
|
} catch (err) {
|
|
@@ -3475,7 +3487,7 @@ var NextMissingBoundariesRunner = class extends BaseRunner {
|
|
|
3475
3487
|
let missingError = 0;
|
|
3476
3488
|
for (const pageDir of pageDirs) {
|
|
3477
3489
|
segmentsChecked++;
|
|
3478
|
-
const relDir =
|
|
3490
|
+
const relDir = relativeFromRoot(projectPath, pageDir);
|
|
3479
3491
|
if (!existsSync16(join26(pageDir, "loading.tsx")) && !existsSync16(join26(pageDir, "loading.jsx"))) {
|
|
3480
3492
|
missingLoading++;
|
|
3481
3493
|
issues.push({
|
|
@@ -4101,7 +4113,7 @@ function filterPnpmAdvisories(advisories, projectPath) {
|
|
|
4101
4113
|
if (!workspaceRoot || workspaceRoot === projectPath) {
|
|
4102
4114
|
return advisories;
|
|
4103
4115
|
}
|
|
4104
|
-
const importerPrefix =
|
|
4116
|
+
const importerPrefix = relative2(workspaceRoot, projectPath).replace(/\//g, "__");
|
|
4105
4117
|
const filtered = {};
|
|
4106
4118
|
for (const [id, advisory] of Object.entries(advisories)) {
|
|
4107
4119
|
const isRelevant = advisory.findings.some(
|
|
@@ -4225,18 +4237,24 @@ function getUpdateType(current, latest) {
|
|
|
4225
4237
|
if (curMin < latMin) return "minor";
|
|
4226
4238
|
return "patch";
|
|
4227
4239
|
}
|
|
4240
|
+
var SOURCE_DIRS2 = ["src", "app", "lib"];
|
|
4228
4241
|
var COMPONENT_EXTENSIONS3 = /* @__PURE__ */ new Set([".tsx", ".jsx"]);
|
|
4229
4242
|
var ReactPerfRunner = class extends BaseRunner {
|
|
4230
4243
|
name = "react-perf";
|
|
4231
4244
|
category = "performance";
|
|
4232
4245
|
applicableFrameworks = ["react", "next", "remix"];
|
|
4246
|
+
async isApplicable(projectPath) {
|
|
4247
|
+
return SOURCE_DIRS2.some((dir) => existsSync22(join32(projectPath, dir)));
|
|
4248
|
+
}
|
|
4233
4249
|
async run(projectPath, options) {
|
|
4234
4250
|
const elapsed = timer();
|
|
4235
4251
|
const isExcluded = createExcludeFilter(options?.checkConfig?.exclude ?? []);
|
|
4236
4252
|
try {
|
|
4237
4253
|
const hasReactCompiler = detectReactCompiler(projectPath);
|
|
4238
4254
|
const findings = [];
|
|
4239
|
-
const files =
|
|
4255
|
+
const files = SOURCE_DIRS2.flatMap(
|
|
4256
|
+
(dir) => existsSync22(join32(projectPath, dir)) ? scanDirectory2(join32(projectPath, dir), projectPath, isExcluded) : []
|
|
4257
|
+
);
|
|
4240
4258
|
for (const file of files) {
|
|
4241
4259
|
findings.push(...analyzeFile(file.path, file.fullPath, file.lines));
|
|
4242
4260
|
}
|
|
@@ -4306,7 +4324,7 @@ function scanDirectory2(dir, projectRoot, isExcluded) {
|
|
|
4306
4324
|
if (entry.startsWith(".") || entry === "node_modules" || entry === "__tests__" || entry === "__mocks__" || entry.includes(".test.") || entry.includes(".spec."))
|
|
4307
4325
|
continue;
|
|
4308
4326
|
const fullPath = join32(dir, entry);
|
|
4309
|
-
const relPath =
|
|
4327
|
+
const relPath = relativeFromRoot(projectRoot, fullPath);
|
|
4310
4328
|
if (isExcluded(relPath)) continue;
|
|
4311
4329
|
const stat = statSync15(fullPath);
|
|
4312
4330
|
if (stat.isDirectory()) {
|
|
@@ -4316,7 +4334,7 @@ function scanDirectory2(dir, projectRoot, isExcluded) {
|
|
|
4316
4334
|
const content = readFileSync26(fullPath, "utf-8");
|
|
4317
4335
|
const lineCount = content.split("\n").length;
|
|
4318
4336
|
files.push({
|
|
4319
|
-
path:
|
|
4337
|
+
path: relativeFromRoot(projectRoot, fullPath),
|
|
4320
4338
|
fullPath,
|
|
4321
4339
|
lines: lineCount
|
|
4322
4340
|
});
|
|
@@ -4453,7 +4471,7 @@ var SecretsRunner = class extends BaseRunner {
|
|
|
4453
4471
|
const findings = [];
|
|
4454
4472
|
const envFiles = [".env", ".env.local", ".env.production"];
|
|
4455
4473
|
for (const envFile of envFiles) {
|
|
4456
|
-
if (
|
|
4474
|
+
if (existsSync23(join33(projectPath, envFile))) {
|
|
4457
4475
|
const gitignorePath = join33(projectPath, ".gitignore");
|
|
4458
4476
|
let ignored = false;
|
|
4459
4477
|
try {
|
|
@@ -4470,9 +4488,14 @@ var SecretsRunner = class extends BaseRunner {
|
|
|
4470
4488
|
}
|
|
4471
4489
|
}
|
|
4472
4490
|
}
|
|
4473
|
-
|
|
4474
|
-
|
|
4491
|
+
const SCAN_DIRS = ["src", "app", "lib", "config", "scripts", ".github/workflows"];
|
|
4492
|
+
for (const dir of SCAN_DIRS) {
|
|
4493
|
+
const fullDir = join33(projectPath, dir);
|
|
4494
|
+
if (existsSync23(fullDir)) {
|
|
4495
|
+
findings.push(...scanDirectory3(fullDir, projectPath, isExcluded));
|
|
4496
|
+
}
|
|
4475
4497
|
}
|
|
4498
|
+
findings.push(...scanRootFiles(projectPath, isExcluded));
|
|
4476
4499
|
const issues = findings.map((f) => ({
|
|
4477
4500
|
severity: "critical",
|
|
4478
4501
|
message: f.line > 0 ? `${f.file}:${f.line} \u2014 ${f.pattern} detected` : `${f.file} \u2014 ${f.pattern}`,
|
|
@@ -4527,7 +4550,7 @@ function scanDirectory3(dir, projectRoot, isExcluded) {
|
|
|
4527
4550
|
if (entry.startsWith(".") || entry === "node_modules" || entry === "__tests__" || entry === "test" || entry === "tests")
|
|
4528
4551
|
continue;
|
|
4529
4552
|
const fullPath = join33(dir, entry);
|
|
4530
|
-
const relPath =
|
|
4553
|
+
const relPath = relativeFromRoot(projectRoot, fullPath);
|
|
4531
4554
|
if (isExcluded(relPath)) continue;
|
|
4532
4555
|
const stat = statSync16(fullPath);
|
|
4533
4556
|
if (stat.isDirectory()) {
|
|
@@ -4543,12 +4566,35 @@ function scanDirectory3(dir, projectRoot, isExcluded) {
|
|
|
4543
4566
|
function isTestFile2(filename) {
|
|
4544
4567
|
return /\.(test|spec)\.(ts|tsx|js|jsx|mts|cts)$/.test(filename);
|
|
4545
4568
|
}
|
|
4569
|
+
function scanRootFiles(projectRoot, isExcluded) {
|
|
4570
|
+
const findings = [];
|
|
4571
|
+
try {
|
|
4572
|
+
for (const entry of readdirSync17(projectRoot)) {
|
|
4573
|
+
const fullPath = join33(projectRoot, entry);
|
|
4574
|
+
let stat;
|
|
4575
|
+
try {
|
|
4576
|
+
stat = statSync16(fullPath);
|
|
4577
|
+
} catch {
|
|
4578
|
+
continue;
|
|
4579
|
+
}
|
|
4580
|
+
if (!stat.isFile()) continue;
|
|
4581
|
+
if (!SCAN_EXTENSIONS.has(extname8(entry))) continue;
|
|
4582
|
+
if (SKIP_FILES.has(basename2(entry))) continue;
|
|
4583
|
+
if (entry === "package.json") continue;
|
|
4584
|
+
if (isTestFile2(entry)) continue;
|
|
4585
|
+
if (isExcluded(entry)) continue;
|
|
4586
|
+
findings.push(...scanFile(fullPath, projectRoot));
|
|
4587
|
+
}
|
|
4588
|
+
} catch {
|
|
4589
|
+
}
|
|
4590
|
+
return findings;
|
|
4591
|
+
}
|
|
4546
4592
|
function scanFile(filePath, projectRoot) {
|
|
4547
4593
|
const findings = [];
|
|
4548
4594
|
try {
|
|
4549
4595
|
const content = readFileSync27(filePath, "utf-8");
|
|
4550
4596
|
const lines = content.split("\n");
|
|
4551
|
-
const relPath =
|
|
4597
|
+
const relPath = relativeFromRoot(projectRoot, filePath);
|
|
4552
4598
|
for (let i = 0; i < lines.length; i++) {
|
|
4553
4599
|
const line = lines[i];
|
|
4554
4600
|
if (line.includes("process.env") || line.includes("import.meta.env")) continue;
|
|
@@ -4762,7 +4808,7 @@ var TodoScannerRunner = class extends BaseRunner {
|
|
|
4762
4808
|
name = "todo-scanner";
|
|
4763
4809
|
category = "code-quality";
|
|
4764
4810
|
async isApplicable(projectPath) {
|
|
4765
|
-
return
|
|
4811
|
+
return existsSync24(join35(projectPath, "src"));
|
|
4766
4812
|
}
|
|
4767
4813
|
async run(projectPath, options) {
|
|
4768
4814
|
const elapsed = timer();
|
|
@@ -4824,7 +4870,7 @@ function scanDirectory4(dir, projectRoot, pattern, isExcluded) {
|
|
|
4824
4870
|
if (entry.startsWith(".") || entry === "node_modules") continue;
|
|
4825
4871
|
if (SELF_REFERENCING_FILES.has(entry)) continue;
|
|
4826
4872
|
const fullPath = join35(dir, entry);
|
|
4827
|
-
const relPath =
|
|
4873
|
+
const relPath = relativeFromRoot(projectRoot, fullPath);
|
|
4828
4874
|
if (isExcluded(relPath)) continue;
|
|
4829
4875
|
const stat = statSync18(fullPath);
|
|
4830
4876
|
if (stat.isDirectory()) {
|
|
@@ -4841,7 +4887,7 @@ function scanFile2(filePath, projectRoot, pattern) {
|
|
|
4841
4887
|
const todos = [];
|
|
4842
4888
|
try {
|
|
4843
4889
|
const lines = readFileSync29(filePath, "utf-8").split("\n");
|
|
4844
|
-
const relPath =
|
|
4890
|
+
const relPath = relativeFromRoot(projectRoot, filePath);
|
|
4845
4891
|
for (let i = 0; i < lines.length; i++) {
|
|
4846
4892
|
const match = stripStringLiterals(lines[i]).match(pattern);
|
|
4847
4893
|
if (match) {
|
|
@@ -4861,7 +4907,7 @@ var TypeScriptRunner = class extends BaseRunner {
|
|
|
4861
4907
|
name = "typescript";
|
|
4862
4908
|
category = "code-quality";
|
|
4863
4909
|
async isApplicable(projectPath) {
|
|
4864
|
-
return
|
|
4910
|
+
return existsSync25(join36(projectPath, "tsconfig.json"));
|
|
4865
4911
|
}
|
|
4866
4912
|
async run(projectPath, options) {
|
|
4867
4913
|
const elapsed = timer();
|
|
@@ -5116,12 +5162,12 @@ async function discoverPackages(rootPath, patterns) {
|
|
|
5116
5162
|
ignore: ["**/node_modules/**"]
|
|
5117
5163
|
});
|
|
5118
5164
|
return matched.filter((dir) => {
|
|
5119
|
-
return dir !== resolve2(rootPath) &&
|
|
5165
|
+
return dir !== resolve2(rootPath) && existsSync26(join37(dir, "package.json"));
|
|
5120
5166
|
});
|
|
5121
5167
|
}
|
|
5122
5168
|
function detectSignals(rootPath) {
|
|
5123
5169
|
const pnpmWs = join37(rootPath, "pnpm-workspace.yaml");
|
|
5124
|
-
if (
|
|
5170
|
+
if (existsSync26(pnpmWs)) {
|
|
5125
5171
|
try {
|
|
5126
5172
|
const content = readFileSync30(pnpmWs, "utf-8");
|
|
5127
5173
|
const patterns = parseYamlPackagesArray(content);
|
|
@@ -5131,7 +5177,7 @@ function detectSignals(rootPath) {
|
|
|
5131
5177
|
}
|
|
5132
5178
|
}
|
|
5133
5179
|
const lernaJson = join37(rootPath, "lerna.json");
|
|
5134
|
-
if (
|
|
5180
|
+
if (existsSync26(lernaJson)) {
|
|
5135
5181
|
try {
|
|
5136
5182
|
const lerna = JSON.parse(readFileSync30(lernaJson, "utf-8"));
|
|
5137
5183
|
const patterns = Array.isArray(lerna.packages) ? lerna.packages : ["packages/*"];
|
|
@@ -5141,27 +5187,27 @@ function detectSignals(rootPath) {
|
|
|
5141
5187
|
}
|
|
5142
5188
|
}
|
|
5143
5189
|
const pkgJson = join37(rootPath, "package.json");
|
|
5144
|
-
if (
|
|
5190
|
+
if (existsSync26(pkgJson)) {
|
|
5145
5191
|
try {
|
|
5146
5192
|
const pkg = JSON.parse(readFileSync30(pkgJson, "utf-8"));
|
|
5147
5193
|
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : Array.isArray(pkg.workspaces?.packages) ? pkg.workspaces.packages : void 0;
|
|
5148
5194
|
if (workspaces && workspaces.length > 0) {
|
|
5149
|
-
if (
|
|
5195
|
+
if (existsSync26(join37(rootPath, "turbo.json"))) {
|
|
5150
5196
|
return { type: "turbo", patterns: workspaces };
|
|
5151
5197
|
}
|
|
5152
|
-
if (
|
|
5198
|
+
if (existsSync26(join37(rootPath, "nx.json"))) {
|
|
5153
5199
|
return { type: "nx", patterns: workspaces };
|
|
5154
5200
|
}
|
|
5155
|
-
const hasYarn =
|
|
5201
|
+
const hasYarn = existsSync26(join37(rootPath, "yarn.lock"));
|
|
5156
5202
|
return { type: hasYarn ? "yarn" : "npm", patterns: workspaces };
|
|
5157
5203
|
}
|
|
5158
5204
|
} catch {
|
|
5159
5205
|
}
|
|
5160
5206
|
}
|
|
5161
|
-
if (
|
|
5207
|
+
if (existsSync26(join37(rootPath, "turbo.json"))) {
|
|
5162
5208
|
return { type: "turbo", patterns: ["packages/*", "apps/*"] };
|
|
5163
5209
|
}
|
|
5164
|
-
if (
|
|
5210
|
+
if (existsSync26(join37(rootPath, "nx.json"))) {
|
|
5165
5211
|
return { type: "nx", patterns: ["packages/*", "apps/*", "libs/*"] };
|
|
5166
5212
|
}
|
|
5167
5213
|
return null;
|
|
@@ -5268,6 +5314,17 @@ var ALL_ADVISORS = [
|
|
|
5268
5314
|
new NextBestPracticesAdvisor(),
|
|
5269
5315
|
new UniversalBestPracticesAdvisor()
|
|
5270
5316
|
];
|
|
5317
|
+
function readPackageName(pkgPath) {
|
|
5318
|
+
const pkgJsonPath = join38(pkgPath, "package.json");
|
|
5319
|
+
if (existsSync27(pkgJsonPath)) {
|
|
5320
|
+
try {
|
|
5321
|
+
const pkg = JSON.parse(readFileSync31(pkgJsonPath, "utf-8"));
|
|
5322
|
+
if (pkg.name) return pkg.name;
|
|
5323
|
+
} catch {
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
return basename3(pkgPath);
|
|
5327
|
+
}
|
|
5271
5328
|
function getAvailableChecks(context) {
|
|
5272
5329
|
const runners = context ? ALL_RUNNERS.filter((r) => r.isApplicableToContext(context)) : ALL_RUNNERS;
|
|
5273
5330
|
return runners.map((r) => ({ name: r.name, category: r.category }));
|
|
@@ -5372,13 +5429,13 @@ async function runSickbayMonorepo(options = {}) {
|
|
|
5372
5429
|
monorepoInfo.packagePaths.map(async (pkgPath) => {
|
|
5373
5430
|
const pkgConfig = await loadConfig(pkgPath);
|
|
5374
5431
|
const mergedConfig = mergeConfigs(rootConfig, pkgConfig);
|
|
5432
|
+
options.onPackageStart?.(readPackageName(pkgPath));
|
|
5375
5433
|
const report = await runSickbay({ ...options, projectPath: pkgPath, _config: mergedConfig });
|
|
5376
5434
|
const context = await detectContext(pkgPath);
|
|
5377
|
-
options.onPackageStart?.(report.projectInfo.name);
|
|
5378
5435
|
const packageReport = {
|
|
5379
5436
|
name: report.projectInfo.name,
|
|
5380
5437
|
path: pkgPath,
|
|
5381
|
-
relativePath:
|
|
5438
|
+
relativePath: relative3(rootPath, pkgPath),
|
|
5382
5439
|
framework: report.projectInfo.framework,
|
|
5383
5440
|
runtime: context.runtime,
|
|
5384
5441
|
checks: report.checks,
|
package/dist/config.js
CHANGED
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-
|
|
11
|
+
} from "./chunk-GTTSACT6.js";
|
|
12
12
|
import {
|
|
13
13
|
getScoreEmoji,
|
|
14
14
|
runSickbay,
|
|
15
15
|
runSickbayMonorepo
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RRLMUX6E.js";
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { existsSync } from "fs";
|
|
@@ -190,7 +190,7 @@ function App({
|
|
|
190
190
|
setMonorepoReport(r);
|
|
191
191
|
setProjectName(`monorepo (${r.packages.length} packages)`);
|
|
192
192
|
try {
|
|
193
|
-
const { getDependencyTree } = await import("./dist-
|
|
193
|
+
const { getDependencyTree } = await import("./dist-CH3OBHPD.js");
|
|
194
194
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
195
195
|
const packages = {};
|
|
196
196
|
for (const pkg of r.packages) {
|
|
@@ -202,7 +202,7 @@ function App({
|
|
|
202
202
|
if (openWeb) {
|
|
203
203
|
setPhase("opening-web");
|
|
204
204
|
try {
|
|
205
|
-
const { serveWeb } = await import("./web-
|
|
205
|
+
const { serveWeb } = await import("./web-CP4PSUZM.js");
|
|
206
206
|
const { default: openBrowser } = await import("open");
|
|
207
207
|
let aiService;
|
|
208
208
|
if (enableAI && process.env.ANTHROPIC_API_KEY) {
|
|
@@ -259,7 +259,7 @@ function App({
|
|
|
259
259
|
} catch {
|
|
260
260
|
}
|
|
261
261
|
try {
|
|
262
|
-
const { getDependencyTree } = await import("./dist-
|
|
262
|
+
const { getDependencyTree } = await import("./dist-CH3OBHPD.js");
|
|
263
263
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
264
264
|
const tree = await getDependencyTree(projectPath, r.projectInfo.packageManager);
|
|
265
265
|
saveDepTree(projectPath, tree);
|
|
@@ -268,7 +268,7 @@ function App({
|
|
|
268
268
|
if (openWeb) {
|
|
269
269
|
setPhase("opening-web");
|
|
270
270
|
try {
|
|
271
|
-
const { serveWeb } = await import("./web-
|
|
271
|
+
const { serveWeb } = await import("./web-CP4PSUZM.js");
|
|
272
272
|
const { default: openBrowser } = await import("open");
|
|
273
273
|
let aiService;
|
|
274
274
|
if (enableAI && process.env.ANTHROPIC_API_KEY) {
|
|
@@ -317,7 +317,7 @@ if (existsSync(globalConfigPath)) {
|
|
|
317
317
|
}
|
|
318
318
|
config({ debug: false, quiet: true });
|
|
319
319
|
var program = new Command();
|
|
320
|
-
program.name("sickbay").description("React project health check CLI").version("1.15.
|
|
320
|
+
program.name("sickbay").description("React project health check CLI").version("1.15.4", "-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) => {
|
|
321
321
|
if (options.path && options.path !== process.cwd()) {
|
|
322
322
|
const projectEnvPath = join(options.path, ".env");
|
|
323
323
|
if (existsSync(projectEnvPath)) {
|
|
@@ -327,13 +327,13 @@ program.name("sickbay").description("React project health check CLI").version("1
|
|
|
327
327
|
const updatePromise = (async () => {
|
|
328
328
|
try {
|
|
329
329
|
const { checkForUpdate } = await import("./update-check-M7IFOMLJ.js");
|
|
330
|
-
return await checkForUpdate("1.15.
|
|
330
|
+
return await checkForUpdate("1.15.4");
|
|
331
331
|
} catch {
|
|
332
332
|
return null;
|
|
333
333
|
}
|
|
334
334
|
})();
|
|
335
335
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
336
|
-
const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2 } = await import("./dist-
|
|
336
|
+
const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2 } = await import("./dist-CH3OBHPD.js");
|
|
337
337
|
const monorepoInfo = await detectMonorepo(options.path);
|
|
338
338
|
if (options.package && monorepoInfo.isMonorepo) {
|
|
339
339
|
const { readFileSync } = await import("fs");
|
|
@@ -397,7 +397,7 @@ program.name("sickbay").description("React project health check CLI").version("1
|
|
|
397
397
|
} catch {
|
|
398
398
|
}
|
|
399
399
|
try {
|
|
400
|
-
const { getDependencyTree } = await import("./dist-
|
|
400
|
+
const { getDependencyTree } = await import("./dist-CH3OBHPD.js");
|
|
401
401
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
402
402
|
const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);
|
|
403
403
|
saveDepTree(options.path, tree);
|
|
@@ -424,16 +424,16 @@ program.command("init").description("Initialize .sickbay/ folder and run an init
|
|
|
424
424
|
"add newly available checks to existing config without touching existing entries"
|
|
425
425
|
).option("--reset-config", "regenerate config from scratch (overwrites existing)").action(async (options) => {
|
|
426
426
|
if (options.resetConfig) {
|
|
427
|
-
const { generateConfigFile } = await import("./init-
|
|
427
|
+
const { generateConfigFile } = await import("./init-ASV2KR4C.js");
|
|
428
428
|
await generateConfigFile(options.path, { force: true });
|
|
429
429
|
return;
|
|
430
430
|
}
|
|
431
431
|
if (options.sync) {
|
|
432
|
-
const { syncConfigFile } = await import("./init-
|
|
432
|
+
const { syncConfigFile } = await import("./init-ASV2KR4C.js");
|
|
433
433
|
await syncConfigFile(options.path);
|
|
434
434
|
return;
|
|
435
435
|
}
|
|
436
|
-
const { initSickbay } = await import("./init-
|
|
436
|
+
const { initSickbay } = await import("./init-ASV2KR4C.js");
|
|
437
437
|
await initSickbay(options.path);
|
|
438
438
|
});
|
|
439
439
|
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) => {
|
|
@@ -443,9 +443,9 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
|
|
|
443
443
|
config({ path: projectEnvPath, override: true });
|
|
444
444
|
}
|
|
445
445
|
}
|
|
446
|
-
const { resolveProject } = await import("./resolve-package-
|
|
446
|
+
const { resolveProject } = await import("./resolve-package-DS44CNYU.js");
|
|
447
447
|
const resolution = await resolveProject(options.path, options.package);
|
|
448
|
-
const { FixApp } = await import("./FixApp-
|
|
448
|
+
const { FixApp } = await import("./FixApp-KXL3C4WC.js");
|
|
449
449
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
450
450
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
451
451
|
render(
|
|
@@ -468,10 +468,10 @@ program.command("trend").description("Show score history and trends over time").
|
|
|
468
468
|
config({ path: projectEnvPath, override: true });
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
|
-
const { resolveProject } = await import("./resolve-package-
|
|
471
|
+
const { resolveProject } = await import("./resolve-package-DS44CNYU.js");
|
|
472
472
|
const resolution = await resolveProject(options.path, options.package);
|
|
473
473
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
474
|
-
const { TrendApp } = await import("./TrendApp-
|
|
474
|
+
const { TrendApp } = await import("./TrendApp-HW3GJVOM.js");
|
|
475
475
|
render(
|
|
476
476
|
React7.createElement(TrendApp, {
|
|
477
477
|
projectPath,
|
|
@@ -490,10 +490,10 @@ program.command("stats").description("Show a quick codebase overview and project
|
|
|
490
490
|
config({ path: projectEnvPath, override: true });
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
|
-
const { resolveProject } = await import("./resolve-package-
|
|
493
|
+
const { resolveProject } = await import("./resolve-package-DS44CNYU.js");
|
|
494
494
|
const resolution = await resolveProject(options.path, options.package);
|
|
495
495
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
496
|
-
const { StatsApp } = await import("./StatsApp-
|
|
496
|
+
const { StatsApp } = await import("./StatsApp-UZU3OXQE.js");
|
|
497
497
|
render(
|
|
498
498
|
React7.createElement(StatsApp, {
|
|
499
499
|
projectPath,
|
|
@@ -505,7 +505,7 @@ program.command("stats").description("Show a quick codebase overview and project
|
|
|
505
505
|
);
|
|
506
506
|
});
|
|
507
507
|
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) => {
|
|
508
|
-
const { TuiApp } = await import("./TuiApp-
|
|
508
|
+
const { TuiApp } = await import("./TuiApp-26Q2ECKP.js");
|
|
509
509
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
510
510
|
render(
|
|
511
511
|
React7.createElement(TuiApp, {
|
|
@@ -525,10 +525,10 @@ program.command("doctor").description("Diagnose project setup and configuration
|
|
|
525
525
|
config({ path: projectEnvPath, override: true });
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
|
-
const { resolveProject } = await import("./resolve-package-
|
|
528
|
+
const { resolveProject } = await import("./resolve-package-DS44CNYU.js");
|
|
529
529
|
const resolution = await resolveProject(options.path, options.package);
|
|
530
530
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
531
|
-
const { DoctorApp } = await import("./DoctorApp-
|
|
531
|
+
const { DoctorApp } = await import("./DoctorApp-AID5U7MJ.js");
|
|
532
532
|
render(
|
|
533
533
|
React7.createElement(DoctorApp, {
|
|
534
534
|
projectPath,
|
|
@@ -541,13 +541,13 @@ program.command("doctor").description("Diagnose project setup and configuration
|
|
|
541
541
|
);
|
|
542
542
|
});
|
|
543
543
|
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) => {
|
|
544
|
-
const { resolveProject } = await import("./resolve-package-
|
|
544
|
+
const { resolveProject } = await import("./resolve-package-DS44CNYU.js");
|
|
545
545
|
const resolution = await resolveProject(options.path, options.package);
|
|
546
546
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
547
547
|
const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-KQ73KEIN.js");
|
|
548
548
|
let score = options.scan ? null : loadScoreFromLastReport(projectPath);
|
|
549
549
|
if (score === null) {
|
|
550
|
-
const { runSickbay: runSickbay2 } = await import("./dist-
|
|
550
|
+
const { runSickbay: runSickbay2 } = await import("./dist-CH3OBHPD.js");
|
|
551
551
|
const report = await runSickbay2({ projectPath, quotes: false });
|
|
552
552
|
try {
|
|
553
553
|
const { saveEntry, saveLastReport } = await import("./history-XLNVZEDI.js");
|
|
@@ -580,7 +580,7 @@ program.command("diff <branch>").description("Compare health score against anoth
|
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
582
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
583
|
-
const { DiffApp } = await import("./DiffApp-
|
|
583
|
+
const { DiffApp } = await import("./DiffApp-27FEBRY2.js");
|
|
584
584
|
render(
|
|
585
585
|
React7.createElement(DiffApp, {
|
|
586
586
|
projectPath: options.path,
|
|
@@ -106,7 +106,7 @@ async function serveWeb(report, preferredPort = 3030, aiService) {
|
|
|
106
106
|
if (url === "/sickbay-config.json") {
|
|
107
107
|
const basePath = "isMonorepo" in report ? report.rootPath : report.projectPath;
|
|
108
108
|
try {
|
|
109
|
-
const { loadConfig } = await import("./dist-
|
|
109
|
+
const { loadConfig } = await import("./dist-CH3OBHPD.js");
|
|
110
110
|
const config = await loadConfig(basePath);
|
|
111
111
|
if (config) {
|
|
112
112
|
res.writeHead(200, { "Content-Type": "application/json" });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sickbay",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.5",
|
|
4
4
|
"description": "Zero-config health check CLI for JavaScript and TypeScript projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -63,5 +63,6 @@
|
|
|
63
63
|
"tsup": "catalog:",
|
|
64
64
|
"typescript": "catalog:",
|
|
65
65
|
"vitest": "catalog:"
|
|
66
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"_bundleNote": "tsup bundles @nebulord/sickbay-core inline (see tsup.config.ts noExternal). Core's runtime deps are mirrored in `dependencies` below so the bundled require() calls resolve at runtime. Do NOT delete entries that look unused from cli source — they are needed by core's bundled code. Drift is enforced by `pnpm check:bundled-deps` (scripts/check-bundled-deps.mjs)."
|
|
67
68
|
}
|