sickbay 1.15.8 → 1.15.9

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 CHANGED
@@ -34,15 +34,18 @@ sickbay [options]
34
34
 
35
35
  ### Flags
36
36
 
37
- | Flag | Default | Description |
38
- | ---------------------- | --------------- | --------------------------------- |
39
- | `-p, --path <path>` | `process.cwd()` | Path to the project to analyze |
40
- | `-c, --checks <names>` | all | Comma-separated check IDs to run |
41
- | `--json` | false | Output raw JSON to stdout (no UI) |
42
- | `--web` | false | Open web dashboard after scan |
43
- | `--verbose` | false | Show tool output during checks |
44
- | `-V, --version` | | Print version |
45
- | `-h, --help` | | Show help |
37
+ | Flag | Default | Description |
38
+ | ---------------------- | --------------- | -------------------------------------------------- |
39
+ | `-p, --path <path>` | `process.cwd()` | Path to the project to analyze |
40
+ | `-c, --checks <names>` | all | Comma-separated check IDs to run |
41
+ | `--package <name>` | | Scope to a single named package (monorepo only) |
42
+ | `--json` | false | Output raw JSON to stdout (no UI) |
43
+ | `--web` | false | Open web dashboard after scan |
44
+ | `--no-ai` | | Disable AI features even if `ANTHROPIC_API_KEY` is set |
45
+ | `--no-quotes` | | Suppress personality quotes in output |
46
+ | `--verbose` | false | Show tool output during checks |
47
+ | `-V, --version` | | Print version |
48
+ | `-h, --help` | | Show help |
46
49
 
47
50
  ### Examples
48
51
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Header
3
- } from "./chunk-Q6CVOYTA.js";
3
+ } from "./chunk-GATOECD6.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-LK2SSQPX.js");
122
+ const { runSickbay } = await import("./dist-IEANON4U.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-O3BKUV2D.js";
3
+ } from "./chunk-IQYSZ3UW.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-Q6CVOYTA.js";
6
+ } from "./chunk-GATOECD6.js";
7
7
  import {
8
8
  detectPackageManager,
9
9
  detectProject
10
- } from "./chunk-7Z6JB75D.js";
10
+ } from "./chunk-W4GJ5ISW.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-O3BKUV2D.js";
3
+ } from "./chunk-IQYSZ3UW.js";
4
4
  import {
5
5
  ProgressList
6
6
  } from "./chunk-MBVA75EM.js";
7
7
  import {
8
8
  Header
9
- } from "./chunk-Q6CVOYTA.js";
9
+ } from "./chunk-GATOECD6.js";
10
10
  import {
11
11
  runSickbay
12
- } from "./chunk-7Z6JB75D.js";
12
+ } from "./chunk-W4GJ5ISW.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-O3BKUV2D.js";
3
+ } from "./chunk-IQYSZ3UW.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-Q6CVOYTA.js";
6
+ } from "./chunk-GATOECD6.js";
7
7
  import {
8
8
  detectProject
9
- } from "./chunk-7Z6JB75D.js";
9
+ } from "./chunk-W4GJ5ISW.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-O3BKUV2D.js";
7
+ } from "./chunk-IQYSZ3UW.js";
8
8
  import {
9
9
  Header
10
- } from "./chunk-Q6CVOYTA.js";
11
- import "./chunk-7Z6JB75D.js";
10
+ } from "./chunk-GATOECD6.js";
11
+ import "./chunk-W4GJ5ISW.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-7Z6JB75D.js";
17
+ } from "./chunk-W4GJ5ISW.js";
18
18
  import {
19
19
  loadHistory
20
20
  } from "./chunk-3OR2GFVE.js";
@@ -705,7 +705,7 @@ function TuiApp({
705
705
  return () => timers.forEach(clearTimeout);
706
706
  }, []);
707
707
  useEffect7(() => {
708
- checkForUpdate("1.15.7").then((info) => {
708
+ checkForUpdate("1.15.8").then((info) => {
709
709
  if (info) setUpdateInfo(info);
710
710
  });
711
711
  }, []);
@@ -731,7 +731,7 @@ function TuiApp({
731
731
  } catch {
732
732
  }
733
733
  try {
734
- const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
734
+ const { getDependencyTree } = await import("./dist-IEANON4U.js");
735
735
  const { saveDepTree } = await import("./history-XLNVZEDI.js");
736
736
  const tree = await getDependencyTree(projectPath, result.projectInfo.packageManager);
737
737
  saveDepTree(projectPath, tree);
@@ -835,7 +835,7 @@ function TuiApp({
835
835
  const webReport = monorepoReportRef.current ?? reportRef.current;
836
836
  if (!webReport) return;
837
837
  try {
838
- const { serveWeb } = await import("./web-H2AR7HV5.js");
838
+ const { serveWeb } = await import("./web-PL4RX5A2.js");
839
839
  const { default: openBrowser } = await import("open");
840
840
  let aiService;
841
841
  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.7")), 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.15.8")), 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,6 +1,6 @@
1
1
  import {
2
2
  detectMonorepo
3
- } from "./chunk-7Z6JB75D.js";
3
+ } from "./chunk-W4GJ5ISW.js";
4
4
 
5
5
  // src/lib/resolve-package.ts
6
6
  import { readFileSync } from "fs";
@@ -4213,7 +4213,7 @@ function parseOutdated(stdout) {
4213
4213
  if (!stdout.trim()) return [];
4214
4214
  try {
4215
4215
  const raw = JSON.parse(stdout);
4216
- return Object.entries(raw).filter(([_, info]) => info.current && info.latest).map(([name, info]) => ({
4216
+ return Object.entries(raw).filter(([_, info]) => info.current && info.latest && info.current !== info.latest).map(([name, info]) => ({
4217
4217
  name,
4218
4218
  current: info.current,
4219
4219
  latest: info.latest,
@@ -4234,10 +4234,11 @@ function getVersionParts(version) {
4234
4234
  ];
4235
4235
  }
4236
4236
  function getUpdateType(current, latest) {
4237
- const [curMaj, curMin] = getVersionParts(current);
4238
- const [latMaj, latMin] = getVersionParts(latest);
4239
- if (curMaj < latMaj) return "major";
4240
- if (curMin < latMin) return "minor";
4237
+ const [curMaj, curMin, curPatch] = getVersionParts(current);
4238
+ const [latMaj, latMin, latPatch] = getVersionParts(latest);
4239
+ if (curMaj !== latMaj) return "major";
4240
+ if (curMin !== latMin) return "minor";
4241
+ if (curPatch !== latPatch) return "patch";
4241
4242
  return "patch";
4242
4243
  }
4243
4244
  var SOURCE_DIRS2 = ["src", "app", "lib"];
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineConfig
3
- } from "./chunk-7Z6JB75D.js";
3
+ } from "./chunk-W4GJ5ISW.js";
4
4
  export {
5
5
  defineConfig
6
6
  };
@@ -29,7 +29,7 @@ import {
29
29
  runSickbay,
30
30
  runSickbayMonorepo,
31
31
  validateConfig
32
- } from "./chunk-7Z6JB75D.js";
32
+ } from "./chunk-W4GJ5ISW.js";
33
33
  export {
34
34
  BaseAdvisor,
35
35
  CATEGORY_WEIGHTS,
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-Q6CVOYTA.js";
11
+ } from "./chunk-GATOECD6.js";
12
12
  import {
13
13
  getScoreEmoji,
14
14
  runSickbay,
15
15
  runSickbayMonorepo
16
- } from "./chunk-7Z6JB75D.js";
16
+ } from "./chunk-W4GJ5ISW.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-LK2SSQPX.js");
193
+ const { getDependencyTree } = await import("./dist-IEANON4U.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-H2AR7HV5.js");
205
+ const { serveWeb } = await import("./web-PL4RX5A2.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-LK2SSQPX.js");
262
+ const { getDependencyTree } = await import("./dist-IEANON4U.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-H2AR7HV5.js");
271
+ const { serveWeb } = await import("./web-PL4RX5A2.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.7", "-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) => {
320
+ program.name("sickbay").description("React project health check CLI").version("1.15.8", "-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 (!existsSync(options.path)) {
322
322
  process.stderr.write(`Error: path does not exist: ${options.path}
323
323
  `);
@@ -332,13 +332,13 @@ program.name("sickbay").description("React project health check CLI").version("1
332
332
  const updatePromise = (async () => {
333
333
  try {
334
334
  const { checkForUpdate } = await import("./update-check-M7IFOMLJ.js");
335
- return await checkForUpdate("1.15.7");
335
+ return await checkForUpdate("1.15.8");
336
336
  } catch {
337
337
  return null;
338
338
  }
339
339
  })();
340
340
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
341
- const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2, getAvailableChecks } = await import("./dist-LK2SSQPX.js");
341
+ const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2, getAvailableChecks } = await import("./dist-IEANON4U.js");
342
342
  if (checks && checks.length > 0) {
343
343
  const knownNames = new Set(getAvailableChecks().map((c) => c.name));
344
344
  const unknown = checks.filter((c) => !knownNames.has(c));
@@ -410,7 +410,7 @@ program.name("sickbay").description("React project health check CLI").version("1
410
410
  } catch {
411
411
  }
412
412
  try {
413
- const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
413
+ const { getDependencyTree } = await import("./dist-IEANON4U.js");
414
414
  const { saveDepTree } = await import("./history-XLNVZEDI.js");
415
415
  const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);
416
416
  saveDepTree(options.path, tree);
@@ -437,16 +437,16 @@ program.command("init").description("Initialize .sickbay/ folder and run an init
437
437
  "add newly available checks to existing config without touching existing entries"
438
438
  ).option("--reset-config", "regenerate config from scratch (overwrites existing)").action(async (options) => {
439
439
  if (options.resetConfig) {
440
- const { generateConfigFile } = await import("./init-5A3DUVIL.js");
440
+ const { generateConfigFile } = await import("./init-PVZHRY3T.js");
441
441
  await generateConfigFile(options.path, { force: true });
442
442
  return;
443
443
  }
444
444
  if (options.sync) {
445
- const { syncConfigFile } = await import("./init-5A3DUVIL.js");
445
+ const { syncConfigFile } = await import("./init-PVZHRY3T.js");
446
446
  await syncConfigFile(options.path);
447
447
  return;
448
448
  }
449
- const { initSickbay } = await import("./init-5A3DUVIL.js");
449
+ const { initSickbay } = await import("./init-PVZHRY3T.js");
450
450
  await initSickbay(options.path);
451
451
  });
452
452
  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) => {
@@ -456,9 +456,9 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
456
456
  config({ path: projectEnvPath, override: true });
457
457
  }
458
458
  }
459
- const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
459
+ const { resolveProject } = await import("./resolve-package-LP7CD7JU.js");
460
460
  const resolution = await resolveProject(options.path, options.package);
461
- const { FixApp } = await import("./FixApp-TMRUKUJD.js");
461
+ const { FixApp } = await import("./FixApp-QRZTLYGC.js");
462
462
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
463
463
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
464
464
  render(
@@ -481,10 +481,10 @@ program.command("trend").description("Show score history and trends over time").
481
481
  config({ path: projectEnvPath, override: true });
482
482
  }
483
483
  }
484
- const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
484
+ const { resolveProject } = await import("./resolve-package-LP7CD7JU.js");
485
485
  const resolution = await resolveProject(options.path, options.package);
486
486
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
487
- const { TrendApp } = await import("./TrendApp-B7UGRJGC.js");
487
+ const { TrendApp } = await import("./TrendApp-3MG7OPMM.js");
488
488
  render(
489
489
  React7.createElement(TrendApp, {
490
490
  projectPath,
@@ -503,10 +503,10 @@ program.command("stats").description("Show a quick codebase overview and project
503
503
  config({ path: projectEnvPath, override: true });
504
504
  }
505
505
  }
506
- const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
506
+ const { resolveProject } = await import("./resolve-package-LP7CD7JU.js");
507
507
  const resolution = await resolveProject(options.path, options.package);
508
508
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
509
- const { StatsApp } = await import("./StatsApp-LXJWX24A.js");
509
+ const { StatsApp } = await import("./StatsApp-FPMKI45D.js");
510
510
  render(
511
511
  React7.createElement(StatsApp, {
512
512
  projectPath,
@@ -518,7 +518,7 @@ program.command("stats").description("Show a quick codebase overview and project
518
518
  );
519
519
  });
520
520
  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) => {
521
- const { TuiApp } = await import("./TuiApp-P5ESVGCB.js");
521
+ const { TuiApp } = await import("./TuiApp-CGUY6DP2.js");
522
522
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
523
523
  render(
524
524
  React7.createElement(TuiApp, {
@@ -538,10 +538,10 @@ program.command("doctor").description("Diagnose project setup and configuration
538
538
  config({ path: projectEnvPath, override: true });
539
539
  }
540
540
  }
541
- const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
541
+ const { resolveProject } = await import("./resolve-package-LP7CD7JU.js");
542
542
  const resolution = await resolveProject(options.path, options.package);
543
543
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
544
- const { DoctorApp } = await import("./DoctorApp-OPZBSIE6.js");
544
+ const { DoctorApp } = await import("./DoctorApp-4SV4QW3O.js");
545
545
  render(
546
546
  React7.createElement(DoctorApp, {
547
547
  projectPath,
@@ -554,13 +554,13 @@ program.command("doctor").description("Diagnose project setup and configuration
554
554
  );
555
555
  });
556
556
  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) => {
557
- const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
557
+ const { resolveProject } = await import("./resolve-package-LP7CD7JU.js");
558
558
  const resolution = await resolveProject(options.path, options.package);
559
559
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
560
560
  const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-KQ73KEIN.js");
561
561
  let score = options.scan ? null : loadScoreFromLastReport(projectPath);
562
562
  if (score === null) {
563
- const { runSickbay: runSickbay2 } = await import("./dist-LK2SSQPX.js");
563
+ const { runSickbay: runSickbay2 } = await import("./dist-IEANON4U.js");
564
564
  const report = await runSickbay2({ projectPath, quotes: false });
565
565
  try {
566
566
  const { saveEntry, saveLastReport } = await import("./history-XLNVZEDI.js");
@@ -593,7 +593,7 @@ program.command("diff <branch>").description("Compare health score against anoth
593
593
  }
594
594
  }
595
595
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
596
- const { DiffApp } = await import("./DiffApp-ECF2VINH.js");
596
+ const { DiffApp } = await import("./DiffApp-UEZKPPRV.js");
597
597
  render(
598
598
  React7.createElement(DiffApp, {
599
599
  projectPath: options.path,
@@ -4,7 +4,7 @@ import {
4
4
  getAvailableChecks,
5
5
  runSickbay,
6
6
  runSickbayMonorepo
7
- } from "./chunk-7Z6JB75D.js";
7
+ } from "./chunk-W4GJ5ISW.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-O3BKUV2D.js";
5
- import "./chunk-7Z6JB75D.js";
4
+ } from "./chunk-IQYSZ3UW.js";
5
+ import "./chunk-W4GJ5ISW.js";
6
6
  export {
7
7
  resolveProject,
8
8
  shortName