sickbay 1.16.2 → 1.16.4

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/dist/index.js CHANGED
@@ -130,7 +130,7 @@ function Header({ projectName }) {
130
130
  return /* @__PURE__ */ React.createElement(Box, {
131
131
  flexDirection: "column",
132
132
  marginBottom: 1
133
- }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.16.1")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, {
133
+ }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.16.3")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, {
134
134
  bold: true,
135
135
  color: "white"
136
136
  }, projectName)));
@@ -294,7 +294,7 @@ function App({ projectPath, checks, openWeb, enableAI, verbose, quotes, isMonore
294
294
  setProjectName(`monorepo (${r.packages.length} packages)`);
295
295
  try {
296
296
  const { getDependencyTree } = await import("./dist-Bjhxbcak.js").then((n) => n.s);
297
- const { saveDepTree } = await import("./history-DVegAwFp.js").then((n) => n.n);
297
+ const { saveDepTree } = await import("./history-C9hu3f6s.js").then((n) => n.n);
298
298
  const packages = {};
299
299
  for (const pkg of r.packages) packages[pkg.name] = await getDependencyTree(pkg.path, r.packageManager);
300
300
  saveDepTree(projectPath, { packages });
@@ -302,7 +302,7 @@ function App({ projectPath, checks, openWeb, enableAI, verbose, quotes, isMonore
302
302
  if (openWeb) {
303
303
  setPhase("opening-web");
304
304
  try {
305
- const { serveWeb } = await import("./web-D5etye5Q.js");
305
+ const { serveWeb } = await import("./web-CFBLfBdc.js");
306
306
  const { default: openBrowser } = await import("open");
307
307
  let aiService;
308
308
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -357,19 +357,19 @@ function App({ projectPath, checks, openWeb, enableAI, verbose, quotes, isMonore
357
357
  setProjectName(r.projectInfo.name);
358
358
  setReport(r);
359
359
  try {
360
- const { saveEntry, saveLastReport } = await import("./history-DVegAwFp.js").then((n) => n.n);
360
+ const { saveEntry, saveLastReport } = await import("./history-C9hu3f6s.js").then((n) => n.n);
361
361
  saveEntry(r);
362
362
  saveLastReport(r);
363
363
  } catch {}
364
364
  try {
365
365
  const { getDependencyTree } = await import("./dist-Bjhxbcak.js").then((n) => n.s);
366
- const { saveDepTree } = await import("./history-DVegAwFp.js").then((n) => n.n);
366
+ const { saveDepTree } = await import("./history-C9hu3f6s.js").then((n) => n.n);
367
367
  saveDepTree(projectPath, await getDependencyTree(projectPath, r.projectInfo.packageManager));
368
368
  } catch {}
369
369
  if (openWeb) {
370
370
  setPhase("opening-web");
371
371
  try {
372
- const { serveWeb } = await import("./web-D5etye5Q.js");
372
+ const { serveWeb } = await import("./web-CFBLfBdc.js");
373
373
  const { default: openBrowser } = await import("open");
374
374
  let aiService;
375
375
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -469,7 +469,7 @@ config({
469
469
  quiet: true
470
470
  });
471
471
  const program = new Command();
472
- program.name("sickbay").description("React project health check CLI").version("1.16.1", "-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) => {
472
+ program.name("sickbay").description("React project health check CLI").version("1.16.3", "-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) => {
473
473
  if (!existsSync(options.path)) {
474
474
  process.stderr.write(`Error: path does not exist: ${options.path}\n`);
475
475
  process.exit(1);
@@ -484,7 +484,7 @@ program.name("sickbay").description("React project health check CLI").version("1
484
484
  const updatePromise = (async () => {
485
485
  try {
486
486
  const { checkForUpdate } = await import("./update-check-C7bNNfvf.js");
487
- return await checkForUpdate("1.16.1");
487
+ return await checkForUpdate("1.16.3");
488
488
  } catch {
489
489
  return null;
490
490
  }
@@ -550,13 +550,13 @@ program.name("sickbay").description("React project health check CLI").version("1
550
550
  quotes: options.quotes
551
551
  });
552
552
  try {
553
- const { saveEntry, saveLastReport } = await import("./history-DVegAwFp.js").then((n) => n.n);
553
+ const { saveEntry, saveLastReport } = await import("./history-C9hu3f6s.js").then((n) => n.n);
554
554
  saveEntry(report);
555
555
  saveLastReport(report);
556
556
  } catch {}
557
557
  try {
558
558
  const { getDependencyTree } = await import("./dist-Bjhxbcak.js").then((n) => n.s);
559
- const { saveDepTree } = await import("./history-DVegAwFp.js").then((n) => n.n);
559
+ const { saveDepTree } = await import("./history-C9hu3f6s.js").then((n) => n.n);
560
560
  const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);
561
561
  saveDepTree(options.path, tree);
562
562
  } catch {}
@@ -576,19 +576,19 @@ program.name("sickbay").description("React project health check CLI").version("1
576
576
  });
577
577
  program.command("init").description("Initialize .sickbay/ folder and run an initial baseline scan").option("-p, --path <path>", "project path to initialize", process.cwd()).option("--sync", "add newly available checks to existing config without touching existing entries").option("--reset-config", "regenerate config from scratch (overwrites existing)").action(async (options) => {
578
578
  if (options.resetConfig) {
579
- const { generateConfigFile } = await import("./init-Dn7eDMEp.js");
579
+ const { generateConfigFile } = await import("./init-Czn8P7An.js");
580
580
  await generateConfigFile(options.path, { force: true });
581
581
  return;
582
582
  }
583
583
  if (options.sync) {
584
- const { syncConfigFile } = await import("./init-Dn7eDMEp.js");
584
+ const { syncConfigFile } = await import("./init-Czn8P7An.js");
585
585
  await syncConfigFile(options.path);
586
586
  return;
587
587
  }
588
- const { initSickbay } = await import("./init-Dn7eDMEp.js");
588
+ const { initSickbay } = await import("./init-Czn8P7An.js");
589
589
  await initSickbay(options.path);
590
590
  });
591
- 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) => {
591
+ 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("--skip-git-check", "skip the uncommitted-changes warning before applying source-modifying fixes").option("--verbose", "show verbose output").action(async (options) => {
592
592
  if (options.path && options.path !== process.cwd()) {
593
593
  const projectEnvPath = join(options.path, ".env");
594
594
  if (existsSync(projectEnvPath)) config({
@@ -598,7 +598,7 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
598
598
  }
599
599
  const { resolveProject } = await import("./resolve-package-DS27JBhN.js");
600
600
  const resolution = await resolveProject(options.path, options.package);
601
- const { FixApp } = await import("./FixApp-MWXohP60.js");
601
+ const { FixApp } = await import("./FixApp-CFotJ2y8.js");
602
602
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
603
603
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
604
604
  render(React.createElement(FixApp, {
@@ -606,6 +606,7 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
606
606
  checks,
607
607
  applyAll: options.all ?? false,
608
608
  dryRun: options.dryRun ?? false,
609
+ skipGitCheck: options.skipGitCheck ?? false,
609
610
  verbose: options.verbose ?? false,
610
611
  isMonorepo: resolution.isMonorepo && !resolution.targetPath,
611
612
  packagePaths: resolution.isMonorepo ? resolution.packagePaths : void 0,
@@ -623,7 +624,7 @@ program.command("trend").description("Show score history and trends over time").
623
624
  const { resolveProject } = await import("./resolve-package-DS27JBhN.js");
624
625
  const resolution = await resolveProject(options.path, options.package);
625
626
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
626
- const { TrendApp } = await import("./TrendApp-DOBt7ITA.js");
627
+ const { TrendApp } = await import("./TrendApp-D_YTj9kI.js");
627
628
  render(React.createElement(TrendApp, {
628
629
  projectPath,
629
630
  last: parseInt(options.last, 10),
@@ -654,7 +655,7 @@ program.command("stats").description("Show a quick codebase overview and project
654
655
  }));
655
656
  });
656
657
  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) => {
657
- const { TuiApp } = await import("./TuiApp-D4Wn81Qv.js");
658
+ const { TuiApp } = await import("./TuiApp-B3l1OC7M.js");
658
659
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
659
660
  render(React.createElement(TuiApp, {
660
661
  projectPath: options.path,
@@ -689,7 +690,7 @@ program.command("badge").description("Generate a health score badge for your REA
689
690
  const { resolveProject } = await import("./resolve-package-DS27JBhN.js");
690
691
  const resolution = await resolveProject(options.path, options.package);
691
692
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
692
- const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-DB3y0fWt.js");
693
+ const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-CTayKnYV.js");
693
694
  let score = options.scan ? null : loadScoreFromLastReport(projectPath);
694
695
  if (score === null) {
695
696
  const { runSickbay } = await import("./dist-Bjhxbcak.js").then((n) => n.s);
@@ -698,7 +699,7 @@ program.command("badge").description("Generate a health score badge for your REA
698
699
  quotes: false
699
700
  });
700
701
  try {
701
- const { saveEntry, saveLastReport } = await import("./history-DVegAwFp.js").then((n) => n.n);
702
+ const { saveEntry, saveLastReport } = await import("./history-C9hu3f6s.js").then((n) => n.n);
702
703
  saveEntry(report);
703
704
  saveLastReport(report);
704
705
  } catch {}
@@ -724,7 +725,7 @@ program.command("diff <branch>").description("Compare health score against anoth
724
725
  });
725
726
  }
726
727
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
727
- const { DiffApp } = await import("./DiffApp-DeNEtlY7.js");
728
+ const { DiffApp } = await import("./DiffApp-39aMGuNc.js");
728
729
  render(React.createElement(DiffApp, {
729
730
  projectPath: options.path,
730
731
  branch,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Spinner","formatDuration"],"sources":["../src/lib/issue-grouping.ts","../src/lib/messages.ts","../src/components/BestPractices.tsx","../src/components/ScoreBar.tsx","../src/components/CheckResult.tsx","../src/components/Header.tsx","../src/components/ProgressList.tsx","../src/components/QuickWins.tsx","../src/components/Summary.tsx","../src/components/UpdateNotice.tsx","../src/components/App.tsx","../src/index.ts"],"sourcesContent":["import type { CheckResult } from 'sickbay-core';\n\nexport function extractPatternStem(message: string): string {\n const idx = message.indexOf(' \\u2014 ');\n return idx >= 0 ? message.slice(idx + 3) : message;\n}\n\nexport function countUniqueIssues(checks: CheckResult[]): {\n critical: number;\n warnings: number;\n info: number;\n totalCritical: number;\n totalWarnings: number;\n totalInfo: number;\n} {\n const seen = { critical: new Set<string>(), warning: new Set<string>(), info: new Set<string>() };\n const totals = { critical: 0, warning: 0, info: 0 };\n\n for (const check of checks) {\n for (const issue of check.issues) {\n const stem = extractPatternStem(issue.message);\n const key = `${check.id}::${stem}`;\n seen[issue.severity].add(key);\n totals[issue.severity]++;\n }\n }\n\n return {\n critical: seen.critical.size,\n warnings: seen.warning.size,\n info: seen.info.size,\n totalCritical: totals.critical,\n totalWarnings: totals.warning,\n totalInfo: totals.info,\n };\n}\n","export const LOADING_MESSAGES = [\n 'Scanning for pre-existing conditions…',\n 'Counting packages… still counting…',\n 'Still here. Still scanning...',\n 'The unused dependencies know what they did...',\n 'Every unused export is a tiny cry for help...',\n \"Checking if 'TODO: fix later' was ever fixed later...\",\n 'Your secrets are safe with us. Unlike your .env file...',\n 'Good things take time. This is one of the good things. Probably...',\n 'npm audit found issues. npm audit --fix found different issues.',\n 'This is fine...',\n 'Evaluating life choices. Yours. Via package.json.',\n 'Almost done. (This is not a legally binding statement.)',\n 'node_modules: depth unknown. Will not attempt.',\n 'Performing checks. Results may vary...',\n];\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport type { SickbayReport } from 'sickbay-core';\n\ninterface BestPracticesProps {\n report: SickbayReport;\n}\n\nexport function BestPractices({ report }: BestPracticesProps) {\n const recs = report.recommendations;\n if (!recs || recs.length === 0) return null;\n\n const sorted = [...recs].sort((a, b) => {\n const order = { recommend: 0, suggest: 1 };\n return order[a.severity] - order[b.severity];\n });\n\n const display = sorted.slice(0, 5);\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>💡 Advisor:</Text>\n {display.map((rec) => (\n <Box key={rec.id} marginLeft={2}>\n <Text color={rec.severity === 'recommend' ? 'yellow' : 'gray'}>\n {rec.severity === 'recommend' ? '● ' : '○ '}\n </Text>\n <Text bold>{rec.title}</Text>\n <Text dimColor> — {rec.message}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\n/**\n * Component to display a horizontal score bar representing the overall health score.\n * The bar is filled proportionally to the score and colored based on thresholds:\n * - Green for 80 and above\n * - Yellow for 60-79\n * - Red for below 60\n */\n\ninterface ScoreBarProps {\n score: number;\n width?: number;\n}\n\nexport function ScoreBar({ score, width = 20 }: ScoreBarProps) {\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red';\n\n return (\n <Box>\n <Text color={color}>{'█'.repeat(filled)}</Text>\n <Text dimColor>{'░'.repeat(empty)}</Text>\n <Text color={color}> {score}/100</Text>\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport { ScoreBar } from './ScoreBar.js';\n\nimport type { CheckResult as CheckResultType } from 'sickbay-core';\n\nconst STATUS_ICONS = {\n pass: '✓',\n warning: '⚠',\n fail: '✗',\n skipped: '○',\n};\n\nconst CATEGORY_ICONS: Record<string, string> = {\n dependencies: '📦',\n security: '✔',\n 'code-quality': '✔',\n performance: '⚡',\n git: '✔',\n};\n\ninterface CheckResultProps {\n result: CheckResultType;\n}\n\nexport function CheckResultRow({ result }: CheckResultProps) {\n const statusColor =\n result.status === 'pass'\n ? 'green'\n : result.status === 'fail'\n ? 'red'\n : result.status === 'skipped'\n ? 'gray'\n : 'yellow';\n const icon = CATEGORY_ICONS[result.category] ?? '•';\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box>\n <Text>{icon} </Text>\n <Text bold>{result.name}</Text>\n <Text dimColor> via {result.toolsUsed.join(', ')}</Text>\n </Box>\n <Box marginLeft={2}>\n <ScoreBar score={result.score} width={16} />\n <Text color={statusColor}>\n {' '}\n {STATUS_ICONS[result.status]} {result.status}\n </Text>\n </Box>\n {result.issues.slice(0, 3).map((issue) => (\n <Box key={`${issue.severity}-${issue.message}`} marginLeft={2}>\n <Text\n color={\n issue.severity === 'critical'\n ? 'red'\n : issue.severity === 'warning'\n ? 'yellow'\n : 'gray'\n }\n >\n {issue.severity === 'critical' ? ' ✗' : issue.severity === 'warning' ? ' ⚠' : ' ℹ'}{' '}\n {issue.message}\n </Text>\n </Box>\n ))}\n {result.issues.length > 3 && (\n <Box marginLeft={4}>\n <Text dimColor>... and {result.issues.length - 3} more</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\ndeclare const __VERSION__: string;\n\nconst ASCII_ART = `\n███████ ██ ██████ ██ ██ ██████ █████ ██ ██ \n██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ \n███████ ██ ██ █████ ██████ ███████ ████ \n ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ \n███████ ██ ██████ ██ ██ ██████ ██ ██ ██ \n\nA vitals health check for your app\n`.trim();\n\ninterface HeaderProps {\n projectName?: string;\n}\n\nexport function Header({ projectName }: HeaderProps) {\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"green\">{ASCII_ART}</Text>\n <Box marginTop={1}>\n <Text dimColor> v{__VERSION__}</Text>\n </Box>\n {projectName && (\n <Box marginTop={1}>\n <Text dimColor> Analyzing </Text>\n <Text bold color=\"white\">\n {projectName}\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\n\nimport { Box, Text } from 'ink';\n\nconst SPINNER_FRAMES = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];\n\nfunction Spinner() {\n const [frame, setFrame] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);\n return () => clearInterval(id);\n }, []);\n return <Text color=\"green\">{SPINNER_FRAMES[frame]}</Text>;\n}\n\ninterface ProgressItem {\n name: string;\n status: 'pending' | 'running' | 'done';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n}\n\nexport function ProgressList({ items }: ProgressListProps) {\n return (\n <Box flexDirection=\"column\">\n {items.map((item) => (\n <Box key={item.name}>\n {item.status === 'running' ? (\n <Spinner />\n ) : item.status === 'done' ? (\n <Text color=\"green\">✓</Text>\n ) : (\n <Text dimColor>○</Text>\n )}\n <Text> {item.name}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport type { SickbayReport } from 'sickbay-core';\n\n/**\n * Component to display quick wins based on the report's issues that have fixes available.\n * It shows up to 5 fixable issues, sorted by severity (critical > warning > info).\n */\n\ninterface QuickWinsProps {\n report: SickbayReport;\n}\n\nfunction replacePackageManager(cmd: string, pm: string): string {\n if (pm === 'npm') return cmd;\n const install = pm === 'pnpm' ? 'pnpm add' : pm === 'yarn' ? 'yarn add' : 'bun add';\n const uninstall = pm === 'pnpm' ? 'pnpm remove' : pm === 'yarn' ? 'yarn remove' : 'bun remove';\n const update = pm === 'pnpm' ? 'pnpm update' : pm === 'yarn' ? 'yarn upgrade' : 'bun update';\n const auditFix =\n pm === 'pnpm' ? 'pnpm audit --fix' : pm === 'yarn' ? 'yarn npm audit --fix' : 'bun audit';\n return cmd\n .replace(/^npm install(?=\\s)/, install)\n .replace(/^npm uninstall(?=\\s)/, uninstall)\n .replace(/^npm update(?=\\s)/, update)\n .replace(/^npm audit fix/, auditFix);\n}\n\nexport function QuickWins({ report }: QuickWinsProps) {\n const pm = report.projectInfo?.packageManager ?? 'npm';\n const fixes = report.checks\n .flatMap((c) => c.issues)\n .filter((i) => i.fix?.command)\n .sort((a, b) => {\n const order = { critical: 0, warning: 1, info: 2 };\n return order[a.severity] - order[b.severity];\n })\n .slice(0, 5);\n\n if (fixes.length === 0) return null;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>🔥 Quick Wins:</Text>\n {fixes.map((fix) => (\n <Box key={`${fix.severity}-${fix.message}`} marginLeft={2}>\n <Text dimColor>→ </Text>\n <Text>{fix.fix!.description}</Text>\n {fix.fix!.command && (\n <Text dimColor>: {replacePackageManager(fix.fix!.command, pm)}</Text>\n )}\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\nimport { getScoreEmoji } from 'sickbay-core';\n\nimport { countUniqueIssues } from '../lib/issue-grouping.js';\nimport { ScoreBar } from './ScoreBar.js';\n\nimport type { SickbayReport } from 'sickbay-core';\n\n/**\n * Summary component displays the overall health score of the project along with a breakdown of critical issues, warnings, and info.\n * It uses the ScoreBar component to visually represent the overall score and color-codes the counts of issues based on severity.\n */\n\ninterface SummaryProps {\n report: SickbayReport;\n scanDuration?: number | null;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(1)}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.round(seconds % 60);\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function Summary({ report, scanDuration }: SummaryProps) {\n const u = countUniqueIssues(report.checks);\n\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>{'━'.repeat(52)}</Text>\n <Box marginTop={1}>\n <Text bold>Overall Health Score: </Text>\n <ScoreBar score={report.overallScore} width={12} />\n <Text> {getScoreEmoji(report.overallScore)}</Text>\n {scanDuration != null && <Text dimColor> {formatDuration(scanDuration)}</Text>}\n </Box>\n <Box marginTop={1}>\n <Text color=\"red\">\n {' '}\n ✗ {u.critical} critical\n {u.totalCritical > u.critical ? ` (${u.totalCritical} total)` : ''}\n </Text>\n <Text color=\"yellow\">\n {' '}\n ⚠ {u.warnings} warning{u.warnings !== 1 ? 's' : ''}\n {u.totalWarnings > u.warnings ? ` (${u.totalWarnings} total)` : ''}\n </Text>\n <Text color=\"gray\"> i {u.info} info</Text>\n </Box>\n {report.quote && (\n <Box marginTop={1}>\n <Text italic dimColor>\n \"{report.quote.text}\"\n </Text>\n <Text dimColor> — {report.quote.source}</Text>\n </Box>\n )}\n {report.config?.hasCustomConfig && (\n <Box marginTop={1}>\n <Text dimColor italic>\n Custom config active\n {report.config.disabledChecks.length > 0 &&\n ` (${report.config.disabledChecks.length} check${report.config.disabledChecks.length === 1 ? '' : 's'} disabled)`}\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\ninterface UpdateNoticeProps {\n currentVersion: string;\n latestVersion: string;\n}\n\nexport function UpdateNotice({ currentVersion, latestVersion }: UpdateNoticeProps) {\n const line1 = `Update available: ${currentVersion} → ${latestVersion}`;\n const line2 = 'npx sickbay@latest (one-time run)';\n const line3 = 'npm i -g sickbay@latest (global install)';\n const maxLength = Math.max(line1.length, line2.length, line3.length);\n const padding = 2;\n const boxWidth = maxLength + padding * 2;\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"yellow\" dimColor>\n {`╭${'─'.repeat(boxWidth)}╮`}\n </Text>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line1}\n </Text>\n </Box>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line2}\n </Text>\n </Box>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line3}\n </Text>\n </Box>\n <Text color=\"yellow\" dimColor>\n {`╰${'─'.repeat(boxWidth)}╯`}\n </Text>\n </Box>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\n\nimport { Box, Text, useApp } from 'ink';\nimport Gradient from 'ink-gradient';\nimport Spinner from 'ink-spinner';\nimport { runSickbay, runSickbayMonorepo } from 'sickbay-core';\n\nimport { countUniqueIssues } from '../lib/issue-grouping.js';\nimport { LOADING_MESSAGES } from '../lib/messages.js';\nimport { BestPractices } from './BestPractices.js';\nimport { CheckResultRow } from './CheckResult.js';\nimport { Header } from './Header.js';\nimport { ProgressList } from './ProgressList.js';\nimport { QuickWins } from './QuickWins.js';\nimport { Summary } from './Summary.js';\nimport { UpdateNotice } from './UpdateNotice.js';\n\nimport type { UpdateInfo } from '../lib/update-check.js';\nimport type { SickbayReport, MonorepoReport, PackageReport } from 'sickbay-core';\n\ninterface AppProps {\n projectPath: string;\n checks?: string[];\n openWeb?: boolean;\n enableAI?: boolean;\n verbose?: boolean;\n quotes?: boolean;\n isMonorepo?: boolean;\n updatePromise?: Promise<UpdateInfo | null>;\n}\n\ntype Phase = 'loading' | 'results' | 'opening-web' | 'error';\n\ninterface ProgressItem {\n name: string;\n status: 'pending' | 'running' | 'done';\n}\n\nfunction scoreBar(score: number, width = 10): string {\n const filled = Math.round((score / 100) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(1)}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.round(seconds % 60);\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function App({\n projectPath,\n checks,\n openWeb,\n enableAI,\n verbose,\n quotes,\n isMonorepo,\n updatePromise,\n}: AppProps) {\n const { exit } = useApp();\n const [phase, setPhase] = useState<Phase>('loading');\n const [report, setReport] = useState<SickbayReport | null>(null);\n const [monorepoReport, setMonorepoReport] = useState<MonorepoReport | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [progress, setProgress] = useState<ProgressItem[]>([]);\n const [webUrl, setWebUrl] = useState<string | null>(null);\n const [projectName, setProjectName] = useState<string | undefined>();\n const [scanningPackage, setScanningPackage] = useState<string | undefined>();\n const [loadingMsgIdx, setLoadingMsgIdx] = useState(0);\n const [scanDuration, setScanDuration] = useState<number | null>(null);\n const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);\n const hasRun = useRef(false);\n const scanStartTime = useRef<number>(0);\n\n useEffect(() => {\n if (!isMonorepo) return;\n const id = setInterval(() => {\n setLoadingMsgIdx((i) => (i + 1) % LOADING_MESSAGES.length);\n }, 4000);\n return () => clearInterval(id);\n }, [isMonorepo]);\n\n useEffect(() => {\n if (updatePromise) {\n updatePromise.then((info) => {\n if (info) setUpdateInfo(info);\n });\n }\n }, [updatePromise]);\n\n useEffect(() => {\n // Prevent double execution (React 18+ can run effects twice in dev/certain conditions)\n if (hasRun.current) return;\n hasRun.current = true;\n\n scanStartTime.current = Date.now();\n\n if (isMonorepo) {\n runSickbayMonorepo({\n projectPath,\n checks,\n verbose,\n quotes,\n onPackageStart: (name) => setScanningPackage(name),\n onPackageComplete: () => setScanningPackage(undefined),\n })\n .then(async (r) => {\n setScanDuration(Date.now() - scanStartTime.current);\n setMonorepoReport(r);\n setProjectName(`monorepo (${r.packages.length} packages)`);\n\n // Cache dependency tree for web dashboard\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('../lib/history.js');\n const packages: Record<string, unknown> = {};\n for (const pkg of r.packages) {\n packages[pkg.name] = await getDependencyTree(pkg.path, r.packageManager);\n }\n saveDepTree(projectPath, { packages });\n } catch {\n /* dep tree is optional */\n }\n\n if (openWeb) {\n setPhase('opening-web');\n try {\n const { serveWeb } = await import('../commands/web.js');\n const { default: openBrowser } = await import('open');\n\n let aiService;\n if (enableAI && process.env.ANTHROPIC_API_KEY) {\n const { createAIService } = await import('../services/ai.js');\n aiService = createAIService(process.env.ANTHROPIC_API_KEY);\n }\n\n const url = await serveWeb(r, 3030, aiService);\n setWebUrl(url);\n await openBrowser(url);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n setPhase('error');\n setTimeout(() => exit(), 100);\n }\n } else {\n setPhase('results');\n setTimeout(() => exit(), 100);\n }\n })\n .catch((err) => {\n setError(err.message ?? String(err));\n setPhase('error');\n setTimeout(() => exit(err), 100);\n });\n return;\n }\n\n runSickbay({\n projectPath,\n checks,\n verbose,\n quotes,\n onRunnersReady: (names) => {\n setProgress(names.map((name) => ({ name, status: 'pending' as const })));\n },\n onCheckStart: (name) => {\n setProgress((prev) => prev.map((p) => (p.name === name ? { ...p, status: 'running' } : p)));\n },\n onCheckComplete: (result) => {\n if (result.status === 'skipped') {\n setProgress((prev) => prev.filter((p) => p.name !== result.id));\n } else {\n setProgress((prev) =>\n prev.map((p) => (p.name === result.id ? { ...p, status: 'done' } : p)),\n );\n }\n },\n })\n .then(async (r) => {\n setScanDuration(Date.now() - scanStartTime.current);\n setProjectName(r.projectInfo.name);\n setReport(r);\n\n // Auto-save to trend history and last-report snapshot\n try {\n const { saveEntry, saveLastReport } = await import('../lib/history.js');\n saveEntry(r);\n saveLastReport(r);\n } catch {\n // Non-critical — silently ignore history save failures\n }\n\n // Cache dependency tree for web dashboard\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('../lib/history.js');\n const tree = await getDependencyTree(projectPath, r.projectInfo.packageManager);\n saveDepTree(projectPath, tree);\n } catch {\n /* dep tree is optional, don't break the scan */\n }\n\n if (openWeb) {\n setPhase('opening-web');\n try {\n const { serveWeb } = await import('../commands/web.js');\n const { default: openBrowser } = await import('open');\n\n // Create AI service if enabled and API key exists\n let aiService;\n if (enableAI && process.env.ANTHROPIC_API_KEY) {\n const { createAIService } = await import('../services/ai.js');\n aiService = createAIService(process.env.ANTHROPIC_API_KEY);\n }\n\n const url = await serveWeb(r, 3030, aiService);\n setWebUrl(url);\n await openBrowser(url);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n setPhase('error');\n setTimeout(() => exit(), 100);\n return;\n }\n // Keep process alive — user closes with Ctrl+C\n } else {\n setPhase('results');\n setTimeout(() => exit(), 100);\n }\n })\n .catch((err) => {\n setError(err.message ?? String(err));\n setPhase('error');\n setTimeout(() => exit(err), 100);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header projectName={projectName} />\n\n {updateInfo && (\n <UpdateNotice\n currentVersion={updateInfo.currentVersion}\n latestVersion={updateInfo.latestVersion}\n />\n )}\n\n {phase === 'loading' && (\n <Box flexDirection=\"column\">\n {isMonorepo ? (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"magenta\">\n <Spinner type=\"dots\" />\n </Text>\n <Text dimColor> {LOADING_MESSAGES[loadingMsgIdx]}</Text>\n </Box>\n {scanningPackage && (\n <Box marginTop={1} marginLeft={2}>\n <Text dimColor>→ </Text>\n <Text color=\"cyan\">{scanningPackage}</Text>\n </Box>\n )}\n </Box>\n ) : (\n <Box flexDirection=\"column\">\n <Text dimColor>Running health checks...</Text>\n <Box marginTop={1} marginLeft={2}>\n <ProgressList items={progress} />\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n {phase === 'error' && (\n <Box>\n <Text color=\"red\">✗ Error: {error}</Text>\n </Box>\n )}\n\n {phase === 'results' && monorepoReport && (\n <MonorepoSummaryTable report={monorepoReport} scanDuration={scanDuration} />\n )}\n\n {phase === 'results' && report && (\n <Box flexDirection=\"column\">\n {report.checks\n .filter((c) => c.status !== 'skipped')\n .map((check) => (\n <CheckResultRow key={check.id} result={check} />\n ))}\n <Summary report={report} scanDuration={scanDuration} />\n <QuickWins report={report} />\n <BestPractices report={report} />\n <Box marginTop={1}>\n <Text dimColor>View detailed report: </Text>\n <Text color=\"cyan\">sickbay --web</Text>\n </Box>\n </Box>\n )}\n\n {phase === 'opening-web' && (monorepoReport ?? report) && (\n <Box flexDirection=\"column\">\n {monorepoReport ? (\n <MonorepoSummaryTable report={monorepoReport} scanDuration={scanDuration} />\n ) : report ? (\n <>\n {report.checks\n .filter((c) => c.status !== 'skipped')\n .map((check) => (\n <CheckResultRow key={check.id} result={check} />\n ))}\n <Summary report={report} scanDuration={scanDuration} />\n </>\n ) : null}\n <Box marginTop={1}>\n {webUrl ? (\n <>\n <Text color=\"green\">✓ Dashboard running at </Text>\n <Text color=\"cyan\">{webUrl}</Text>\n <Text dimColor> (Ctrl+C to stop)</Text>\n </>\n ) : (\n <Text>\n <Text color=\"magenta\">\n <Spinner type=\"dots\" />\n </Text>{' '}\n <Gradient name=\"retro\">Launching dashboard with AI insights...</Gradient>\n </Text>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction MonorepoSummaryTable({\n report,\n scanDuration,\n}: {\n report: MonorepoReport;\n scanDuration: number | null;\n}) {\n const scoreColor = (score: number) => (score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red');\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold>Monorepo · </Text>\n <Text dimColor>{report.monorepoType} workspaces · </Text>\n <Text>{report.packages.length} packages</Text>\n </Box>\n {report.packages.map((pkg: PackageReport) => (\n <Box key={pkg.path} marginLeft={2} gap={1}>\n <Text color={scoreColor(pkg.score)}>{scoreBar(pkg.score)}</Text>\n <Text bold color={scoreColor(pkg.score)}>\n {String(pkg.score).padStart(3)}\n </Text>\n <Text>{pkg.name}</Text>\n <Text dimColor>{pkg.framework}</Text>\n {pkg.summary.critical > 0 && <Text color=\"red\"> {pkg.summary.critical} critical</Text>}\n </Box>\n ))}\n <Box marginTop={1} gap={2}>\n <Text bold>Overall: </Text>\n <Text color={scoreColor(report.overallScore)} bold>\n {report.overallScore}\n </Text>\n <Text dimColor>· </Text>\n {(() => {\n const u = countUniqueIssues(report.packages.flatMap((p) => p.checks));\n return (\n <>\n <Text color=\"red\">\n {u.critical} critical\n {u.totalCritical > u.critical ? ` (${u.totalCritical} total)` : ''}\n </Text>\n <Text dimColor>· </Text>\n <Text color=\"yellow\">\n {u.warnings} warnings\n {u.totalWarnings > u.warnings ? ` (${u.totalWarnings} total)` : ''}\n </Text>\n </>\n );\n })()}\n {scanDuration !== null && (\n <>\n <Text dimColor>· </Text>\n <Text dimColor>{formatDuration(scanDuration)}</Text>\n </>\n )}\n </Box>\n {report.quote && (\n <Box marginTop={1}>\n <Text italic dimColor>\n \"{report.quote.text}\"\n </Text>\n <Text dimColor> — {report.quote.source}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>Per-package details: </Text>\n <Text color=\"cyan\">sickbay --web</Text>\n </Box>\n </Box>\n );\n}\n","#!/usr/bin/env node\nimport { existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nimport React from 'react';\n\nimport { Command } from 'commander';\nimport { config } from 'dotenv';\nimport { render } from 'ink';\n\nimport { App } from './components/App.js';\n\ndeclare const __VERSION__: string;\n\n/**\n * Entry point for the Sickbay CLI application.\n * This script sets up the command-line interface using Commander, loads environment variables, and renders the appropriate Ink components based on user commands.\n * It supports multiple commands including the default scan, trend analysis, stats overview, and a doctor command for diagnosing project issues.\n * Each command can output results in JSON format or render an interactive UI in the terminal.\n */\n\n// Load .env from global config first (~/.sickbay/.env)\nconst globalConfigPath = join(homedir(), '.sickbay', '.env');\nif (existsSync(globalConfigPath)) {\n config({ path: globalConfigPath, debug: false, quiet: true });\n}\n\n// Load .env from current directory (overrides global)\nconfig({ debug: false, quiet: true });\n\nconst program = new Command();\n\nprogram\n .name('sickbay')\n .description('React project health check CLI')\n .version(__VERSION__, '-v, --version')\n .enablePositionalOptions()\n .passThroughOptions()\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--package <name>', 'scope to a single named package (monorepo only)')\n .option('--json', 'output raw JSON report')\n .option('--web', 'open web dashboard after scan')\n .option('--no-ai', 'disable AI features')\n .option('--no-quotes', 'suppress personality quotes in output')\n .option('--verbose', 'show verbose output')\n .action(async (options) => {\n // Validate --path exists before doing any I/O\n if (!existsSync(options.path)) {\n process.stderr.write(`Error: path does not exist: ${options.path}\\n`);\n process.exit(1);\n }\n\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n // Non-blocking update check\n const updatePromise = (async () => {\n try {\n const { checkForUpdate } = await import('./lib/update-check.js');\n return await checkForUpdate(__VERSION__);\n } catch {\n return null;\n }\n })();\n\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const { detectMonorepo, runSickbay, runSickbayMonorepo, getAvailableChecks } =\n await import('sickbay-core');\n\n // Warn early if any --checks IDs don't match known check names\n if (checks && checks.length > 0) {\n const knownNames = new Set(getAvailableChecks().map((c) => c.name));\n const unknown = checks.filter((c: string) => !knownNames.has(c));\n if (unknown.length > 0) {\n process.stderr.write(`Warning: unknown check ID(s): ${unknown.join(', ')}\\n`);\n }\n }\n\n const monorepoInfo = await detectMonorepo(options.path);\n\n // --package flag: scope to a single named package within a monorepo\n if (options.package && monorepoInfo.isMonorepo) {\n const { readFileSync } = await import('fs');\n const targetPath = monorepoInfo.packagePaths.find((p) => {\n try {\n const pkg = JSON.parse(readFileSync(join(p, 'package.json'), 'utf-8'));\n return pkg.name === options.package || pkg.name?.endsWith(`/${options.package}`);\n } catch {\n return false;\n }\n });\n\n if (!targetPath) {\n process.stderr.write(`Package \"${options.package}\" not found in monorepo\\n`);\n process.exit(1);\n }\n\n if (options.json) {\n const report = await runSickbay({\n projectPath: targetPath,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n render(\n React.createElement(App, {\n projectPath: targetPath,\n checks,\n openWeb: options.web,\n enableAI: options.ai !== false,\n verbose: options.verbose,\n quotes: options.quotes,\n updatePromise,\n }),\n );\n return;\n }\n\n if (options.json) {\n if (monorepoInfo.isMonorepo) {\n const report = await runSickbayMonorepo({\n projectPath: options.path,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n const report = await runSickbay({\n projectPath: options.path,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n\n // Auto-save to trend history and last-report snapshot\n try {\n const { saveEntry, saveLastReport } = await import('./lib/history.js');\n saveEntry(report);\n saveLastReport(report);\n } catch {\n // Non-critical\n }\n\n // Cache dependency tree\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('./lib/history.js');\n const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);\n saveDepTree(options.path, tree);\n } catch {\n /* dep tree is optional */\n }\n\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n render(\n React.createElement(App, {\n projectPath: options.path,\n checks,\n openWeb: options.web,\n enableAI: options.ai !== false,\n verbose: options.verbose,\n quotes: options.quotes,\n isMonorepo: monorepoInfo.isMonorepo,\n updatePromise,\n }),\n );\n });\n\n// --- sickbay init ---\nprogram\n .command('init')\n .description('Initialize .sickbay/ folder and run an initial baseline scan')\n .option('-p, --path <path>', 'project path to initialize', process.cwd())\n .option(\n '--sync',\n 'add newly available checks to existing config without touching existing entries',\n )\n .option('--reset-config', 'regenerate config from scratch (overwrites existing)')\n .action(async (options) => {\n if (options.resetConfig) {\n const { generateConfigFile } = await import('./commands/init.js');\n await generateConfigFile(options.path, { force: true });\n return;\n }\n if (options.sync) {\n const { syncConfigFile } = await import('./commands/init.js');\n await syncConfigFile(options.path);\n return;\n }\n const { initSickbay } = await import('./commands/init.js');\n await initSickbay(options.path);\n });\n\n// --- sickbay fix ---\nprogram\n .command('fix')\n .description('Interactively fix issues found by sickbay scan')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--all', 'apply all available fixes without prompting')\n .option('--dry-run', 'show what would be fixed without executing')\n .option('--verbose', 'show verbose output')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const { FixApp } = await import('./components/FixApp.js');\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n render(\n React.createElement(FixApp, {\n projectPath,\n checks,\n applyAll: options.all ?? false,\n dryRun: options.dryRun ?? false,\n verbose: options.verbose ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay trend ---\nprogram\n .command('trend')\n .description('Show score history and trends over time')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-n, --last <count>', 'number of recent scans to show', '20')\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--json', 'output trend data as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { TrendApp } = await import('./components/TrendApp.js');\n render(\n React.createElement(TrendApp, {\n projectPath,\n last: parseInt(options.last, 10),\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay stats ---\nprogram\n .command('stats')\n .description('Show a quick codebase overview and project summary')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--json', 'output stats as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { StatsApp } = await import('./components/StatsApp.js');\n render(\n React.createElement(StatsApp, {\n projectPath,\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay tui ---\nprogram\n .command('tui')\n .description('Launch the persistent developer dashboard')\n .option('-p, --path <path>', 'project path to monitor', process.cwd())\n .option('--no-watch', 'disable file-watching auto-refresh')\n .option('--no-quotes', 'suppress personality quotes in output')\n .option('--refresh <seconds>', 'auto-refresh interval in seconds', '300')\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .action(async (options) => {\n const { TuiApp } = await import('./components/tui/TuiApp.js');\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n render(\n React.createElement(TuiApp, {\n projectPath: options.path,\n checks,\n watchEnabled: options.watch !== false,\n refreshInterval: parseInt(options.refresh, 10),\n quotes: options.quotes,\n }),\n { exitOnCtrlC: true },\n );\n });\n\n// --- sickbay doctor ---\nprogram\n .command('doctor')\n .description('Diagnose project setup and configuration issues')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--fix', 'auto-scaffold missing configuration files')\n .option('--json', 'output diagnostic results as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { DoctorApp } = await import('./components/DoctorApp.js');\n render(\n React.createElement(DoctorApp, {\n projectPath,\n autoFix: options.fix ?? false,\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay badge ---\nprogram\n .command('badge')\n .description('Generate a health score badge for your README')\n .option('-p, --path <path>', 'project path', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--html', 'output HTML <img> tag instead of markdown')\n .option('--url', 'output bare badge URL only')\n .option('--label <text>', 'custom badge label', 'sickbay')\n .option('--scan', 'run a fresh scan instead of using last report')\n .action(async (options) => {\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } =\n await import('./commands/badge.js');\n\n let score = options.scan ? null : loadScoreFromLastReport(projectPath);\n\n if (score === null) {\n const { runSickbay } = await import('sickbay-core');\n const report = await runSickbay({ projectPath, quotes: false });\n\n try {\n const { saveEntry, saveLastReport } = await import('./lib/history.js');\n saveEntry(report);\n saveLastReport(report);\n } catch {\n // Non-critical\n }\n\n score = report.overallScore;\n }\n\n let output: string;\n if (options.url) {\n output = badgeUrl(score, options.label);\n } else if (options.html) {\n output = badgeHtml(score, options.label);\n } else {\n output = badgeMarkdown(score, options.label);\n }\n\n process.stdout.write(output + '\\n');\n process.exit(0);\n });\n\n// --- sickbay claude ---\nprogram\n .command('claude')\n .description('Generate a Claude Code skill file for your project')\n .option('-p, --path <path>', 'project path', process.cwd())\n .action(async (options) => {\n const { generateClaudeSkill } = await import('./commands/claude.js');\n generateClaudeSkill(options.path);\n });\n\n// --- sickbay diff ---\nprogram\n .command('diff <branch>')\n .description('Compare health score against another branch')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--json', 'output diff as JSON')\n .option('--verbose', 'show verbose output')\n .action(async (branch, options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const { DiffApp } = await import('./components/DiffApp.js');\n render(\n React.createElement(DiffApp, {\n projectPath: options.path,\n branch,\n jsonOutput: options.json ?? false,\n checks,\n verbose: options.verbose,\n }),\n );\n });\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Spinner","formatDuration"],"sources":["../src/lib/issue-grouping.ts","../src/lib/messages.ts","../src/components/BestPractices.tsx","../src/components/ScoreBar.tsx","../src/components/CheckResult.tsx","../src/components/Header.tsx","../src/components/ProgressList.tsx","../src/components/QuickWins.tsx","../src/components/Summary.tsx","../src/components/UpdateNotice.tsx","../src/components/App.tsx","../src/index.ts"],"sourcesContent":["import type { CheckResult } from 'sickbay-core';\n\nexport function extractPatternStem(message: string): string {\n const idx = message.indexOf(' \\u2014 ');\n return idx >= 0 ? message.slice(idx + 3) : message;\n}\n\nexport function countUniqueIssues(checks: CheckResult[]): {\n critical: number;\n warnings: number;\n info: number;\n totalCritical: number;\n totalWarnings: number;\n totalInfo: number;\n} {\n const seen = { critical: new Set<string>(), warning: new Set<string>(), info: new Set<string>() };\n const totals = { critical: 0, warning: 0, info: 0 };\n\n for (const check of checks) {\n for (const issue of check.issues) {\n const stem = extractPatternStem(issue.message);\n const key = `${check.id}::${stem}`;\n seen[issue.severity].add(key);\n totals[issue.severity]++;\n }\n }\n\n return {\n critical: seen.critical.size,\n warnings: seen.warning.size,\n info: seen.info.size,\n totalCritical: totals.critical,\n totalWarnings: totals.warning,\n totalInfo: totals.info,\n };\n}\n","export const LOADING_MESSAGES = [\n 'Scanning for pre-existing conditions…',\n 'Counting packages… still counting…',\n 'Still here. Still scanning...',\n 'The unused dependencies know what they did...',\n 'Every unused export is a tiny cry for help...',\n \"Checking if 'TODO: fix later' was ever fixed later...\",\n 'Your secrets are safe with us. Unlike your .env file...',\n 'Good things take time. This is one of the good things. Probably...',\n 'npm audit found issues. npm audit --fix found different issues.',\n 'This is fine...',\n 'Evaluating life choices. Yours. Via package.json.',\n 'Almost done. (This is not a legally binding statement.)',\n 'node_modules: depth unknown. Will not attempt.',\n 'Performing checks. Results may vary...',\n];\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport type { SickbayReport } from 'sickbay-core';\n\ninterface BestPracticesProps {\n report: SickbayReport;\n}\n\nexport function BestPractices({ report }: BestPracticesProps) {\n const recs = report.recommendations;\n if (!recs || recs.length === 0) return null;\n\n const sorted = [...recs].sort((a, b) => {\n const order = { recommend: 0, suggest: 1 };\n return order[a.severity] - order[b.severity];\n });\n\n const display = sorted.slice(0, 5);\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>💡 Advisor:</Text>\n {display.map((rec) => (\n <Box key={rec.id} marginLeft={2}>\n <Text color={rec.severity === 'recommend' ? 'yellow' : 'gray'}>\n {rec.severity === 'recommend' ? '● ' : '○ '}\n </Text>\n <Text bold>{rec.title}</Text>\n <Text dimColor> — {rec.message}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\n/**\n * Component to display a horizontal score bar representing the overall health score.\n * The bar is filled proportionally to the score and colored based on thresholds:\n * - Green for 80 and above\n * - Yellow for 60-79\n * - Red for below 60\n */\n\ninterface ScoreBarProps {\n score: number;\n width?: number;\n}\n\nexport function ScoreBar({ score, width = 20 }: ScoreBarProps) {\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red';\n\n return (\n <Box>\n <Text color={color}>{'█'.repeat(filled)}</Text>\n <Text dimColor>{'░'.repeat(empty)}</Text>\n <Text color={color}> {score}/100</Text>\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport { ScoreBar } from './ScoreBar.js';\n\nimport type { CheckResult as CheckResultType } from 'sickbay-core';\n\nconst STATUS_ICONS = {\n pass: '✓',\n warning: '⚠',\n fail: '✗',\n skipped: '○',\n};\n\nconst CATEGORY_ICONS: Record<string, string> = {\n dependencies: '📦',\n security: '✔',\n 'code-quality': '✔',\n performance: '⚡',\n git: '✔',\n};\n\ninterface CheckResultProps {\n result: CheckResultType;\n}\n\nexport function CheckResultRow({ result }: CheckResultProps) {\n const statusColor =\n result.status === 'pass'\n ? 'green'\n : result.status === 'fail'\n ? 'red'\n : result.status === 'skipped'\n ? 'gray'\n : 'yellow';\n const icon = CATEGORY_ICONS[result.category] ?? '•';\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box>\n <Text>{icon} </Text>\n <Text bold>{result.name}</Text>\n <Text dimColor> via {result.toolsUsed.join(', ')}</Text>\n </Box>\n <Box marginLeft={2}>\n <ScoreBar score={result.score} width={16} />\n <Text color={statusColor}>\n {' '}\n {STATUS_ICONS[result.status]} {result.status}\n </Text>\n </Box>\n {result.issues.slice(0, 3).map((issue) => (\n <Box key={`${issue.severity}-${issue.message}`} marginLeft={2}>\n <Text\n color={\n issue.severity === 'critical'\n ? 'red'\n : issue.severity === 'warning'\n ? 'yellow'\n : 'gray'\n }\n >\n {issue.severity === 'critical' ? ' ✗' : issue.severity === 'warning' ? ' ⚠' : ' ℹ'}{' '}\n {issue.message}\n </Text>\n </Box>\n ))}\n {result.issues.length > 3 && (\n <Box marginLeft={4}>\n <Text dimColor>... and {result.issues.length - 3} more</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\ndeclare const __VERSION__: string;\n\nconst ASCII_ART = `\n███████ ██ ██████ ██ ██ ██████ █████ ██ ██ \n██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ \n███████ ██ ██ █████ ██████ ███████ ████ \n ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ \n███████ ██ ██████ ██ ██ ██████ ██ ██ ██ \n\nA vitals health check for your app\n`.trim();\n\ninterface HeaderProps {\n projectName?: string;\n}\n\nexport function Header({ projectName }: HeaderProps) {\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"green\">{ASCII_ART}</Text>\n <Box marginTop={1}>\n <Text dimColor> v{__VERSION__}</Text>\n </Box>\n {projectName && (\n <Box marginTop={1}>\n <Text dimColor> Analyzing </Text>\n <Text bold color=\"white\">\n {projectName}\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\n\nimport { Box, Text } from 'ink';\n\nconst SPINNER_FRAMES = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];\n\nfunction Spinner() {\n const [frame, setFrame] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);\n return () => clearInterval(id);\n }, []);\n return <Text color=\"green\">{SPINNER_FRAMES[frame]}</Text>;\n}\n\ninterface ProgressItem {\n name: string;\n status: 'pending' | 'running' | 'done';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n}\n\nexport function ProgressList({ items }: ProgressListProps) {\n return (\n <Box flexDirection=\"column\">\n {items.map((item) => (\n <Box key={item.name}>\n {item.status === 'running' ? (\n <Spinner />\n ) : item.status === 'done' ? (\n <Text color=\"green\">✓</Text>\n ) : (\n <Text dimColor>○</Text>\n )}\n <Text> {item.name}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\nimport type { SickbayReport } from 'sickbay-core';\n\n/**\n * Component to display quick wins based on the report's issues that have fixes available.\n * It shows up to 5 fixable issues, sorted by severity (critical > warning > info).\n */\n\ninterface QuickWinsProps {\n report: SickbayReport;\n}\n\nfunction replacePackageManager(cmd: string, pm: string): string {\n if (pm === 'npm') return cmd;\n const install = pm === 'pnpm' ? 'pnpm add' : pm === 'yarn' ? 'yarn add' : 'bun add';\n const uninstall = pm === 'pnpm' ? 'pnpm remove' : pm === 'yarn' ? 'yarn remove' : 'bun remove';\n const update = pm === 'pnpm' ? 'pnpm update' : pm === 'yarn' ? 'yarn upgrade' : 'bun update';\n const auditFix =\n pm === 'pnpm' ? 'pnpm audit --fix' : pm === 'yarn' ? 'yarn npm audit --fix' : 'bun audit';\n return cmd\n .replace(/^npm install(?=\\s)/, install)\n .replace(/^npm uninstall(?=\\s)/, uninstall)\n .replace(/^npm update(?=\\s)/, update)\n .replace(/^npm audit fix/, auditFix);\n}\n\nexport function QuickWins({ report }: QuickWinsProps) {\n const pm = report.projectInfo?.packageManager ?? 'npm';\n const fixes = report.checks\n .flatMap((c) => c.issues)\n .filter((i) => i.fix?.command)\n .sort((a, b) => {\n const order = { critical: 0, warning: 1, info: 2 };\n return order[a.severity] - order[b.severity];\n })\n .slice(0, 5);\n\n if (fixes.length === 0) return null;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>🔥 Quick Wins:</Text>\n {fixes.map((fix) => (\n <Box key={`${fix.severity}-${fix.message}`} marginLeft={2}>\n <Text dimColor>→ </Text>\n <Text>{fix.fix!.description}</Text>\n {fix.fix!.command && (\n <Text dimColor>: {replacePackageManager(fix.fix!.command, pm)}</Text>\n )}\n </Box>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\nimport { getScoreEmoji } from 'sickbay-core';\n\nimport { countUniqueIssues } from '../lib/issue-grouping.js';\nimport { ScoreBar } from './ScoreBar.js';\n\nimport type { SickbayReport } from 'sickbay-core';\n\n/**\n * Summary component displays the overall health score of the project along with a breakdown of critical issues, warnings, and info.\n * It uses the ScoreBar component to visually represent the overall score and color-codes the counts of issues based on severity.\n */\n\ninterface SummaryProps {\n report: SickbayReport;\n scanDuration?: number | null;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(1)}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.round(seconds % 60);\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function Summary({ report, scanDuration }: SummaryProps) {\n const u = countUniqueIssues(report.checks);\n\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>{'━'.repeat(52)}</Text>\n <Box marginTop={1}>\n <Text bold>Overall Health Score: </Text>\n <ScoreBar score={report.overallScore} width={12} />\n <Text> {getScoreEmoji(report.overallScore)}</Text>\n {scanDuration != null && <Text dimColor> {formatDuration(scanDuration)}</Text>}\n </Box>\n <Box marginTop={1}>\n <Text color=\"red\">\n {' '}\n ✗ {u.critical} critical\n {u.totalCritical > u.critical ? ` (${u.totalCritical} total)` : ''}\n </Text>\n <Text color=\"yellow\">\n {' '}\n ⚠ {u.warnings} warning{u.warnings !== 1 ? 's' : ''}\n {u.totalWarnings > u.warnings ? ` (${u.totalWarnings} total)` : ''}\n </Text>\n <Text color=\"gray\"> i {u.info} info</Text>\n </Box>\n {report.quote && (\n <Box marginTop={1}>\n <Text italic dimColor>\n \"{report.quote.text}\"\n </Text>\n <Text dimColor> — {report.quote.source}</Text>\n </Box>\n )}\n {report.config?.hasCustomConfig && (\n <Box marginTop={1}>\n <Text dimColor italic>\n Custom config active\n {report.config.disabledChecks.length > 0 &&\n ` (${report.config.disabledChecks.length} check${report.config.disabledChecks.length === 1 ? '' : 's'} disabled)`}\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { Box, Text } from 'ink';\n\ninterface UpdateNoticeProps {\n currentVersion: string;\n latestVersion: string;\n}\n\nexport function UpdateNotice({ currentVersion, latestVersion }: UpdateNoticeProps) {\n const line1 = `Update available: ${currentVersion} → ${latestVersion}`;\n const line2 = 'npx sickbay@latest (one-time run)';\n const line3 = 'npm i -g sickbay@latest (global install)';\n const maxLength = Math.max(line1.length, line2.length, line3.length);\n const padding = 2;\n const boxWidth = maxLength + padding * 2;\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"yellow\" dimColor>\n {`╭${'─'.repeat(boxWidth)}╮`}\n </Text>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line1}\n </Text>\n </Box>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line2}\n </Text>\n </Box>\n <Box paddingX={padding}>\n <Text color=\"yellow\" dimColor>\n {line3}\n </Text>\n </Box>\n <Text color=\"yellow\" dimColor>\n {`╰${'─'.repeat(boxWidth)}╯`}\n </Text>\n </Box>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\n\nimport { Box, Text, useApp } from 'ink';\nimport Gradient from 'ink-gradient';\nimport Spinner from 'ink-spinner';\nimport { runSickbay, runSickbayMonorepo } from 'sickbay-core';\n\nimport { countUniqueIssues } from '../lib/issue-grouping.js';\nimport { LOADING_MESSAGES } from '../lib/messages.js';\nimport { BestPractices } from './BestPractices.js';\nimport { CheckResultRow } from './CheckResult.js';\nimport { Header } from './Header.js';\nimport { ProgressList } from './ProgressList.js';\nimport { QuickWins } from './QuickWins.js';\nimport { Summary } from './Summary.js';\nimport { UpdateNotice } from './UpdateNotice.js';\n\nimport type { UpdateInfo } from '../lib/update-check.js';\nimport type { SickbayReport, MonorepoReport, PackageReport } from 'sickbay-core';\n\ninterface AppProps {\n projectPath: string;\n checks?: string[];\n openWeb?: boolean;\n enableAI?: boolean;\n verbose?: boolean;\n quotes?: boolean;\n isMonorepo?: boolean;\n updatePromise?: Promise<UpdateInfo | null>;\n}\n\ntype Phase = 'loading' | 'results' | 'opening-web' | 'error';\n\ninterface ProgressItem {\n name: string;\n status: 'pending' | 'running' | 'done';\n}\n\nfunction scoreBar(score: number, width = 10): string {\n const filled = Math.round((score / 100) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(1)}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.round(seconds % 60);\n return `${minutes}m ${remainingSeconds}s`;\n}\n\nexport function App({\n projectPath,\n checks,\n openWeb,\n enableAI,\n verbose,\n quotes,\n isMonorepo,\n updatePromise,\n}: AppProps) {\n const { exit } = useApp();\n const [phase, setPhase] = useState<Phase>('loading');\n const [report, setReport] = useState<SickbayReport | null>(null);\n const [monorepoReport, setMonorepoReport] = useState<MonorepoReport | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [progress, setProgress] = useState<ProgressItem[]>([]);\n const [webUrl, setWebUrl] = useState<string | null>(null);\n const [projectName, setProjectName] = useState<string | undefined>();\n const [scanningPackage, setScanningPackage] = useState<string | undefined>();\n const [loadingMsgIdx, setLoadingMsgIdx] = useState(0);\n const [scanDuration, setScanDuration] = useState<number | null>(null);\n const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);\n const hasRun = useRef(false);\n const scanStartTime = useRef<number>(0);\n\n useEffect(() => {\n if (!isMonorepo) return;\n const id = setInterval(() => {\n setLoadingMsgIdx((i) => (i + 1) % LOADING_MESSAGES.length);\n }, 4000);\n return () => clearInterval(id);\n }, [isMonorepo]);\n\n useEffect(() => {\n if (updatePromise) {\n updatePromise.then((info) => {\n if (info) setUpdateInfo(info);\n });\n }\n }, [updatePromise]);\n\n useEffect(() => {\n // Prevent double execution (React 18+ can run effects twice in dev/certain conditions)\n if (hasRun.current) return;\n hasRun.current = true;\n\n scanStartTime.current = Date.now();\n\n if (isMonorepo) {\n runSickbayMonorepo({\n projectPath,\n checks,\n verbose,\n quotes,\n onPackageStart: (name) => setScanningPackage(name),\n onPackageComplete: () => setScanningPackage(undefined),\n })\n .then(async (r) => {\n setScanDuration(Date.now() - scanStartTime.current);\n setMonorepoReport(r);\n setProjectName(`monorepo (${r.packages.length} packages)`);\n\n // Cache dependency tree for web dashboard\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('../lib/history.js');\n const packages: Record<string, unknown> = {};\n for (const pkg of r.packages) {\n packages[pkg.name] = await getDependencyTree(pkg.path, r.packageManager);\n }\n saveDepTree(projectPath, { packages });\n } catch {\n /* dep tree is optional */\n }\n\n if (openWeb) {\n setPhase('opening-web');\n try {\n const { serveWeb } = await import('../commands/web.js');\n const { default: openBrowser } = await import('open');\n\n let aiService;\n if (enableAI && process.env.ANTHROPIC_API_KEY) {\n const { createAIService } = await import('../services/ai.js');\n aiService = createAIService(process.env.ANTHROPIC_API_KEY);\n }\n\n const url = await serveWeb(r, 3030, aiService);\n setWebUrl(url);\n await openBrowser(url);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n setPhase('error');\n setTimeout(() => exit(), 100);\n }\n } else {\n setPhase('results');\n setTimeout(() => exit(), 100);\n }\n })\n .catch((err) => {\n setError(err.message ?? String(err));\n setPhase('error');\n setTimeout(() => exit(err), 100);\n });\n return;\n }\n\n runSickbay({\n projectPath,\n checks,\n verbose,\n quotes,\n onRunnersReady: (names) => {\n setProgress(names.map((name) => ({ name, status: 'pending' as const })));\n },\n onCheckStart: (name) => {\n setProgress((prev) => prev.map((p) => (p.name === name ? { ...p, status: 'running' } : p)));\n },\n onCheckComplete: (result) => {\n if (result.status === 'skipped') {\n setProgress((prev) => prev.filter((p) => p.name !== result.id));\n } else {\n setProgress((prev) =>\n prev.map((p) => (p.name === result.id ? { ...p, status: 'done' } : p)),\n );\n }\n },\n })\n .then(async (r) => {\n setScanDuration(Date.now() - scanStartTime.current);\n setProjectName(r.projectInfo.name);\n setReport(r);\n\n // Auto-save to trend history and last-report snapshot\n try {\n const { saveEntry, saveLastReport } = await import('../lib/history.js');\n saveEntry(r);\n saveLastReport(r);\n } catch {\n // Non-critical — silently ignore history save failures\n }\n\n // Cache dependency tree for web dashboard\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('../lib/history.js');\n const tree = await getDependencyTree(projectPath, r.projectInfo.packageManager);\n saveDepTree(projectPath, tree);\n } catch {\n /* dep tree is optional, don't break the scan */\n }\n\n if (openWeb) {\n setPhase('opening-web');\n try {\n const { serveWeb } = await import('../commands/web.js');\n const { default: openBrowser } = await import('open');\n\n // Create AI service if enabled and API key exists\n let aiService;\n if (enableAI && process.env.ANTHROPIC_API_KEY) {\n const { createAIService } = await import('../services/ai.js');\n aiService = createAIService(process.env.ANTHROPIC_API_KEY);\n }\n\n const url = await serveWeb(r, 3030, aiService);\n setWebUrl(url);\n await openBrowser(url);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n setPhase('error');\n setTimeout(() => exit(), 100);\n return;\n }\n // Keep process alive — user closes with Ctrl+C\n } else {\n setPhase('results');\n setTimeout(() => exit(), 100);\n }\n })\n .catch((err) => {\n setError(err.message ?? String(err));\n setPhase('error');\n setTimeout(() => exit(err), 100);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header projectName={projectName} />\n\n {updateInfo && (\n <UpdateNotice\n currentVersion={updateInfo.currentVersion}\n latestVersion={updateInfo.latestVersion}\n />\n )}\n\n {phase === 'loading' && (\n <Box flexDirection=\"column\">\n {isMonorepo ? (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"magenta\">\n <Spinner type=\"dots\" />\n </Text>\n <Text dimColor> {LOADING_MESSAGES[loadingMsgIdx]}</Text>\n </Box>\n {scanningPackage && (\n <Box marginTop={1} marginLeft={2}>\n <Text dimColor>→ </Text>\n <Text color=\"cyan\">{scanningPackage}</Text>\n </Box>\n )}\n </Box>\n ) : (\n <Box flexDirection=\"column\">\n <Text dimColor>Running health checks...</Text>\n <Box marginTop={1} marginLeft={2}>\n <ProgressList items={progress} />\n </Box>\n </Box>\n )}\n </Box>\n )}\n\n {phase === 'error' && (\n <Box>\n <Text color=\"red\">✗ Error: {error}</Text>\n </Box>\n )}\n\n {phase === 'results' && monorepoReport && (\n <MonorepoSummaryTable report={monorepoReport} scanDuration={scanDuration} />\n )}\n\n {phase === 'results' && report && (\n <Box flexDirection=\"column\">\n {report.checks\n .filter((c) => c.status !== 'skipped')\n .map((check) => (\n <CheckResultRow key={check.id} result={check} />\n ))}\n <Summary report={report} scanDuration={scanDuration} />\n <QuickWins report={report} />\n <BestPractices report={report} />\n <Box marginTop={1}>\n <Text dimColor>View detailed report: </Text>\n <Text color=\"cyan\">sickbay --web</Text>\n </Box>\n </Box>\n )}\n\n {phase === 'opening-web' && (monorepoReport ?? report) && (\n <Box flexDirection=\"column\">\n {monorepoReport ? (\n <MonorepoSummaryTable report={monorepoReport} scanDuration={scanDuration} />\n ) : report ? (\n <>\n {report.checks\n .filter((c) => c.status !== 'skipped')\n .map((check) => (\n <CheckResultRow key={check.id} result={check} />\n ))}\n <Summary report={report} scanDuration={scanDuration} />\n </>\n ) : null}\n <Box marginTop={1}>\n {webUrl ? (\n <>\n <Text color=\"green\">✓ Dashboard running at </Text>\n <Text color=\"cyan\">{webUrl}</Text>\n <Text dimColor> (Ctrl+C to stop)</Text>\n </>\n ) : (\n <Text>\n <Text color=\"magenta\">\n <Spinner type=\"dots\" />\n </Text>{' '}\n <Gradient name=\"retro\">Launching dashboard with AI insights...</Gradient>\n </Text>\n )}\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction MonorepoSummaryTable({\n report,\n scanDuration,\n}: {\n report: MonorepoReport;\n scanDuration: number | null;\n}) {\n const scoreColor = (score: number) => (score >= 80 ? 'green' : score >= 60 ? 'yellow' : 'red');\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold>Monorepo · </Text>\n <Text dimColor>{report.monorepoType} workspaces · </Text>\n <Text>{report.packages.length} packages</Text>\n </Box>\n {report.packages.map((pkg: PackageReport) => (\n <Box key={pkg.path} marginLeft={2} gap={1}>\n <Text color={scoreColor(pkg.score)}>{scoreBar(pkg.score)}</Text>\n <Text bold color={scoreColor(pkg.score)}>\n {String(pkg.score).padStart(3)}\n </Text>\n <Text>{pkg.name}</Text>\n <Text dimColor>{pkg.framework}</Text>\n {pkg.summary.critical > 0 && <Text color=\"red\"> {pkg.summary.critical} critical</Text>}\n </Box>\n ))}\n <Box marginTop={1} gap={2}>\n <Text bold>Overall: </Text>\n <Text color={scoreColor(report.overallScore)} bold>\n {report.overallScore}\n </Text>\n <Text dimColor>· </Text>\n {(() => {\n const u = countUniqueIssues(report.packages.flatMap((p) => p.checks));\n return (\n <>\n <Text color=\"red\">\n {u.critical} critical\n {u.totalCritical > u.critical ? ` (${u.totalCritical} total)` : ''}\n </Text>\n <Text dimColor>· </Text>\n <Text color=\"yellow\">\n {u.warnings} warnings\n {u.totalWarnings > u.warnings ? ` (${u.totalWarnings} total)` : ''}\n </Text>\n </>\n );\n })()}\n {scanDuration !== null && (\n <>\n <Text dimColor>· </Text>\n <Text dimColor>{formatDuration(scanDuration)}</Text>\n </>\n )}\n </Box>\n {report.quote && (\n <Box marginTop={1}>\n <Text italic dimColor>\n \"{report.quote.text}\"\n </Text>\n <Text dimColor> — {report.quote.source}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>Per-package details: </Text>\n <Text color=\"cyan\">sickbay --web</Text>\n </Box>\n </Box>\n );\n}\n","#!/usr/bin/env node\nimport { existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nimport React from 'react';\n\nimport { Command } from 'commander';\nimport { config } from 'dotenv';\nimport { render } from 'ink';\n\nimport { App } from './components/App.js';\n\ndeclare const __VERSION__: string;\n\n/**\n * Entry point for the Sickbay CLI application.\n * This script sets up the command-line interface using Commander, loads environment variables, and renders the appropriate Ink components based on user commands.\n * It supports multiple commands including the default scan, trend analysis, stats overview, and a doctor command for diagnosing project issues.\n * Each command can output results in JSON format or render an interactive UI in the terminal.\n */\n\n// Load .env from global config first (~/.sickbay/.env)\nconst globalConfigPath = join(homedir(), '.sickbay', '.env');\nif (existsSync(globalConfigPath)) {\n config({ path: globalConfigPath, debug: false, quiet: true });\n}\n\n// Load .env from current directory (overrides global)\nconfig({ debug: false, quiet: true });\n\nconst program = new Command();\n\nprogram\n .name('sickbay')\n .description('React project health check CLI')\n .version(__VERSION__, '-v, --version')\n .enablePositionalOptions()\n .passThroughOptions()\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--package <name>', 'scope to a single named package (monorepo only)')\n .option('--json', 'output raw JSON report')\n .option('--web', 'open web dashboard after scan')\n .option('--no-ai', 'disable AI features')\n .option('--no-quotes', 'suppress personality quotes in output')\n .option('--verbose', 'show verbose output')\n .action(async (options) => {\n // Validate --path exists before doing any I/O\n if (!existsSync(options.path)) {\n process.stderr.write(`Error: path does not exist: ${options.path}\\n`);\n process.exit(1);\n }\n\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n // Non-blocking update check\n const updatePromise = (async () => {\n try {\n const { checkForUpdate } = await import('./lib/update-check.js');\n return await checkForUpdate(__VERSION__);\n } catch {\n return null;\n }\n })();\n\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const { detectMonorepo, runSickbay, runSickbayMonorepo, getAvailableChecks } =\n await import('sickbay-core');\n\n // Warn early if any --checks IDs don't match known check names\n if (checks && checks.length > 0) {\n const knownNames = new Set(getAvailableChecks().map((c) => c.name));\n const unknown = checks.filter((c: string) => !knownNames.has(c));\n if (unknown.length > 0) {\n process.stderr.write(`Warning: unknown check ID(s): ${unknown.join(', ')}\\n`);\n }\n }\n\n const monorepoInfo = await detectMonorepo(options.path);\n\n // --package flag: scope to a single named package within a monorepo\n if (options.package && monorepoInfo.isMonorepo) {\n const { readFileSync } = await import('fs');\n const targetPath = monorepoInfo.packagePaths.find((p) => {\n try {\n const pkg = JSON.parse(readFileSync(join(p, 'package.json'), 'utf-8'));\n return pkg.name === options.package || pkg.name?.endsWith(`/${options.package}`);\n } catch {\n return false;\n }\n });\n\n if (!targetPath) {\n process.stderr.write(`Package \"${options.package}\" not found in monorepo\\n`);\n process.exit(1);\n }\n\n if (options.json) {\n const report = await runSickbay({\n projectPath: targetPath,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n render(\n React.createElement(App, {\n projectPath: targetPath,\n checks,\n openWeb: options.web,\n enableAI: options.ai !== false,\n verbose: options.verbose,\n quotes: options.quotes,\n updatePromise,\n }),\n );\n return;\n }\n\n if (options.json) {\n if (monorepoInfo.isMonorepo) {\n const report = await runSickbayMonorepo({\n projectPath: options.path,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n const report = await runSickbay({\n projectPath: options.path,\n checks,\n verbose: options.verbose,\n quotes: options.quotes,\n });\n\n // Auto-save to trend history and last-report snapshot\n try {\n const { saveEntry, saveLastReport } = await import('./lib/history.js');\n saveEntry(report);\n saveLastReport(report);\n } catch {\n // Non-critical\n }\n\n // Cache dependency tree\n try {\n const { getDependencyTree } = await import('sickbay-core');\n const { saveDepTree } = await import('./lib/history.js');\n const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);\n saveDepTree(options.path, tree);\n } catch {\n /* dep tree is optional */\n }\n\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n process.exit(0);\n }\n\n render(\n React.createElement(App, {\n projectPath: options.path,\n checks,\n openWeb: options.web,\n enableAI: options.ai !== false,\n verbose: options.verbose,\n quotes: options.quotes,\n isMonorepo: monorepoInfo.isMonorepo,\n updatePromise,\n }),\n );\n });\n\n// --- sickbay init ---\nprogram\n .command('init')\n .description('Initialize .sickbay/ folder and run an initial baseline scan')\n .option('-p, --path <path>', 'project path to initialize', process.cwd())\n .option(\n '--sync',\n 'add newly available checks to existing config without touching existing entries',\n )\n .option('--reset-config', 'regenerate config from scratch (overwrites existing)')\n .action(async (options) => {\n if (options.resetConfig) {\n const { generateConfigFile } = await import('./commands/init.js');\n await generateConfigFile(options.path, { force: true });\n return;\n }\n if (options.sync) {\n const { syncConfigFile } = await import('./commands/init.js');\n await syncConfigFile(options.path);\n return;\n }\n const { initSickbay } = await import('./commands/init.js');\n await initSickbay(options.path);\n });\n\n// --- sickbay fix ---\nprogram\n .command('fix')\n .description('Interactively fix issues found by sickbay scan')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--all', 'apply all available fixes without prompting')\n .option('--dry-run', 'show what would be fixed without executing')\n .option(\n '--skip-git-check',\n 'skip the uncommitted-changes warning before applying source-modifying fixes',\n )\n .option('--verbose', 'show verbose output')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const { FixApp } = await import('./components/FixApp.js');\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n render(\n React.createElement(FixApp, {\n projectPath,\n checks,\n applyAll: options.all ?? false,\n dryRun: options.dryRun ?? false,\n skipGitCheck: options.skipGitCheck ?? false,\n verbose: options.verbose ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay trend ---\nprogram\n .command('trend')\n .description('Show score history and trends over time')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-n, --last <count>', 'number of recent scans to show', '20')\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--json', 'output trend data as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { TrendApp } = await import('./components/TrendApp.js');\n render(\n React.createElement(TrendApp, {\n projectPath,\n last: parseInt(options.last, 10),\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay stats ---\nprogram\n .command('stats')\n .description('Show a quick codebase overview and project summary')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--json', 'output stats as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { StatsApp } = await import('./components/StatsApp.js');\n render(\n React.createElement(StatsApp, {\n projectPath,\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay tui ---\nprogram\n .command('tui')\n .description('Launch the persistent developer dashboard')\n .option('-p, --path <path>', 'project path to monitor', process.cwd())\n .option('--no-watch', 'disable file-watching auto-refresh')\n .option('--no-quotes', 'suppress personality quotes in output')\n .option('--refresh <seconds>', 'auto-refresh interval in seconds', '300')\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .action(async (options) => {\n const { TuiApp } = await import('./components/tui/TuiApp.js');\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n render(\n React.createElement(TuiApp, {\n projectPath: options.path,\n checks,\n watchEnabled: options.watch !== false,\n refreshInterval: parseInt(options.refresh, 10),\n quotes: options.quotes,\n }),\n { exitOnCtrlC: true },\n );\n });\n\n// --- sickbay doctor ---\nprogram\n .command('doctor')\n .description('Diagnose project setup and configuration issues')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--fix', 'auto-scaffold missing configuration files')\n .option('--json', 'output diagnostic results as JSON')\n .action(async (options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { DoctorApp } = await import('./components/DoctorApp.js');\n render(\n React.createElement(DoctorApp, {\n projectPath,\n autoFix: options.fix ?? false,\n jsonOutput: options.json ?? false,\n isMonorepo: resolution.isMonorepo && !resolution.targetPath,\n packagePaths: resolution.isMonorepo ? resolution.packagePaths : undefined,\n packageNames: resolution.isMonorepo ? resolution.packageNames : undefined,\n }),\n );\n });\n\n// --- sickbay badge ---\nprogram\n .command('badge')\n .description('Generate a health score badge for your README')\n .option('-p, --path <path>', 'project path', process.cwd())\n .option('--package <name>', 'scope to a single package (monorepo only)')\n .option('--html', 'output HTML <img> tag instead of markdown')\n .option('--url', 'output bare badge URL only')\n .option('--label <text>', 'custom badge label', 'sickbay')\n .option('--scan', 'run a fresh scan instead of using last report')\n .action(async (options) => {\n const { resolveProject } = await import('./lib/resolve-package.js');\n const resolution = await resolveProject(options.path, options.package);\n\n const projectPath = resolution.isMonorepo\n ? (resolution.targetPath ?? options.path)\n : resolution.targetPath;\n\n const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } =\n await import('./commands/badge.js');\n\n let score = options.scan ? null : loadScoreFromLastReport(projectPath);\n\n if (score === null) {\n const { runSickbay } = await import('sickbay-core');\n const report = await runSickbay({ projectPath, quotes: false });\n\n try {\n const { saveEntry, saveLastReport } = await import('./lib/history.js');\n saveEntry(report);\n saveLastReport(report);\n } catch {\n // Non-critical\n }\n\n score = report.overallScore;\n }\n\n let output: string;\n if (options.url) {\n output = badgeUrl(score, options.label);\n } else if (options.html) {\n output = badgeHtml(score, options.label);\n } else {\n output = badgeMarkdown(score, options.label);\n }\n\n process.stdout.write(output + '\\n');\n process.exit(0);\n });\n\n// --- sickbay claude ---\nprogram\n .command('claude')\n .description('Generate a Claude Code skill file for your project')\n .option('-p, --path <path>', 'project path', process.cwd())\n .action(async (options) => {\n const { generateClaudeSkill } = await import('./commands/claude.js');\n generateClaudeSkill(options.path);\n });\n\n// --- sickbay diff ---\nprogram\n .command('diff <branch>')\n .description('Compare health score against another branch')\n .option('-p, --path <path>', 'project path to analyze', process.cwd())\n .option('-c, --checks <checks>', 'comma-separated list of checks to run')\n .option('--json', 'output diff as JSON')\n .option('--verbose', 'show verbose output')\n .action(async (branch, options) => {\n // Load .env from project path if it differs from cwd\n if (options.path && options.path !== process.cwd()) {\n const projectEnvPath = join(options.path, '.env');\n if (existsSync(projectEnvPath)) {\n config({ path: projectEnvPath, override: true });\n }\n }\n\n const checks = options.checks\n ? options.checks.split(',').map((s: string) => s.trim())\n : undefined;\n\n const { DiffApp } = await import('./components/DiffApp.js');\n render(\n React.createElement(DiffApp, {\n projectPath: options.path,\n branch,\n jsonOutput: options.json ?? false,\n checks,\n verbose: options.verbose,\n }),\n );\n });\n\nprogram.parse();\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { c as getAvailableChecks, d as runSickbayMonorepo, i as detectMonorepo, r as detectContext, u as runSickbay } from "./dist-Bjhxbcak.js";
2
- import { i as saveEntry } from "./history-DVegAwFp.js";
2
+ import { i as saveEntry } from "./history-C9hu3f6s.js";
3
3
  import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
4
4
  import { join } from "path";
5
5
  //#region src/commands/init.ts
@@ -196,4 +196,4 @@ async function initSickbay(projectPath) {
196
196
  //#endregion
197
197
  export { generateConfigFile, initSickbay, syncConfigFile };
198
198
 
199
- //# sourceMappingURL=init-Dn7eDMEp.js.map
199
+ //# sourceMappingURL=init-Czn8P7An.js.map