sickbay 1.15.6 → 1.15.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{DiffApp-UCBWNYDV.js → DiffApp-OVPXXDEK.js} +1 -1
  2. package/dist/{DoctorApp-SUPQ73LO.js → DoctorApp-RMHCSF6H.js} +1 -1
  3. package/dist/{FixApp-DUD426JB.js → FixApp-GTFLJHMI.js} +1 -1
  4. package/dist/{StatsApp-X2Y7LMG5.js → StatsApp-GZITWMQU.js} +1 -1
  5. package/dist/{TrendApp-CYONZAVG.js → TrendApp-BB3KOCYK.js} +1 -1
  6. package/dist/{TuiApp-NQGIS2T6.js → TuiApp-CZY5TGWC.js} +2 -2
  7. package/dist/{chunk-UFTUJIJ2.js → chunk-PJI22Z5Y.js} +1 -1
  8. package/dist/config.d.ts +1 -1
  9. package/dist/index.js +11 -11
  10. package/dist/web/assets/{ChatDrawer-Dqewz3Yz.js → ChatDrawer-dCdqFiGs.js} +2 -2
  11. package/dist/web/assets/ChatDrawer-dCdqFiGs.js.map +1 -0
  12. package/dist/web/assets/{DependencyGraph-DS5sXNvY.js → DependencyGraph-BSJPytrP.js} +2 -2
  13. package/dist/web/assets/{DependencyGraph-DS5sXNvY.js.map → DependencyGraph-BSJPytrP.js.map} +1 -1
  14. package/dist/web/assets/{MonorepoOverview-vTq9TL11.js → MonorepoOverview-DDbHHZi0.js} +2 -2
  15. package/dist/web/assets/MonorepoOverview-DDbHHZi0.js.map +1 -0
  16. package/dist/web/assets/constants-DYzuOu1F.js +2 -0
  17. package/dist/web/assets/constants-DYzuOu1F.js.map +1 -0
  18. package/dist/web/assets/graph-viz-7--E40m7.js +2 -0
  19. package/dist/web/assets/{graph-viz-Ls9Hbzox.js.map → graph-viz-7--E40m7.js.map} +1 -1
  20. package/dist/web/assets/{index-B_XNCPiK.js → index-BgK5odk3.js} +12 -12
  21. package/dist/web/assets/index-BgK5odk3.js.map +1 -0
  22. package/dist/web/assets/{markdown-BkROfETq.js → markdown-oPAUxr3B.js} +8 -8
  23. package/dist/web/assets/{markdown-BkROfETq.js.map → markdown-oPAUxr3B.js.map} +1 -1
  24. package/dist/web/assets/react-DeNSbYyc.js +16 -0
  25. package/dist/web/assets/{react-BEi4PGB1.js.map → react-DeNSbYyc.js.map} +1 -1
  26. package/dist/web/index.html +4 -3
  27. package/dist/{web-TCEOS752.js → web-4P4CCEHQ.js} +30 -10
  28. package/package.json +5 -5
  29. package/dist/web/assets/ChatDrawer-Dqewz3Yz.js.map +0 -1
  30. package/dist/web/assets/MonorepoOverview-vTq9TL11.js.map +0 -1
  31. package/dist/web/assets/graph-viz-Ls9Hbzox.js +0 -2
  32. package/dist/web/assets/index-B_XNCPiK.js.map +0 -1
  33. package/dist/web/assets/react-BEi4PGB1.js +0 -16
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Header
3
- } from "./chunk-UFTUJIJ2.js";
3
+ } from "./chunk-PJI22Z5Y.js";
4
4
 
5
5
  // src/components/DiffApp.tsx
6
6
  import React, { useState, useEffect } from "react";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-L7KHKFWR.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-UFTUJIJ2.js";
6
+ } from "./chunk-PJI22Z5Y.js";
7
7
  import {
8
8
  detectPackageManager,
9
9
  detectProject
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-MBVA75EM.js";
7
7
  import {
8
8
  Header
9
- } from "./chunk-UFTUJIJ2.js";
9
+ } from "./chunk-PJI22Z5Y.js";
10
10
  import {
11
11
  runSickbay
12
12
  } from "./chunk-XSQZTZWJ.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-L7KHKFWR.js";
4
4
  import {
5
5
  Header
6
- } from "./chunk-UFTUJIJ2.js";
6
+ } from "./chunk-PJI22Z5Y.js";
7
7
  import {
8
8
  detectProject
9
9
  } from "./chunk-XSQZTZWJ.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-L7KHKFWR.js";
8
8
  import {
9
9
  Header
10
- } from "./chunk-UFTUJIJ2.js";
10
+ } from "./chunk-PJI22Z5Y.js";
11
11
  import "./chunk-XSQZTZWJ.js";
12
12
  import {
13
13
  detectRegressions,
@@ -689,7 +689,7 @@ function TuiApp({
689
689
  return () => timers.forEach(clearTimeout);
690
690
  }, []);
691
691
  useEffect7(() => {
692
- checkForUpdate("1.15.5").then((info) => {
692
+ checkForUpdate("1.15.6").then((info) => {
693
693
  if (info) setUpdateInfo(info);
694
694
  });
695
695
  }, []);
@@ -819,7 +819,7 @@ function TuiApp({
819
819
  const webReport = monorepoReportRef.current ?? reportRef.current;
820
820
  if (!webReport) return;
821
821
  try {
822
- const { serveWeb } = await import("./web-TCEOS752.js");
822
+ const { serveWeb } = await import("./web-4P4CCEHQ.js");
823
823
  const { default: openBrowser } = await import("open");
824
824
  let aiService;
825
825
  if (withAI && process.env.ANTHROPIC_API_KEY && !monorepoReportRef.current) {
@@ -11,7 +11,7 @@ var ASCII_ART = `
11
11
  A vitals health check for your app
12
12
  `.trim();
13
13
  function Header({ projectName }) {
14
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.15.5")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, projectName)));
14
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.15.6")), projectName && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " Analyzing "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, projectName)));
15
15
  }
16
16
 
17
17
  export {
package/dist/config.d.ts CHANGED
@@ -1 +1 @@
1
- export { Category, CheckConfig, SickbayConfig, SuppressionRule, defineConfig } from '@nebulord/sickbay-core';
1
+ export { Category, CheckConfig, SickbayConfig, SuppressionRule, defineConfig } from 'sickbay-core';
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-TYG7ZQBP.js";
9
9
  import {
10
10
  Header
11
- } from "./chunk-UFTUJIJ2.js";
11
+ } from "./chunk-PJI22Z5Y.js";
12
12
  import {
13
13
  getScoreEmoji,
14
14
  runSickbay,
@@ -202,7 +202,7 @@ function App({
202
202
  if (openWeb) {
203
203
  setPhase("opening-web");
204
204
  try {
205
- const { serveWeb } = await import("./web-TCEOS752.js");
205
+ const { serveWeb } = await import("./web-4P4CCEHQ.js");
206
206
  const { default: openBrowser } = await import("open");
207
207
  let aiService;
208
208
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -268,7 +268,7 @@ function App({
268
268
  if (openWeb) {
269
269
  setPhase("opening-web");
270
270
  try {
271
- const { serveWeb } = await import("./web-TCEOS752.js");
271
+ const { serveWeb } = await import("./web-4P4CCEHQ.js");
272
272
  const { default: openBrowser } = await import("open");
273
273
  let aiService;
274
274
  if (enableAI && process.env.ANTHROPIC_API_KEY) {
@@ -317,7 +317,7 @@ if (existsSync(globalConfigPath)) {
317
317
  }
318
318
  config({ debug: false, quiet: true });
319
319
  var program = new Command();
320
- program.name("sickbay").description("React project health check CLI").version("1.15.5", "-v, --version").enablePositionalOptions().passThroughOptions().option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single named package (monorepo only)").option("--json", "output raw JSON report").option("--web", "open web dashboard after scan").option("--no-ai", "disable AI features").option("--no-quotes", "suppress personality quotes in output").option("--verbose", "show verbose output").action(async (options) => {
320
+ program.name("sickbay").description("React project health check CLI").version("1.15.6", "-v, --version").enablePositionalOptions().passThroughOptions().option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single named package (monorepo only)").option("--json", "output raw JSON report").option("--web", "open web dashboard after scan").option("--no-ai", "disable AI features").option("--no-quotes", "suppress personality quotes in output").option("--verbose", "show verbose output").action(async (options) => {
321
321
  if (options.path && options.path !== process.cwd()) {
322
322
  const projectEnvPath = join(options.path, ".env");
323
323
  if (existsSync(projectEnvPath)) {
@@ -327,7 +327,7 @@ program.name("sickbay").description("React project health check CLI").version("1
327
327
  const updatePromise = (async () => {
328
328
  try {
329
329
  const { checkForUpdate } = await import("./update-check-M7IFOMLJ.js");
330
- return await checkForUpdate("1.15.5");
330
+ return await checkForUpdate("1.15.6");
331
331
  } catch {
332
332
  return null;
333
333
  }
@@ -445,7 +445,7 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
445
445
  }
446
446
  const { resolveProject } = await import("./resolve-package-4UT4RYHY.js");
447
447
  const resolution = await resolveProject(options.path, options.package);
448
- const { FixApp } = await import("./FixApp-DUD426JB.js");
448
+ const { FixApp } = await import("./FixApp-GTFLJHMI.js");
449
449
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
450
450
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
451
451
  render(
@@ -471,7 +471,7 @@ program.command("trend").description("Show score history and trends over time").
471
471
  const { resolveProject } = await import("./resolve-package-4UT4RYHY.js");
472
472
  const resolution = await resolveProject(options.path, options.package);
473
473
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
474
- const { TrendApp } = await import("./TrendApp-CYONZAVG.js");
474
+ const { TrendApp } = await import("./TrendApp-BB3KOCYK.js");
475
475
  render(
476
476
  React7.createElement(TrendApp, {
477
477
  projectPath,
@@ -493,7 +493,7 @@ program.command("stats").description("Show a quick codebase overview and project
493
493
  const { resolveProject } = await import("./resolve-package-4UT4RYHY.js");
494
494
  const resolution = await resolveProject(options.path, options.package);
495
495
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
496
- const { StatsApp } = await import("./StatsApp-X2Y7LMG5.js");
496
+ const { StatsApp } = await import("./StatsApp-GZITWMQU.js");
497
497
  render(
498
498
  React7.createElement(StatsApp, {
499
499
  projectPath,
@@ -505,7 +505,7 @@ program.command("stats").description("Show a quick codebase overview and project
505
505
  );
506
506
  });
507
507
  program.command("tui").description("Launch the persistent developer dashboard").option("-p, --path <path>", "project path to monitor", process.cwd()).option("--no-watch", "disable file-watching auto-refresh").option("--no-quotes", "suppress personality quotes in output").option("--refresh <seconds>", "auto-refresh interval in seconds", "300").option("-c, --checks <checks>", "comma-separated list of checks to run").action(async (options) => {
508
- const { TuiApp } = await import("./TuiApp-NQGIS2T6.js");
508
+ const { TuiApp } = await import("./TuiApp-CZY5TGWC.js");
509
509
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
510
510
  render(
511
511
  React7.createElement(TuiApp, {
@@ -528,7 +528,7 @@ program.command("doctor").description("Diagnose project setup and configuration
528
528
  const { resolveProject } = await import("./resolve-package-4UT4RYHY.js");
529
529
  const resolution = await resolveProject(options.path, options.package);
530
530
  const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
531
- const { DoctorApp } = await import("./DoctorApp-SUPQ73LO.js");
531
+ const { DoctorApp } = await import("./DoctorApp-RMHCSF6H.js");
532
532
  render(
533
533
  React7.createElement(DoctorApp, {
534
534
  projectPath,
@@ -580,7 +580,7 @@ program.command("diff <branch>").description("Compare health score against anoth
580
580
  }
581
581
  }
582
582
  const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
583
- const { DiffApp } = await import("./DiffApp-UCBWNYDV.js");
583
+ const { DiffApp } = await import("./DiffApp-OVPXXDEK.js");
584
584
  render(
585
585
  React7.createElement(DiffApp, {
586
586
  projectPath: options.path,
@@ -1,2 +1,2 @@
1
- import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{a as t,i as n,n as r,r as i,t as a}from"./markdown-BkROfETq.js";import{i as o}from"./react-BEi4PGB1.js";var s=o(),c=e(t(),1),l=n();function u(e){let t=(0,s.c)(3),{content:n}=e,o;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(o={code(e){let{className:t,children:n,...i}=e,o=/language-(\w+)/.exec(t||``);return o?(0,l.jsx)(r,{style:a,language:o[1],PreTag:`div`,className:`rounded-md bg-black/30! mt-2! mb-2!`,customStyle:{margin:0,padding:`0.75rem`},...i,children:String(n).replace(/\n$/,``)}):(0,l.jsx)(`code`,{className:`bg-black/30 px-1.5 py-0.5 rounded-sm text-accent font-mono text-xs`,...i,children:n})},p(e){let{children:t}=e;return(0,l.jsx)(`p`,{className:`mb-2 last:mb-0`,children:t})},ul(e){let{children:t}=e;return(0,l.jsx)(`ul`,{className:`list-disc list-inside mb-2 space-y-1`,children:t})},ol(e){let{children:t}=e;return(0,l.jsx)(`ol`,{className:`list-decimal list-inside mb-2 space-y-1`,children:t})},li(e){let{children:t}=e;return(0,l.jsx)(`li`,{className:`text-sm`,children:t})},strong(e){let{children:t}=e;return(0,l.jsx)(`strong`,{className:`font-semibold text-white`,children:t})},em(e){let{children:t}=e;return(0,l.jsx)(`em`,{className:`italic text-gray-200`,children:t})},a(e){let{href:t,children:n}=e;return(0,l.jsx)(`a`,{href:t,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent hover:underline`,children:n})}},t[0]=o):o=t[0];let c;return t[1]===n?c=t[2]:(c=(0,l.jsx)(`div`,{className:`prose prose-invert prose-sm max-w-none`,children:(0,l.jsx)(i,{components:o,children:n})}),t[1]=n,t[2]=c),c}function d({report:e,packageName:t}){let[n,r]=(0,c.useState)(!1),[i,a]=(0,c.useState)(null),[o,s]=(0,c.useState)([]),[d,f]=(0,c.useState)(``),[p,m]=(0,c.useState)(!1),h=(0,c.useRef)(null);(0,c.useEffect)(()=>{fetch(`/ai/summary`,{method:`HEAD`}).then(e=>a(e.ok)).catch(()=>a(!1))},[]),(0,c.useEffect)(()=>{s([]),r(!1)},[t]),(0,c.useEffect)(()=>{h.current?.scrollIntoView({behavior:`smooth`})},[o]);let g=async()=>{if(!d.trim()||p)return;let e={role:`user`,content:d};s(t=>[...t,e]),f(``),m(!0);try{let e=t?`/ai/chat?package=${encodeURIComponent(t)}`:`/ai/chat`,n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({message:d,history:o})});if(n.ok){let e={role:`assistant`,content:(await n.json()).response};s(t=>[...t,e])}else{let e={role:`assistant`,content:`Sorry, I encountered an error. Please try again.`};s(t=>[...t,e])}}catch{let e={role:`assistant`,content:`Sorry, I encountered an error. Please try again.`};s(t=>[...t,e])}finally{m(!1)}};return i===!1?null:(0,l.jsxs)(l.Fragment,{children:[!n&&(0,l.jsx)(`button`,{onClick:()=>r(!0),className:`fixed bottom-6 right-6 w-14 h-14 bg-accent text-black rounded-sm shadow-lg hover:shadow-xl transition-all hover:scale-110 flex items-center justify-center text-2xl z-50`,title:`AI Assistant`,children:`VAI`}),n&&(0,l.jsxs)(`div`,{className:`fixed bottom-6 right-6 w-140 h-200 bg-surface border border-border rounded-lg shadow-2xl flex flex-col z-50`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-lg`,children:(0,l.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`32`,height:`32`,viewBox:`0 0 24 24`,children:(0,l.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,d:`M9.6 6.112c.322-.816 1.478-.816 1.8 0l.91 2.31a5.8 5.8 0 0 0 3.268 3.268l2.31.91c.816.322.816 1.478 0 1.8l-2.31.91a5.8 5.8 0 0 0-3.268 3.268l-.91 2.31c-.322.816-1.478.816-1.8 0l-.91-2.31a5.8 5.8 0 0 0-3.268-3.268l-2.31-.91c-.816-.322-.816-1.478 0-1.8l2.31-.91A5.8 5.8 0 0 0 8.69 8.422zm8.563-3.382a.363.363 0 0 1 .674 0l.342.866c.221.56.665 1.004 1.225 1.225l.866.342a.363.363 0 0 1 0 .674l-.866.342a2.18 2.18 0 0 0-1.225 1.225l-.342.866a.363.363 0 0 1-.674 0l-.342-.866a2.18 2.18 0 0 0-1.225-1.225l-.867-.342a.363.363 0 0 1 0-.674l.867-.342a2.18 2.18 0 0 0 1.225-1.225z`})})}),(0,l.jsx)(`span`,{className:`font-semibold text-sm`,children:`AI Assistant`})]}),(0,l.jsx)(`button`,{onClick:()=>r(!1),className:`text-gray-500 hover:text-white transition-colors text-lg`,children:`✕`})]}),(0,l.jsxs)(`div`,{className:`flex-1 overflow-y-auto p-4 space-y-3`,children:[o.length===0&&(0,l.jsxs)(`div`,{className:`text-sm text-gray-500 text-center py-8`,children:[`Ask me anything about your project health!`,(0,l.jsx)(`div`,{className:`mt-2 text-xs text-gray-600`,children:`Try: "What should I fix first?" or "Explain the security issues"`})]}),o.map((e,t)=>(0,l.jsx)(`div`,{className:`flex ${e.role===`user`?`justify-end`:`justify-start`}`,children:(0,l.jsx)(`div`,{className:`max-w-[80%] px-3 py-2 rounded-lg text-sm ${e.role===`user`?`bg-accent text-black font-medium`:`bg-card text-gray-300`}`,children:e.role===`assistant`?(0,l.jsx)(u,{content:e.content}):e.content})},`${e.role}-${t}`)),p&&(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(`div`,{className:`bg-card text-gray-500 px-3 py-2 rounded-lg text-sm`,children:(0,l.jsx)(`span`,{className:`animate-pulse`,children:`⠋ thinking...`})})}),(0,l.jsx)(`div`,{ref:h})]}),(0,l.jsx)(`div`,{className:`px-4 py-3 border-t border-border`,children:(0,l.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),g()},className:`flex gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:d,onChange:e=>f(e.target.value),placeholder:`Ask about your project...`,disabled:p,className:`flex-1 bg-card border border-border rounded-sm px-3 py-2 text-sm focus:outline-hidden focus:border-accent disabled:opacity-50`}),(0,l.jsx)(`button`,{type:`submit`,disabled:p||!d.trim(),className:`px-4 py-2 bg-accent text-black rounded-sm text-sm font-semibold hover:bg-accent/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:`Send`})]})})]})]})}export{d as ChatDrawer};
2
- //# sourceMappingURL=ChatDrawer-Dqewz3Yz.js.map
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{a as t,i as n,n as r,r as i,t as a}from"./markdown-oPAUxr3B.js";import{i as o}from"./react-DeNSbYyc.js";var s=o(),c=e(t(),1),l=n();function u(e){let t=(0,s.c)(3),{content:n}=e,o;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(o={code(e){let{className:t,children:n,...i}=e,o=/language-(\w+)/.exec(t||``);return o?(0,l.jsx)(r,{style:a,language:o[1],PreTag:`div`,className:`rounded-md bg-black/30! mt-2! mb-2!`,customStyle:{margin:0,padding:`0.75rem`},...i,children:String(n).replace(/\n$/,``)}):(0,l.jsx)(`code`,{className:`bg-black/30 px-1.5 py-0.5 rounded-sm text-accent font-mono text-xs`,...i,children:n})},p(e){let{children:t}=e;return(0,l.jsx)(`p`,{className:`mb-2 last:mb-0`,children:t})},ul(e){let{children:t}=e;return(0,l.jsx)(`ul`,{className:`list-disc list-inside mb-2 space-y-1`,children:t})},ol(e){let{children:t}=e;return(0,l.jsx)(`ol`,{className:`list-decimal list-inside mb-2 space-y-1`,children:t})},li(e){let{children:t}=e;return(0,l.jsx)(`li`,{className:`text-sm`,children:t})},strong(e){let{children:t}=e;return(0,l.jsx)(`strong`,{className:`font-semibold text-white`,children:t})},em(e){let{children:t}=e;return(0,l.jsx)(`em`,{className:`italic text-gray-200`,children:t})},a(e){let{href:t,children:n}=e;return(0,l.jsx)(`a`,{href:t,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent hover:underline`,children:n})}},t[0]=o):o=t[0];let c;return t[1]===n?c=t[2]:(c=(0,l.jsx)(`div`,{className:`prose prose-invert prose-sm max-w-none`,children:(0,l.jsx)(i,{components:o,children:n})}),t[1]=n,t[2]=c),c}function d({report:e,packageName:t}){let[n,r]=(0,c.useState)(!1),[i,a]=(0,c.useState)(null),[o,s]=(0,c.useState)([]),[d,f]=(0,c.useState)(``),[p,m]=(0,c.useState)(!1),h=(0,c.useRef)(null);(0,c.useEffect)(()=>{fetch(`/ai/summary`,{method:`HEAD`}).then(e=>a(e.ok)).catch(()=>a(!1))},[]),(0,c.useEffect)(()=>{s([]),r(!1)},[t]),(0,c.useEffect)(()=>{h.current?.scrollIntoView({behavior:`smooth`})},[o]);let g=async()=>{if(!d.trim()||p)return;let e={role:`user`,content:d};s(t=>[...t,e]),f(``),m(!0);try{let e=t?`/ai/chat?package=${encodeURIComponent(t)}`:`/ai/chat`,n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({message:d,history:o})});if(n.ok){let e={role:`assistant`,content:(await n.json()).response};s(t=>[...t,e])}else{let e={role:`assistant`,content:`Sorry, I encountered an error. Please try again.`};s(t=>[...t,e])}}catch{let e={role:`assistant`,content:`Sorry, I encountered an error. Please try again.`};s(t=>[...t,e])}finally{m(!1)}};return i===!1?null:(0,l.jsxs)(l.Fragment,{children:[!n&&(0,l.jsx)(`button`,{onClick:()=>r(!0),className:`fixed bottom-6 right-6 w-14 h-14 bg-accent text-black rounded-sm shadow-lg hover:shadow-xl transition-all hover:scale-110 flex items-center justify-center text-2xl z-50`,title:`AI Assistant`,children:`VAI`}),n&&(0,l.jsxs)(`div`,{className:`fixed bottom-6 right-6 w-140 h-200 bg-surface border border-border rounded-lg shadow-2xl flex flex-col z-50`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-lg`,children:(0,l.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`32`,height:`32`,viewBox:`0 0 24 24`,children:(0,l.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,d:`M9.6 6.112c.322-.816 1.478-.816 1.8 0l.91 2.31a5.8 5.8 0 0 0 3.268 3.268l2.31.91c.816.322.816 1.478 0 1.8l-2.31.91a5.8 5.8 0 0 0-3.268 3.268l-.91 2.31c-.322.816-1.478.816-1.8 0l-.91-2.31a5.8 5.8 0 0 0-3.268-3.268l-2.31-.91c-.816-.322-.816-1.478 0-1.8l2.31-.91A5.8 5.8 0 0 0 8.69 8.422zm8.563-3.382a.363.363 0 0 1 .674 0l.342.866c.221.56.665 1.004 1.225 1.225l.866.342a.363.363 0 0 1 0 .674l-.866.342a2.18 2.18 0 0 0-1.225 1.225l-.342.866a.363.363 0 0 1-.674 0l-.342-.866a2.18 2.18 0 0 0-1.225-1.225l-.867-.342a.363.363 0 0 1 0-.674l.867-.342a2.18 2.18 0 0 0 1.225-1.225z`})})}),(0,l.jsx)(`span`,{className:`font-semibold text-sm`,children:`AI Assistant`})]}),(0,l.jsx)(`button`,{onClick:()=>r(!1),className:`text-gray-500 hover:text-white transition-colors text-lg`,children:`✕`})]}),(0,l.jsxs)(`div`,{className:`flex-1 overflow-y-auto p-4 space-y-3`,children:[o.length===0&&(0,l.jsxs)(`div`,{className:`text-sm text-gray-500 text-center py-8`,children:[`Ask me anything about your project health!`,(0,l.jsx)(`div`,{className:`mt-2 text-xs text-gray-600`,children:`Try: "What should I fix first?" or "Explain the security issues"`})]}),o.map((e,t)=>(0,l.jsx)(`div`,{className:`flex ${e.role===`user`?`justify-end`:`justify-start`}`,children:(0,l.jsx)(`div`,{className:`max-w-[80%] px-3 py-2 rounded-lg text-sm ${e.role===`user`?`bg-accent text-black font-medium`:`bg-card text-gray-300`}`,children:e.role===`assistant`?(0,l.jsx)(u,{content:e.content}):e.content})},`${e.role}-${t}`)),p&&(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(`div`,{className:`bg-card text-gray-500 px-3 py-2 rounded-lg text-sm`,children:(0,l.jsx)(`span`,{className:`animate-pulse`,children:`⠋ thinking...`})})}),(0,l.jsx)(`div`,{ref:h})]}),(0,l.jsx)(`div`,{className:`px-4 py-3 border-t border-border`,children:(0,l.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),g()},className:`flex gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:d,onChange:e=>f(e.target.value),placeholder:`Ask about your project...`,disabled:p,className:`flex-1 bg-card border border-border rounded-sm px-3 py-2 text-sm focus:outline-hidden focus:border-accent disabled:opacity-50`}),(0,l.jsx)(`button`,{type:`submit`,disabled:p||!d.trim(),className:`px-4 py-2 bg-accent text-black rounded-sm text-sm font-semibold hover:bg-accent/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:`Send`})]})})]})]})}export{d as ChatDrawer};
2
+ //# sourceMappingURL=ChatDrawer-dCdqFiGs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatDrawer-dCdqFiGs.js","names":["useState","useEffect","useRef","ReactMarkdown","Prism","SyntaxHighlighter","vscDarkPlus","SickbayReport","ChatDrawerProps","report","packageName","Message","role","content","MarkdownMessage","t0","$","_c","t1","Symbol","for","code","t2","className","children","props","match","exec","margin","padding","String","replace","p","t3","children_0","ul","t4","children_1","ol","t5","children_2","li","t6","children_3","strong","t7","children_4","em","t8","children_5","a","t9","href","children_6","ChatDrawer","_report","isOpen","setIsOpen","isAvailable","setIsAvailable","messages","setMessages","input","setInput","loading","setLoading","messagesEndRef","HTMLDivElement","fetch","method","then","res","ok","catch","current","scrollIntoView","behavior","handleSend","trim","userMessage","prev","chatUrl","encodeURIComponent","response","headers","body","JSON","stringify","message","history","data","json","assistantMessage","errorMessage","length","map","msg","i","e","preventDefault","target","value"],"sources":["../../src/components/ChatDrawer.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\n\nimport { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport type { SickbayReport } from 'sickbay-core';\n\ninterface ChatDrawerProps {\n report: SickbayReport;\n packageName?: string;\n}\n\ninterface Message {\n role: 'user' | 'assistant';\n content: string;\n}\n\nfunction MarkdownMessage({ content }: { content: string }) {\n return (\n <div className=\"prose prose-invert prose-sm max-w-none\">\n <ReactMarkdown\n components={{\n code({\n className,\n children,\n ...props\n }: {\n className?: string;\n children?: React.ReactNode;\n }) {\n const match = /language-(\\w+)/.exec(className || '');\n return match ? (\n <SyntaxHighlighter\n style={vscDarkPlus}\n language={match[1]}\n PreTag=\"div\"\n className=\"rounded-md bg-black/30! mt-2! mb-2!\"\n customStyle={{ margin: 0, padding: '0.75rem' }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n ) : (\n <code\n className=\"bg-black/30 px-1.5 py-0.5 rounded-sm text-accent font-mono text-xs\"\n {...props}\n >\n {children}\n </code>\n );\n },\n p({ children }) {\n return <p className=\"mb-2 last:mb-0\">{children}</p>;\n },\n ul({ children }) {\n return <ul className=\"list-disc list-inside mb-2 space-y-1\">{children}</ul>;\n },\n ol({ children }) {\n return <ol className=\"list-decimal list-inside mb-2 space-y-1\">{children}</ol>;\n },\n li({ children }) {\n return <li className=\"text-sm\">{children}</li>;\n },\n strong({ children }) {\n return <strong className=\"font-semibold text-white\">{children}</strong>;\n },\n em({ children }) {\n return <em className=\"italic text-gray-200\">{children}</em>;\n },\n a({ href, children }) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-accent hover:underline\"\n >\n {children}\n </a>\n );\n },\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n );\n}\n\nexport function ChatDrawer({ report: _report, packageName }: ChatDrawerProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [isAvailable, setIsAvailable] = useState<boolean | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [loading, setLoading] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // Check if AI is available\n fetch('/ai/summary', { method: 'HEAD' })\n .then((res) => setIsAvailable(res.ok))\n .catch(() => setIsAvailable(false));\n }, []);\n\n // Reset conversation when switching packages\n useEffect(() => {\n setMessages([]);\n setIsOpen(false);\n }, [packageName]);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages]);\n\n const handleSend = async () => {\n if (!input.trim() || loading) return;\n\n const userMessage: Message = { role: 'user', content: input };\n setMessages((prev) => [...prev, userMessage]);\n setInput('');\n setLoading(true);\n\n try {\n const chatUrl = packageName\n ? `/ai/chat?package=${encodeURIComponent(packageName)}`\n : '/ai/chat';\n const response = await fetch(chatUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: input,\n history: messages,\n }),\n });\n\n if (response.ok) {\n const data = await response.json();\n const assistantMessage: Message = {\n role: 'assistant',\n content: data.response,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n } else {\n const errorMessage: Message = {\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n };\n setMessages((prev) => [...prev, errorMessage]);\n }\n } catch {\n const errorMessage: Message = {\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n };\n setMessages((prev) => [...prev, errorMessage]);\n } finally {\n setLoading(false);\n }\n };\n\n if (isAvailable === false) {\n return null;\n }\n\n return (\n <>\n {/* Floating button */}\n {!isOpen && (\n <button\n onClick={() => setIsOpen(true)}\n className=\"fixed bottom-6 right-6 w-14 h-14 bg-accent text-black rounded-sm shadow-lg hover:shadow-xl transition-all hover:scale-110 flex items-center justify-center text-2xl z-50\"\n title=\"AI Assistant\"\n >\n VAI\n </button>\n )}\n\n {/* Drawer */}\n {isOpen && (\n <div className=\"fixed bottom-6 right-6 w-140 h-200 bg-surface border border-border rounded-lg shadow-2xl flex flex-col z-50\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-lg\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n d=\"M9.6 6.112c.322-.816 1.478-.816 1.8 0l.91 2.31a5.8 5.8 0 0 0 3.268 3.268l2.31.91c.816.322.816 1.478 0 1.8l-2.31.91a5.8 5.8 0 0 0-3.268 3.268l-.91 2.31c-.322.816-1.478.816-1.8 0l-.91-2.31a5.8 5.8 0 0 0-3.268-3.268l-2.31-.91c-.816-.322-.816-1.478 0-1.8l2.31-.91A5.8 5.8 0 0 0 8.69 8.422zm8.563-3.382a.363.363 0 0 1 .674 0l.342.866c.221.56.665 1.004 1.225 1.225l.866.342a.363.363 0 0 1 0 .674l-.866.342a2.18 2.18 0 0 0-1.225 1.225l-.342.866a.363.363 0 0 1-.674 0l-.342-.866a2.18 2.18 0 0 0-1.225-1.225l-.867-.342a.363.363 0 0 1 0-.674l.867-.342a2.18 2.18 0 0 0 1.225-1.225z\"\n />\n </svg>\n </span>\n <span className=\"font-semibold text-sm\">AI Assistant</span>\n </div>\n <button\n onClick={() => setIsOpen(false)}\n className=\"text-gray-500 hover:text-white transition-colors text-lg\"\n >\n ✕\n </button>\n </div>\n\n {/* Messages */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-3\">\n {messages.length === 0 && (\n <div className=\"text-sm text-gray-500 text-center py-8\">\n Ask me anything about your project health!\n <div className=\"mt-2 text-xs text-gray-600\">\n Try: \"What should I fix first?\" or \"Explain the security issues\"\n </div>\n </div>\n )}\n {messages.map((msg, i) => (\n <div\n key={`${msg.role}-${i}`}\n className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}\n >\n <div\n className={`max-w-[80%] px-3 py-2 rounded-lg text-sm ${\n msg.role === 'user'\n ? 'bg-accent text-black font-medium'\n : 'bg-card text-gray-300'\n }`}\n >\n {msg.role === 'assistant' ? (\n <MarkdownMessage content={msg.content} />\n ) : (\n msg.content\n )}\n </div>\n </div>\n ))}\n {loading && (\n <div className=\"flex justify-start\">\n <div className=\"bg-card text-gray-500 px-3 py-2 rounded-lg text-sm\">\n <span className=\"animate-pulse\">⠋ thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input */}\n <div className=\"px-4 py-3 border-t border-border\">\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleSend();\n }}\n className=\"flex gap-2\"\n >\n <input\n type=\"text\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Ask about your project...\"\n disabled={loading}\n className=\"flex-1 bg-card border border-border rounded-sm px-3 py-2 text-sm focus:outline-hidden focus:border-accent disabled:opacity-50\"\n />\n <button\n type=\"submit\"\n disabled={loading || !input.trim()}\n className=\"px-4 py-2 bg-accent text-black rounded-sm text-sm font-semibold hover:bg-accent/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n Send\n </button>\n </form>\n </div>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"6LAkBA,SAAAc,EAAAC,EAAA,CAAA,IAAAC,GAAAA,EAAAA,EAAAA,GAAA,EAAA,CAAyB,CAAAH,WAAAE,EAAgCG,EAAAF,EAAA,KAAAG,OAAAC,IAAA,4BAAA,EAIrCF,EAAA,CAAAG,KAAAC,EAAA,CACL,GAAA,CAAAC,YAAAC,WAAA,GAAAC,GAAAH,EAQHI,EAAc,iBAAgBC,KAAMJ,GAAA,GAAgB,CAAC,OAC9CG,GACL,EAAA,EAAA,KAAC,EAAD,CACSpB,MAAAA,EACG,SAAAoB,EAAK,GACR,OAAA,MACG,UAAA,sCACG,YAAA,CAAAE,OAAU,EAACC,QAAW,UAAU,CAAC,GAC1CJ,WAEHK,OAAON,EAAS,CAAAO,QAAS,MAAO,GAAE,CAStC,CAAA,EANC,EAAA,EAAA,KAAA,OAAA,CACY,UAAA,qEAAoE,GAC1EN,EAEHD,WAEJ,CAAA,EAAAQ,EAAAC,EAAA,CAED,GAAA,CAAAT,SAAAU,GAAAD,EAAY,OACL,EAAA,EAAA,KAAA,IAAA,CAAa,UAAA,0BAAkBT,EAAa,CAAA,EAAAW,GAAAC,EAAA,CAElD,GAAA,CAAAZ,SAAAa,GAAAD,EAAY,OACN,EAAA,EAAA,KAAA,KAAA,CAAc,UAAA,gDAAwCZ,EAAc,CAAA,EAAAc,GAAAC,EAAA,CAE1E,GAAA,CAAAf,SAAAgB,GAAAD,EAAY,OACN,EAAA,EAAA,KAAA,KAAA,CAAc,UAAA,mDAA2Cf,EAAc,CAAA,EAAAiB,GAAAC,EAAA,CAE7E,GAAA,CAAAlB,SAAAmB,GAAAD,EAAY,OACN,EAAA,EAAA,KAAA,KAAA,CAAc,UAAA,mBAAWlB,EAAc,CAAA,EAAAoB,OAAAC,EAAA,CAEzC,GAAA,CAAArB,SAAAsB,GAAAD,EAAY,OACV,EAAA,EAAA,KAAA,SAAA,CAAkB,UAAA,oCAA4BrB,EAAkB,CAAA,EAAAuB,GAAAC,EAAA,CAEtE,GAAA,CAAAxB,SAAAyB,GAAAD,EAAY,OACN,EAAA,EAAA,KAAA,KAAA,CAAc,UAAA,gCAAwBxB,EAAc,CAAA,EAAA0B,EAAAC,EAAA,CAE3D,GAAA,CAAAC,OAAA5B,SAAA6B,GAAAF,EAAkB,OAEhB,EAAA,EAAA,KAAA,IAAA,CACQC,OACC,OAAA,SACH,IAAA,sBACM,UAAA,uCAET5B,EACC,CAAA,EAGT,CAAAR,EAAA,GAAAE,GAAAA,EAAAF,EAAA,GAAA,IAAAM,EAIC,OAJDN,EAAA,KAAAH,EAICS,EAAAN,EAAA,IAlENM,GAAA,EAAA,EAAA,KAAA,MAAA,CAAe,UAAA,mDACb,EAAA,EAAA,KAAC,EAAD,CACc,WAAAJ,WA8DXL,EAEL,CAAA,CAAM,CAAA,CAAAG,EAAA,GAAAH,EAAAG,EAAA,GAAAM,GAlENA,EAsEJ,SAAgBgC,EAAW,CAAE7C,OAAQ8C,EAAS7C,eAAgC,CAC5E,GAAM,CAAC8C,EAAQC,IAAAA,EAAAA,EAAAA,UAAsB,GAAM,CACrC,CAACC,EAAaC,IAAAA,EAAAA,EAAAA,UAA2C,KAAK,CAC9D,CAACC,EAAUC,IAAAA,EAAAA,EAAAA,UAAmC,EAAE,CAAC,CACjD,CAACC,EAAOC,IAAAA,EAAAA,EAAAA,UAAqB,GAAG,CAChC,CAACC,EAASC,IAAAA,EAAAA,EAAAA,UAAuB,GAAM,CACvCC,GAAAA,EAAAA,EAAAA,QAAwC,KAAK,EAEnDjE,EAAAA,EAAAA,eAAgB,CAEdmE,MAAM,cAAe,CAAEC,OAAQ,OAAQ,CAAC,CACrCC,KAAMC,GAAQZ,EAAeY,EAAIC,GAAG,CAAC,CACrCC,UAAYd,EAAe,GAAM,CAAC,EACpC,EAAE,CAAC,EAGN1D,EAAAA,EAAAA,eAAgB,CACd4D,EAAY,EAAE,CAAC,CACfJ,EAAU,GAAM,EACf,CAAC/C,EAAY,CAAC,EAEjBT,EAAAA,EAAAA,eAAgB,CACdiE,EAAeQ,SAASC,eAAe,CAAEC,SAAU,SAAU,CAAC,EAC7D,CAAChB,EAAS,CAAC,CAEd,IAAMiB,EAAa,SAAY,CAC7B,GAAI,CAACf,EAAMgB,MAAM,EAAId,EAAS,OAE9B,IAAMe,EAAuB,CAAEnE,KAAM,OAAQC,QAASiD,EAAO,CAC7DD,EAAamB,GAAS,CAAC,GAAGA,EAAMD,EAAY,CAAC,CAC7ChB,EAAS,GAAG,CACZE,EAAW,GAAK,CAEhB,GAAI,CACF,IAAMgB,EAAUvE,EACZ,oBAAoBwE,mBAAmBxE,EAAY,GACnD,WACEyE,EAAW,MAAMf,MAAMa,EAAS,CACpCZ,OAAQ,OACRe,QAAS,CAAE,eAAgB,mBAAoB,CAC/CC,KAAMC,KAAKC,UAAU,CACnBC,QAAS1B,EACT2B,QAAS7B,EACV,CAAA,CACF,CAAC,CAEF,GAAIuB,EAASX,GAAI,CAEf,IAAMoB,EAA4B,CAChChF,KAAM,YACNC,SAHW,MAAMsE,EAASQ,MAAM,EAGlBR,SACf,CACDtB,EAAamB,GAAS,CAAC,GAAGA,EAAMY,EAAiB,CAAC,KAC7C,CACL,IAAMC,EAAwB,CAC5BjF,KAAM,YACNC,QAAS,mDACV,CACDgD,EAAamB,GAAS,CAAC,GAAGA,EAAMa,EAAa,CAAC,OAE1C,CACN,IAAMA,EAAwB,CAC5BjF,KAAM,YACNC,QAAS,mDACV,CACDgD,EAAamB,GAAS,CAAC,GAAGA,EAAMa,EAAa,CAAC,QACtC,CACR5B,EAAW,GAAM,GAQrB,OAJIP,IAAgB,GACX,MAIP,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CAEG,CAACF,IACA,EAAA,EAAA,KAAC,SAAD,CACE,YAAeC,EAAU,GAAK,CAC9B,UAAU,2KACV,MAAM,wBAAc,MAIvB,CAAA,CAGAD,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,wHAAf,EAEE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,8EAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBACd,EAAA,EAAA,KAAC,MAAD,CAAK,MAAM,6BAA6B,MAAM,KAAK,OAAO,KAAK,QAAQ,sBACrE,EAAA,EAAA,KAAC,OAAD,CACE,KAAK,OACL,OAAO,eACP,YAAY,MACZ,EAAE,6jBAA4jB,CAAA,CAE7jB,CAAA,CACD,CAAA,EACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,iCAAwB,eAAkB,CAAA,CACvD,IACL,EAAA,EAAA,KAAC,SAAD,CACE,YAAeC,EAAU,GAAM,CAC/B,UAAU,oEAA0D,IAG9D,CAAA,CACL,IAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,gDAAf,CACGG,EAASkC,SAAW,IACnB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kDAAf,CAAuD,8CAErD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sCAA4B,mEAEtC,CAAA,CAER,GACAlC,EAASmC,KAAKC,EAAKC,KAClB,EAAA,EAAA,KAAC,MAAD,CAEE,UAAW,QAAQD,EAAIpF,OAAS,OAAS,cAAgB,4BAEzD,EAAA,EAAA,KAAC,MAAD,CACE,UAAW,4CACToF,EAAIpF,OAAS,OACT,mCACA,mCAGLoF,EAAIpF,OAAS,aACZ,EAAA,EAAA,KAAC,EAAD,CAAiB,QAASoF,EAAInF,QAAW,CAAA,CAEzCmF,EAAInF,QAEH,CAAA,CAER,CAjBQ,GAAGmF,EAAIpF,KAAI,GAAIqF,IAiBvB,CAAC,CACDjC,IACC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BACb,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+DACb,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yBAAgB,gBAAmB,CAAA,CAChD,CAAA,CAER,CAAA,EACD,EAAA,EAAA,KAAC,MAAD,CAAK,IAAKE,EAAe,CAAA,CACtB,IAGL,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6CACb,EAAA,EAAA,MAAC,OAAD,CACE,SAAWgC,GAAM,CACfA,EAAEC,gBAAgB,CAClBtB,GAAY,EAEd,UAAU,sBALZ,EAOE,EAAA,EAAA,KAAC,QAAD,CACE,KAAK,OACL,MAAOf,EACP,SAAWoC,GAAMnC,EAASmC,EAAEE,OAAOC,MAAM,CACzC,YAAY,4BACZ,SAAUrC,EACV,UAAU,gIAA+H,CAAA,EAE3I,EAAA,EAAA,KAAC,SAAD,CACE,KAAK,SACL,SAAUA,GAAW,CAACF,EAAMgB,MAAM,CAClC,UAAU,gKAAsJ,OAG1J,CAAA,CACJ,GACH,CAAA,CAER,GACA,CAAA,CAAA"}
@@ -1,2 +1,2 @@
1
- import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{i as t}from"./markdown-BkROfETq.js";import{i as n,n as r,r as i,t as a}from"./react-BEi4PGB1.js";import{t as o}from"./graph-viz-Ls9Hbzox.js";var s=n(),c=e(o(),1),l=t(),u={components:`#3b82f6`,hooks:`#10b981`,utils:`#a855f7`,lib:`#a855f7`,services:`#f59e0b`,api:`#f59e0b`,pages:`#ec4899`,views:`#ec4899`,routes:`#ec4899`,store:`#ef4444`,context:`#ef4444`,styles:`#06b6d4`,assets:`#06b6d4`,types:`#6b7280`};function d(e){let t=e.split(`/`);for(let e of t){let t=e.toLowerCase();if(u[t])return u[t]}return`#6b7280`}function f(e){let t=e.split(`/`);return t[t.length-1]}function p(e){let t=new Set,n=new Set,r=new Set;function i(a,o){if(r.has(a)){let e=o.indexOf(a);if(e!==-1){for(let n=e;n<o.length-1;n++)t.add(`${o[n]}|${o[n+1]}`);t.add(`${o[o.length-1]}|${a}`)}return}if(!n.has(a)){n.add(a),r.add(a),o.push(a);for(let t of e[a]??[])i(t,[...o]);r.delete(a)}}for(let t of Object.keys(e))i(t,[]);return t}function m(e,t){let n=new c.default.graphlib.Graph;n.setDefaultEdgeLabel(()=>({})),n.setGraph({rankdir:`LR`,nodesep:30,ranksep:80});for(let t of e)n.setNode(t.id,{width:160,height:36});for(let e of t)n.setEdge(e.source,e.target);return c.default.layout(n),{nodes:e.map(e=>{let t=n.node(e.id);return{...e,position:{x:t.x-80,y:t.y-18}}}),edges:t}}function h(e){return/\.(test|spec)\.[^.]+$/.test(e)||/\/__tests__\//.test(e)}function g(e){let t=(0,s.c)(9),{graph:n}=e,i;if(t[0]!==n){let e={};for(let[t,r]of Object.entries(n))h(t)||(e[t]=r.filter(y));let r=new Set;for(let[t,n]of Object.entries(e)){r.add(t);for(let e of n)r.add(e)}let a=p(e),o=Array.from(r).map(v),s=[];for(let[t,n]of Object.entries(e))for(let e of n){let n=a.has(`${t}|${e}`);s.push({id:`${t}->${e}`,source:t,target:e,style:{stroke:n?`#ef4444`:`#374151`,strokeWidth:n?2:1},animated:n,label:n?`circular`:void 0,labelStyle:n?{fill:`#ef4444`,fontSize:`9px`,fontWeight:600}:void 0,labelBgStyle:n?{fill:`#1a1a2e`,fillOpacity:.9}:void 0})}i=m(o,s),t[0]=n,t[1]=i}else i=t[1];let{nodes:o,edges:c}=i,u=_;if(o.length===0)return null;let d;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(d={height:`calc(100vh - 120px)`},t[2]=d):d=t[2];let f,g,b;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(f={hideAttribution:!0},g={background:`#0a0a0a`},b=(0,l.jsx)(a,{color:`#1e1e2e`,gap:20}),t[3]=f,t[4]=g,t[5]=b):(f=t[3],g=t[4],b=t[5]);let x;return t[6]!==c||t[7]!==o?(x=(0,l.jsx)(`div`,{className:`rounded-lg border border-border overflow-hidden`,style:d,children:(0,l.jsx)(r,{nodes:o,edges:c,onInit:u,fitView:!0,minZoom:.1,maxZoom:2,proOptions:f,style:g,children:b})}),t[6]=c,t[7]=o,t[8]=x):x=t[8],x}function _(e){setTimeout(()=>e.fitView(),100)}function v(e){let t=d(e);return{id:e,data:{label:f(e)},position:{x:0,y:0},sourcePosition:i.Right,targetPosition:i.Left,style:{background:`#1a1a2e`,color:`#e2e8f0`,border:`1.5px solid ${t}`,borderRadius:`6px`,fontSize:`11px`,padding:`6px 10px`,fontFamily:`monospace`,width:160}}}function y(e){return!h(e)}export{g as DependencyGraph};
2
- //# sourceMappingURL=DependencyGraph-DS5sXNvY.js.map
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{i as t}from"./markdown-oPAUxr3B.js";import{i as n,n as r,r as i,t as a}from"./react-DeNSbYyc.js";import{t as o}from"./graph-viz-7--E40m7.js";var s=n(),c=e(o(),1),l=t(),u={components:`#3b82f6`,hooks:`#10b981`,utils:`#a855f7`,lib:`#a855f7`,services:`#f59e0b`,api:`#f59e0b`,pages:`#ec4899`,views:`#ec4899`,routes:`#ec4899`,store:`#ef4444`,context:`#ef4444`,styles:`#06b6d4`,assets:`#06b6d4`,types:`#6b7280`};function d(e){let t=e.split(`/`);for(let e of t){let t=e.toLowerCase();if(u[t])return u[t]}return`#6b7280`}function f(e){let t=e.split(`/`);return t[t.length-1]}function p(e){let t=new Set,n=new Set,r=new Set;function i(a,o){if(r.has(a)){let e=o.indexOf(a);if(e!==-1){for(let n=e;n<o.length-1;n++)t.add(`${o[n]}|${o[n+1]}`);t.add(`${o[o.length-1]}|${a}`)}return}if(!n.has(a)){n.add(a),r.add(a),o.push(a);for(let t of e[a]??[])i(t,[...o]);r.delete(a)}}for(let t of Object.keys(e))i(t,[]);return t}function m(e,t){let n=new c.default.graphlib.Graph;n.setDefaultEdgeLabel(()=>({})),n.setGraph({rankdir:`LR`,nodesep:30,ranksep:80});for(let t of e)n.setNode(t.id,{width:160,height:36});for(let e of t)n.setEdge(e.source,e.target);return c.default.layout(n),{nodes:e.map(e=>{let t=n.node(e.id);return{...e,position:{x:t.x-80,y:t.y-18}}}),edges:t}}function h(e){return/\.(test|spec)\.[^.]+$/.test(e)||/\/__tests__\//.test(e)}function g(e){let t=(0,s.c)(9),{graph:n}=e,i;if(t[0]!==n){let e={};for(let[t,r]of Object.entries(n))h(t)||(e[t]=r.filter(y));let r=new Set;for(let[t,n]of Object.entries(e)){r.add(t);for(let e of n)r.add(e)}let a=p(e),o=Array.from(r).map(v),s=[];for(let[t,n]of Object.entries(e))for(let e of n){let n=a.has(`${t}|${e}`);s.push({id:`${t}->${e}`,source:t,target:e,style:{stroke:n?`#ef4444`:`#374151`,strokeWidth:n?2:1},animated:n,label:n?`circular`:void 0,labelStyle:n?{fill:`#ef4444`,fontSize:`9px`,fontWeight:600}:void 0,labelBgStyle:n?{fill:`#1a1a2e`,fillOpacity:.9}:void 0})}i=m(o,s),t[0]=n,t[1]=i}else i=t[1];let{nodes:o,edges:c}=i,u=_;if(o.length===0)return null;let d;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(d={height:`calc(100vh - 120px)`},t[2]=d):d=t[2];let f,g,b;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(f={hideAttribution:!0},g={background:`#0a0a0a`},b=(0,l.jsx)(a,{color:`#1e1e2e`,gap:20}),t[3]=f,t[4]=g,t[5]=b):(f=t[3],g=t[4],b=t[5]);let x;return t[6]!==c||t[7]!==o?(x=(0,l.jsx)(`div`,{className:`rounded-lg border border-border overflow-hidden`,style:d,children:(0,l.jsx)(r,{nodes:o,edges:c,onInit:u,fitView:!0,minZoom:.1,maxZoom:2,proOptions:f,style:g,children:b})}),t[6]=c,t[7]=o,t[8]=x):x=t[8],x}function _(e){setTimeout(()=>e.fitView(),100)}function v(e){let t=d(e);return{id:e,data:{label:f(e)},position:{x:0,y:0},sourcePosition:i.Right,targetPosition:i.Left,style:{background:`#1a1a2e`,color:`#e2e8f0`,border:`1.5px solid ${t}`,borderRadius:`6px`,fontSize:`11px`,padding:`6px 10px`,fontFamily:`monospace`,width:160}}}function y(e){return!h(e)}export{g as DependencyGraph};
2
+ //# sourceMappingURL=DependencyGraph-BSJPytrP.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DependencyGraph-DS5sXNvY.js","names":["useMemo","useCallback","ReactFlow","Background","Node","Edge","Position","dagre","DependencyGraphProps","graph","Record","circularCount","DIR_COLORS","components","hooks","utils","lib","services","api","pages","views","routes","store","context","styles","assets","types","getNodeColor","filePath","parts","split","part","lower","toLowerCase","getFileName","length","findCircularEdges","Set","circularEdges","visited","stack","dfs","node","path","has","cycleStart","indexOf","i","add","push","dep","delete","Object","keys","layoutGraph","nodes","edges","g","graphlib","Graph","setDefaultEdgeLabel","setGraph","rankdir","nodesep","ranksep","setNode","id","width","height","edge","setEdge","source","target","layout","layoutedNodes","map","pos","position","x","y","isTestFile","test","DependencyGraph","t0","$","_c","t1","filteredGraph","file","deps","entries","filter","_temp","allFiles","file_0","deps_0","rawNodes","Array","from","_temp2","rawEdges","file_2","deps_1","dep_0","isCircular","style","stroke","strokeWidth","animated","label","undefined","labelStyle","fill","fontSize","fontWeight","labelBgStyle","fillOpacity","onInit","_temp3","t2","Symbol","for","t3","t4","t5","hideAttribution","background","t6","instance","setTimeout","fitView","file_1","color","data","sourcePosition","Right","targetPosition","Left","border","borderRadius","padding","fontFamily","d"],"sources":["../../src/components/DependencyGraph.tsx"],"sourcesContent":["import { useMemo, useCallback } from 'react';\n\nimport { ReactFlow, Background, type Node, type Edge, Position } from '@xyflow/react';\nimport '@xyflow/react/dist/style.css';\nimport dagre from 'dagre';\n\ninterface DependencyGraphProps {\n graph: Record<string, string[]>;\n circularCount?: number;\n}\n\nconst DIR_COLORS: Record<string, string> = {\n components: '#3b82f6', // blue\n hooks: '#10b981', // green\n utils: '#a855f7', // purple\n lib: '#a855f7',\n services: '#f59e0b', // amber\n api: '#f59e0b',\n pages: '#ec4899', // pink\n views: '#ec4899',\n routes: '#ec4899',\n store: '#ef4444', // red\n context: '#ef4444',\n styles: '#06b6d4', // cyan\n assets: '#06b6d4',\n types: '#6b7280', // gray\n};\n\nfunction getNodeColor(filePath: string): string {\n const parts = filePath.split('/');\n for (const part of parts) {\n const lower = part.toLowerCase();\n if (DIR_COLORS[lower]) return DIR_COLORS[lower];\n }\n return '#6b7280'; // default gray\n}\n\nfunction getFileName(filePath: string): string {\n const parts = filePath.split('/');\n return parts[parts.length - 1];\n}\n\nfunction findCircularEdges(graph: Record<string, string[]>): Set<string> {\n const circularEdges = new Set<string>();\n const visited = new Set<string>();\n const stack = new Set<string>();\n\n function dfs(node: string, path: string[]): void {\n if (stack.has(node)) {\n // Found a cycle - mark all edges in the cycle\n const cycleStart = path.indexOf(node);\n if (cycleStart !== -1) {\n for (let i = cycleStart; i < path.length - 1; i++) {\n circularEdges.add(`${path[i]}|${path[i + 1]}`);\n }\n circularEdges.add(`${path[path.length - 1]}|${node}`);\n }\n return;\n }\n if (visited.has(node)) return;\n\n visited.add(node);\n stack.add(node);\n path.push(node);\n\n for (const dep of graph[node] ?? []) {\n dfs(dep, [...path]);\n }\n\n stack.delete(node);\n }\n\n for (const node of Object.keys(graph)) {\n dfs(node, []);\n }\n\n return circularEdges;\n}\n\nfunction layoutGraph(nodes: Node[], edges: Edge[]): { nodes: Node[]; edges: Edge[] } {\n const g = new dagre.graphlib.Graph();\n g.setDefaultEdgeLabel(() => ({}));\n g.setGraph({ rankdir: 'LR', nodesep: 30, ranksep: 80 });\n\n for (const node of nodes) {\n g.setNode(node.id, { width: 160, height: 36 });\n }\n\n for (const edge of edges) {\n g.setEdge(edge.source, edge.target);\n }\n\n dagre.layout(g);\n\n const layoutedNodes = nodes.map((node) => {\n const pos = g.node(node.id);\n return {\n ...node,\n position: { x: pos.x - 80, y: pos.y - 18 },\n };\n });\n\n return { nodes: layoutedNodes, edges };\n}\n\nfunction isTestFile(filePath: string): boolean {\n return /\\.(test|spec)\\.[^.]+$/.test(filePath) || /\\/__tests__\\//.test(filePath);\n}\n\nexport function DependencyGraph({ graph }: DependencyGraphProps) {\n const { nodes, edges } = useMemo(() => {\n const filteredGraph: Record<string, string[]> = {};\n for (const [file, deps] of Object.entries(graph)) {\n if (isTestFile(file)) continue;\n filteredGraph[file] = deps.filter((d) => !isTestFile(d));\n }\n\n const allFiles = new Set<string>();\n for (const [file, deps] of Object.entries(filteredGraph)) {\n allFiles.add(file);\n for (const dep of deps) {\n allFiles.add(dep);\n }\n }\n\n const circularEdges = findCircularEdges(filteredGraph);\n\n const rawNodes: Node[] = Array.from(allFiles).map((file) => {\n const color = getNodeColor(file);\n return {\n id: file,\n data: { label: getFileName(file) },\n position: { x: 0, y: 0 },\n sourcePosition: Position.Right,\n targetPosition: Position.Left,\n style: {\n background: '#1a1a2e',\n color: '#e2e8f0',\n border: `1.5px solid ${color}`,\n borderRadius: '6px',\n fontSize: '11px',\n padding: '6px 10px',\n fontFamily: 'monospace',\n width: 160,\n },\n };\n });\n\n const rawEdges: Edge[] = [];\n for (const [file, deps] of Object.entries(filteredGraph)) {\n for (const dep of deps) {\n const isCircular = circularEdges.has(`${file}|${dep}`);\n rawEdges.push({\n id: `${file}->${dep}`,\n source: file,\n target: dep,\n style: {\n stroke: isCircular ? '#ef4444' : '#374151',\n strokeWidth: isCircular ? 2 : 1,\n },\n animated: isCircular,\n label: isCircular ? 'circular' : undefined,\n labelStyle: isCircular\n ? { fill: '#ef4444', fontSize: '9px', fontWeight: 600 }\n : undefined,\n labelBgStyle: isCircular ? { fill: '#1a1a2e', fillOpacity: 0.9 } : undefined,\n });\n }\n }\n\n return layoutGraph(rawNodes, rawEdges);\n }, [graph]);\n\n const onInit = useCallback((instance: { fitView: () => void }) => {\n setTimeout(() => instance.fitView(), 100);\n }, []);\n\n if (nodes.length === 0) return null;\n\n return (\n <div\n className=\"rounded-lg border border-border overflow-hidden\"\n style={{ height: 'calc(100vh - 120px)' }}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onInit={onInit}\n fitView\n minZoom={0.1}\n maxZoom={2}\n proOptions={{ hideAttribution: true }}\n style={{ background: '#0a0a0a' }}\n >\n <Background color=\"#1e1e2e\" gap={20} />\n </ReactFlow>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DependencyGraph-BSJPytrP.js","names":["useMemo","useCallback","ReactFlow","Background","Node","Edge","Position","dagre","DependencyGraphProps","graph","Record","circularCount","DIR_COLORS","components","hooks","utils","lib","services","api","pages","views","routes","store","context","styles","assets","types","getNodeColor","filePath","parts","split","part","lower","toLowerCase","getFileName","length","findCircularEdges","Set","circularEdges","visited","stack","dfs","node","path","has","cycleStart","indexOf","i","add","push","dep","delete","Object","keys","layoutGraph","nodes","edges","g","graphlib","Graph","setDefaultEdgeLabel","setGraph","rankdir","nodesep","ranksep","setNode","id","width","height","edge","setEdge","source","target","layout","layoutedNodes","map","pos","position","x","y","isTestFile","test","DependencyGraph","t0","$","_c","t1","filteredGraph","file","deps","entries","filter","_temp","allFiles","file_0","deps_0","rawNodes","Array","from","_temp2","rawEdges","file_2","deps_1","dep_0","isCircular","style","stroke","strokeWidth","animated","label","undefined","labelStyle","fill","fontSize","fontWeight","labelBgStyle","fillOpacity","onInit","_temp3","t2","Symbol","for","t3","t4","t5","hideAttribution","background","t6","instance","setTimeout","fitView","file_1","color","data","sourcePosition","Right","targetPosition","Left","border","borderRadius","padding","fontFamily","d"],"sources":["../../src/components/DependencyGraph.tsx"],"sourcesContent":["import { useMemo, useCallback } from 'react';\n\nimport { ReactFlow, Background, type Node, type Edge, Position } from '@xyflow/react';\nimport '@xyflow/react/dist/style.css';\nimport dagre from 'dagre';\n\ninterface DependencyGraphProps {\n graph: Record<string, string[]>;\n circularCount?: number;\n}\n\nconst DIR_COLORS: Record<string, string> = {\n components: '#3b82f6', // blue\n hooks: '#10b981', // green\n utils: '#a855f7', // purple\n lib: '#a855f7',\n services: '#f59e0b', // amber\n api: '#f59e0b',\n pages: '#ec4899', // pink\n views: '#ec4899',\n routes: '#ec4899',\n store: '#ef4444', // red\n context: '#ef4444',\n styles: '#06b6d4', // cyan\n assets: '#06b6d4',\n types: '#6b7280', // gray\n};\n\nfunction getNodeColor(filePath: string): string {\n const parts = filePath.split('/');\n for (const part of parts) {\n const lower = part.toLowerCase();\n if (DIR_COLORS[lower]) return DIR_COLORS[lower];\n }\n return '#6b7280'; // default gray\n}\n\nfunction getFileName(filePath: string): string {\n const parts = filePath.split('/');\n return parts[parts.length - 1];\n}\n\nfunction findCircularEdges(graph: Record<string, string[]>): Set<string> {\n const circularEdges = new Set<string>();\n const visited = new Set<string>();\n const stack = new Set<string>();\n\n function dfs(node: string, path: string[]): void {\n if (stack.has(node)) {\n // Found a cycle - mark all edges in the cycle\n const cycleStart = path.indexOf(node);\n if (cycleStart !== -1) {\n for (let i = cycleStart; i < path.length - 1; i++) {\n circularEdges.add(`${path[i]}|${path[i + 1]}`);\n }\n circularEdges.add(`${path[path.length - 1]}|${node}`);\n }\n return;\n }\n if (visited.has(node)) return;\n\n visited.add(node);\n stack.add(node);\n path.push(node);\n\n for (const dep of graph[node] ?? []) {\n dfs(dep, [...path]);\n }\n\n stack.delete(node);\n }\n\n for (const node of Object.keys(graph)) {\n dfs(node, []);\n }\n\n return circularEdges;\n}\n\nfunction layoutGraph(nodes: Node[], edges: Edge[]): { nodes: Node[]; edges: Edge[] } {\n const g = new dagre.graphlib.Graph();\n g.setDefaultEdgeLabel(() => ({}));\n g.setGraph({ rankdir: 'LR', nodesep: 30, ranksep: 80 });\n\n for (const node of nodes) {\n g.setNode(node.id, { width: 160, height: 36 });\n }\n\n for (const edge of edges) {\n g.setEdge(edge.source, edge.target);\n }\n\n dagre.layout(g);\n\n const layoutedNodes = nodes.map((node) => {\n const pos = g.node(node.id);\n return {\n ...node,\n position: { x: pos.x - 80, y: pos.y - 18 },\n };\n });\n\n return { nodes: layoutedNodes, edges };\n}\n\nfunction isTestFile(filePath: string): boolean {\n return /\\.(test|spec)\\.[^.]+$/.test(filePath) || /\\/__tests__\\//.test(filePath);\n}\n\nexport function DependencyGraph({ graph }: DependencyGraphProps) {\n const { nodes, edges } = useMemo(() => {\n const filteredGraph: Record<string, string[]> = {};\n for (const [file, deps] of Object.entries(graph)) {\n if (isTestFile(file)) continue;\n filteredGraph[file] = deps.filter((d) => !isTestFile(d));\n }\n\n const allFiles = new Set<string>();\n for (const [file, deps] of Object.entries(filteredGraph)) {\n allFiles.add(file);\n for (const dep of deps) {\n allFiles.add(dep);\n }\n }\n\n const circularEdges = findCircularEdges(filteredGraph);\n\n const rawNodes: Node[] = Array.from(allFiles).map((file) => {\n const color = getNodeColor(file);\n return {\n id: file,\n data: { label: getFileName(file) },\n position: { x: 0, y: 0 },\n sourcePosition: Position.Right,\n targetPosition: Position.Left,\n style: {\n background: '#1a1a2e',\n color: '#e2e8f0',\n border: `1.5px solid ${color}`,\n borderRadius: '6px',\n fontSize: '11px',\n padding: '6px 10px',\n fontFamily: 'monospace',\n width: 160,\n },\n };\n });\n\n const rawEdges: Edge[] = [];\n for (const [file, deps] of Object.entries(filteredGraph)) {\n for (const dep of deps) {\n const isCircular = circularEdges.has(`${file}|${dep}`);\n rawEdges.push({\n id: `${file}->${dep}`,\n source: file,\n target: dep,\n style: {\n stroke: isCircular ? '#ef4444' : '#374151',\n strokeWidth: isCircular ? 2 : 1,\n },\n animated: isCircular,\n label: isCircular ? 'circular' : undefined,\n labelStyle: isCircular\n ? { fill: '#ef4444', fontSize: '9px', fontWeight: 600 }\n : undefined,\n labelBgStyle: isCircular ? { fill: '#1a1a2e', fillOpacity: 0.9 } : undefined,\n });\n }\n }\n\n return layoutGraph(rawNodes, rawEdges);\n }, [graph]);\n\n const onInit = useCallback((instance: { fitView: () => void }) => {\n setTimeout(() => instance.fitView(), 100);\n }, []);\n\n if (nodes.length === 0) return null;\n\n return (\n <div\n className=\"rounded-lg border border-border overflow-hidden\"\n style={{ height: 'calc(100vh - 120px)' }}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onInit={onInit}\n fitView\n minZoom={0.1}\n maxZoom={2}\n proOptions={{ hideAttribution: true }}\n style={{ background: '#0a0a0a' }}\n >\n <Background color=\"#1e1e2e\" gap={20} />\n </ReactFlow>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as e}from"./markdown-BkROfETq.js";import{i as t}from"./react-BEi4PGB1.js";var n=t(),r=e();function i(e){return e>=80?`text-green-400`:e>=60?`text-yellow-400`:`text-red-400`}function a(e){return e>=80?`stroke-green-400`:e>=60?`stroke-yellow-400`:`stroke-red-400`}function o(e){let t=(0,n.c)(41),{pkg:o,index:s,onClick:c}=e,l=2*Math.PI*28,u=l-o.score/100*l,d;t[0]===o.score?d=t[1]:(d=i(o.score),t[0]=o.score,t[1]=d);let f=d,p;t[2]===o.score?p=t[3]:(p=a(o.score),t[2]=o.score,t[3]=p);let m=p,h;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,r.jsx)(`circle`,{cx:`32`,cy:`32`,r:`28`,fill:`none`,stroke:`#2a2a2a`,strokeWidth:`4`}),t[4]=h):h=t[4];let g=`transition-all duration-700 ${m}`,_;t[5]!==u||t[6]!==g?(_=(0,r.jsxs)(`svg`,{className:`w-16 h-16 -rotate-90`,viewBox:`0 0 64 64`,children:[h,(0,r.jsx)(`circle`,{cx:`32`,cy:`32`,r:`28`,fill:`none`,strokeWidth:`4`,strokeDasharray:l,strokeDashoffset:u,strokeLinecap:`round`,className:g})]}),t[5]=u,t[6]=g,t[7]=_):_=t[7];let v=`absolute inset-0 flex items-center justify-center text-lg font-bold ${f}`,y;t[8]!==o.score||t[9]!==v?(y=(0,r.jsx)(`span`,{className:v,children:o.score}),t[8]=o.score,t[9]=v,t[10]=y):y=t[10];let b;t[11]!==_||t[12]!==y?(b=(0,r.jsxs)(`div`,{className:`relative w-16 h-16`,children:[_,y]}),t[11]=_,t[12]=y,t[13]=b):b=t[13];let x;t[14]===o.name?x=t[15]:(x=(0,r.jsx)(`div`,{className:`text-sm font-semibold truncate`,children:o.name}),t[14]=o.name,t[15]=x);let S;t[16]!==o.framework||t[17]!==o.relativePath?(S=(0,r.jsxs)(`div`,{className:`text-xs text-gray-500 mt-0.5`,children:[o.framework,` · `,o.relativePath]}),t[16]=o.framework,t[17]=o.relativePath,t[18]=S):S=t[18];let C;t[19]!==S||t[20]!==x?(C=(0,r.jsxs)(`div`,{className:`text-center w-full`,children:[x,S]}),t[19]=S,t[20]=x,t[21]=C):C=t[21];let w;t[22]===o.summary.critical?w=t[23]:(w=o.summary.critical>0&&(0,r.jsxs)(`span`,{className:`text-red-400`,children:[o.summary.critical,` critical`]}),t[22]=o.summary.critical,t[23]=w);let T;t[24]===o.summary.warnings?T=t[25]:(T=o.summary.warnings>0&&(0,r.jsxs)(`span`,{className:`text-yellow-400`,children:[o.summary.warnings,` warnings`]}),t[24]=o.summary.warnings,t[25]=T);let E;t[26]!==o.summary.critical||t[27]!==o.summary.warnings?(E=o.summary.critical===0&&o.summary.warnings===0&&(0,r.jsx)(`span`,{className:`text-green-400`,children:`✓ clean`}),t[26]=o.summary.critical,t[27]=o.summary.warnings,t[28]=E):E=t[28];let D;t[29]!==w||t[30]!==T||t[31]!==E?(D=(0,r.jsxs)(`div`,{className:`flex gap-3 text-xs w-full justify-center`,children:[w,T,E]}),t[29]=w,t[30]=T,t[31]=E,t[32]=D):D=t[32];let O=s+1===1?`click to inspect →`:``,k;t[33]===O?k=t[34]:(k=(0,r.jsx)(`div`,{className:`text-xs text-gray-500`,children:O}),t[33]=O,t[34]=k);let A;return t[35]!==c||t[36]!==C||t[37]!==D||t[38]!==k||t[39]!==b?(A=(0,r.jsxs)(`button`,{onClick:c,className:`flex flex-col items-center gap-3 p-4 rounded-lg border border-border bg-surface hover:border-accent/50 transition-all cursor-pointer text-left w-full`,children:[b,C,D,k]}),t[35]=c,t[36]=C,t[37]=D,t[38]=k,t[39]=b,t[40]=A):A=t[40],A}function s(e,t=8){let n=new Set,r=[];for(let i of e)for(let e of i.checks)for(let a of e.issues){if(a.severity===`critical`&&a.fix){let e=a.fix.command??a.fix.description;n.has(e)||(n.add(e),r.push({pkg:i.name,message:a.message,command:a.fix.command}))}if(r.length>=t)return r}return r}function c(e){let t=(0,n.c)(40),{report:a,onSelectPackage:c}=e,u;if(t[0]!==c||t[1]!==a.monorepoType||t[2]!==a.overallScore||t[3]!==a.packages||t[4]!==a.summary.critical||t[5]!==a.summary.info||t[6]!==a.summary.warnings){let e=s(a.packages),n;t[8]===a.overallScore?n=t[9]:(n=i(a.overallScore),t[8]=a.overallScore,t[9]=n);let d=`text-5xl font-bold ${n}`,f;t[10]!==a.overallScore||t[11]!==d?(f=(0,r.jsx)(`div`,{className:d,children:a.overallScore}),t[10]=a.overallScore,t[11]=d,t[12]=f):f=t[12];let p;t[13]!==a.monorepoType||t[14]!==a.packages.length?(p=(0,r.jsxs)(`div`,{className:`text-gray-400 text-sm`,children:[`monorepo health · `,a.monorepoType,` workspaces · `,a.packages.length,` packages`]}),t[13]=a.monorepoType,t[14]=a.packages.length,t[15]=p):p=t[15];let m;t[16]!==f||t[17]!==p?(m=(0,r.jsxs)(`div`,{className:`flex items-baseline gap-4 mb-1`,children:[f,p]}),t[16]=f,t[17]=p,t[18]=m):m=t[18];let h;t[19]===a.summary.critical?h=t[20]:(h=(0,r.jsxs)(`span`,{className:`text-red-400`,children:[a.summary.critical,` critical`]}),t[19]=a.summary.critical,t[20]=h);let g;t[21]===a.summary.warnings?g=t[22]:(g=(0,r.jsxs)(`span`,{className:`text-yellow-400`,children:[a.summary.warnings,` warnings`]}),t[21]=a.summary.warnings,t[22]=g);let _;t[23]===a.summary.info?_=t[24]:(_=(0,r.jsxs)(`span`,{className:`text-gray-500`,children:[a.summary.info,` info`]}),t[23]=a.summary.info,t[24]=_);let v;t[25]!==h||t[26]!==g||t[27]!==_?(v=(0,r.jsxs)(`div`,{className:`flex gap-4 text-sm`,children:[h,g,_]}),t[25]=h,t[26]=g,t[27]=_,t[28]=v):v=t[28];let y;t[29]!==v||t[30]!==m?(y=(0,r.jsxs)(`div`,{className:`mb-6`,children:[m,v]}),t[29]=v,t[30]=m,t[31]=y):y=t[31];let b;t[32]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,r.jsx)(`h2`,{className:`text-xs text-gray-500 font-mono uppercase tracking-wider mb-3`,children:`packages`}),t[32]=b):b=t[32];let x;if(t[33]!==c||t[34]!==a.packages){let e;t[36]===c?e=t[37]:(e=(e,t)=>(0,r.jsx)(o,{pkg:e,index:t,onClick:()=>c(t)},e.path),t[36]=c,t[37]=e),x=a.packages.map(e),t[33]=c,t[34]=a.packages,t[35]=x}else x=t[35];let S;t[38]===x?S=t[39]:(S=(0,r.jsxs)(`div`,{className:`mb-8`,children:[b,(0,r.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4`,children:x})]}),t[38]=x,t[39]=S),u=(0,r.jsxs)(`div`,{className:`p-6`,children:[y,S,e.length>0&&(0,r.jsxs)(`div`,{children:[(0,r.jsx)(`h2`,{className:`text-xs text-gray-500 font-mono uppercase tracking-wider mb-3`,children:`cross-package quick wins`}),(0,r.jsx)(`div`,{className:`space-y-2`,children:e.map(l)})]})]}),t[0]=c,t[1]=a.monorepoType,t[2]=a.overallScore,t[3]=a.packages,t[4]=a.summary.critical,t[5]=a.summary.info,t[6]=a.summary.warnings,t[7]=u}else u=t[7];return u}function l(e){return(0,r.jsxs)(`div`,{className:`flex flex-col gap-0.5 p-3 rounded-sm border border-border bg-surface`,children:[(0,r.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,r.jsx)(`span`,{className:`text-red-400 text-xs font-mono shrink-0`,children:`●`}),(0,r.jsxs)(`div`,{children:[(0,r.jsx)(`span`,{className:`text-sm text-gray-300`,children:e.message}),(0,r.jsxs)(`span`,{className:`text-xs text-gray-500 ml-2`,children:[`(`,e.pkg,`)`]})]})]}),e.command&&(0,r.jsxs)(`code`,{className:`text-xs text-green-400 font-mono ml-4 mt-0.5 block`,children:[`$ `,e.command]})]},`${e.pkg}-${e.message}`)}export{c as MonorepoOverview};
2
- //# sourceMappingURL=MonorepoOverview-vTq9TL11.js.map
1
+ import{i as e}from"./markdown-oPAUxr3B.js";import{i as t}from"./react-DeNSbYyc.js";var n=t(),r=e();function i(e){return e>=80?`text-green-400`:e>=60?`text-yellow-400`:`text-red-400`}function a(e){return e>=80?`stroke-green-400`:e>=60?`stroke-yellow-400`:`stroke-red-400`}function o(e){let t=(0,n.c)(41),{pkg:o,index:s,onClick:c}=e,l=2*Math.PI*28,u=l-o.score/100*l,d;t[0]===o.score?d=t[1]:(d=i(o.score),t[0]=o.score,t[1]=d);let f=d,p;t[2]===o.score?p=t[3]:(p=a(o.score),t[2]=o.score,t[3]=p);let m=p,h;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,r.jsx)(`circle`,{cx:`32`,cy:`32`,r:`28`,fill:`none`,stroke:`#2a2a2a`,strokeWidth:`4`}),t[4]=h):h=t[4];let g=`transition-all duration-700 ${m}`,_;t[5]!==u||t[6]!==g?(_=(0,r.jsxs)(`svg`,{className:`w-16 h-16 -rotate-90`,viewBox:`0 0 64 64`,children:[h,(0,r.jsx)(`circle`,{cx:`32`,cy:`32`,r:`28`,fill:`none`,strokeWidth:`4`,strokeDasharray:l,strokeDashoffset:u,strokeLinecap:`round`,className:g})]}),t[5]=u,t[6]=g,t[7]=_):_=t[7];let v=`absolute inset-0 flex items-center justify-center text-lg font-bold ${f}`,y;t[8]!==o.score||t[9]!==v?(y=(0,r.jsx)(`span`,{className:v,children:o.score}),t[8]=o.score,t[9]=v,t[10]=y):y=t[10];let b;t[11]!==_||t[12]!==y?(b=(0,r.jsxs)(`div`,{className:`relative w-16 h-16`,children:[_,y]}),t[11]=_,t[12]=y,t[13]=b):b=t[13];let x;t[14]===o.name?x=t[15]:(x=(0,r.jsx)(`div`,{className:`text-sm font-semibold truncate`,children:o.name}),t[14]=o.name,t[15]=x);let S;t[16]!==o.framework||t[17]!==o.relativePath?(S=(0,r.jsxs)(`div`,{className:`text-xs text-gray-500 mt-0.5`,children:[o.framework,` · `,o.relativePath]}),t[16]=o.framework,t[17]=o.relativePath,t[18]=S):S=t[18];let C;t[19]!==S||t[20]!==x?(C=(0,r.jsxs)(`div`,{className:`text-center w-full`,children:[x,S]}),t[19]=S,t[20]=x,t[21]=C):C=t[21];let w;t[22]===o.summary.critical?w=t[23]:(w=o.summary.critical>0&&(0,r.jsxs)(`span`,{className:`text-red-400`,children:[o.summary.critical,` critical`]}),t[22]=o.summary.critical,t[23]=w);let T;t[24]===o.summary.warnings?T=t[25]:(T=o.summary.warnings>0&&(0,r.jsxs)(`span`,{className:`text-yellow-400`,children:[o.summary.warnings,` warnings`]}),t[24]=o.summary.warnings,t[25]=T);let E;t[26]!==o.summary.critical||t[27]!==o.summary.warnings?(E=o.summary.critical===0&&o.summary.warnings===0&&(0,r.jsx)(`span`,{className:`text-green-400`,children:`✓ clean`}),t[26]=o.summary.critical,t[27]=o.summary.warnings,t[28]=E):E=t[28];let D;t[29]!==w||t[30]!==T||t[31]!==E?(D=(0,r.jsxs)(`div`,{className:`flex gap-3 text-xs w-full justify-center`,children:[w,T,E]}),t[29]=w,t[30]=T,t[31]=E,t[32]=D):D=t[32];let O=s+1===1?`click to inspect →`:``,k;t[33]===O?k=t[34]:(k=(0,r.jsx)(`div`,{className:`text-xs text-gray-500`,children:O}),t[33]=O,t[34]=k);let A;return t[35]!==c||t[36]!==C||t[37]!==D||t[38]!==k||t[39]!==b?(A=(0,r.jsxs)(`button`,{onClick:c,className:`flex flex-col items-center gap-3 p-4 rounded-lg border border-border bg-surface hover:border-accent/50 transition-all cursor-pointer text-left w-full`,children:[b,C,D,k]}),t[35]=c,t[36]=C,t[37]=D,t[38]=k,t[39]=b,t[40]=A):A=t[40],A}function s(e,t=8){let n=new Set,r=[];for(let i of e)for(let e of i.checks)for(let a of e.issues){if(a.severity===`critical`&&a.fix){let e=a.fix.command??a.fix.description;n.has(e)||(n.add(e),r.push({pkg:i.name,message:a.message,command:a.fix.command}))}if(r.length>=t)return r}return r}function c(e){let t=(0,n.c)(40),{report:a,onSelectPackage:c}=e,u;if(t[0]!==c||t[1]!==a.monorepoType||t[2]!==a.overallScore||t[3]!==a.packages||t[4]!==a.summary.critical||t[5]!==a.summary.info||t[6]!==a.summary.warnings){let e=s(a.packages),n;t[8]===a.overallScore?n=t[9]:(n=i(a.overallScore),t[8]=a.overallScore,t[9]=n);let d=`text-5xl font-bold ${n}`,f;t[10]!==a.overallScore||t[11]!==d?(f=(0,r.jsx)(`div`,{className:d,children:a.overallScore}),t[10]=a.overallScore,t[11]=d,t[12]=f):f=t[12];let p;t[13]!==a.monorepoType||t[14]!==a.packages.length?(p=(0,r.jsxs)(`div`,{className:`text-gray-400 text-sm`,children:[`monorepo health · `,a.monorepoType,` workspaces · `,a.packages.length,` packages`]}),t[13]=a.monorepoType,t[14]=a.packages.length,t[15]=p):p=t[15];let m;t[16]!==f||t[17]!==p?(m=(0,r.jsxs)(`div`,{className:`flex items-baseline gap-4 mb-1`,children:[f,p]}),t[16]=f,t[17]=p,t[18]=m):m=t[18];let h;t[19]===a.summary.critical?h=t[20]:(h=(0,r.jsxs)(`span`,{className:`text-red-400`,children:[a.summary.critical,` critical`]}),t[19]=a.summary.critical,t[20]=h);let g;t[21]===a.summary.warnings?g=t[22]:(g=(0,r.jsxs)(`span`,{className:`text-yellow-400`,children:[a.summary.warnings,` warnings`]}),t[21]=a.summary.warnings,t[22]=g);let _;t[23]===a.summary.info?_=t[24]:(_=(0,r.jsxs)(`span`,{className:`text-gray-500`,children:[a.summary.info,` info`]}),t[23]=a.summary.info,t[24]=_);let v;t[25]!==h||t[26]!==g||t[27]!==_?(v=(0,r.jsxs)(`div`,{className:`flex gap-4 text-sm`,children:[h,g,_]}),t[25]=h,t[26]=g,t[27]=_,t[28]=v):v=t[28];let y;t[29]!==v||t[30]!==m?(y=(0,r.jsxs)(`div`,{className:`mb-6`,children:[m,v]}),t[29]=v,t[30]=m,t[31]=y):y=t[31];let b;t[32]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,r.jsx)(`h2`,{className:`text-xs text-gray-500 font-mono uppercase tracking-wider mb-3`,children:`packages`}),t[32]=b):b=t[32];let x;if(t[33]!==c||t[34]!==a.packages){let e;t[36]===c?e=t[37]:(e=(e,t)=>(0,r.jsx)(o,{pkg:e,index:t,onClick:()=>c(t)},e.path),t[36]=c,t[37]=e),x=a.packages.map(e),t[33]=c,t[34]=a.packages,t[35]=x}else x=t[35];let S;t[38]===x?S=t[39]:(S=(0,r.jsxs)(`div`,{className:`mb-8`,children:[b,(0,r.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4`,children:x})]}),t[38]=x,t[39]=S),u=(0,r.jsxs)(`div`,{className:`p-6`,children:[y,S,e.length>0&&(0,r.jsxs)(`div`,{children:[(0,r.jsx)(`h2`,{className:`text-xs text-gray-500 font-mono uppercase tracking-wider mb-3`,children:`cross-package quick wins`}),(0,r.jsx)(`div`,{className:`space-y-2`,children:e.map(l)})]})]}),t[0]=c,t[1]=a.monorepoType,t[2]=a.overallScore,t[3]=a.packages,t[4]=a.summary.critical,t[5]=a.summary.info,t[6]=a.summary.warnings,t[7]=u}else u=t[7];return u}function l(e){return(0,r.jsxs)(`div`,{className:`flex flex-col gap-0.5 p-3 rounded-sm border border-border bg-surface`,children:[(0,r.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,r.jsx)(`span`,{className:`text-red-400 text-xs font-mono shrink-0`,children:`●`}),(0,r.jsxs)(`div`,{children:[(0,r.jsx)(`span`,{className:`text-sm text-gray-300`,children:e.message}),(0,r.jsxs)(`span`,{className:`text-xs text-gray-500 ml-2`,children:[`(`,e.pkg,`)`]})]})]}),e.command&&(0,r.jsxs)(`code`,{className:`text-xs text-green-400 font-mono ml-4 mt-0.5 block`,children:[`$ `,e.command]})]},`${e.pkg}-${e.message}`)}export{c as MonorepoOverview};
2
+ //# sourceMappingURL=MonorepoOverview-DDbHHZi0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonorepoOverview-DDbHHZi0.js","names":["SCORE_GOOD","SCORE_FAIR","MonorepoReport","PackageReport","MonorepoOverviewProps","report","onSelectPackage","idx","getScoreColorClass","score","getScoreRingClass","PackageScoreCard","t0","$","_c","pkg","index","onClick","circumference","Math","PI","offset","t1","colorClass","t2","ringClass","t3","Symbol","for","t4","t5","t6","t7","t8","t9","name","t10","framework","relativePath","t11","t12","summary","critical","t13","warnings","t14","t15","t16","t17","t18","collectQuickWins","packages","limit","seen","Set","wins","Array","message","command","check","checks","issue","issues","severity","fix","key","description","has","add","push","length","MonorepoOverview","monorepoType","overallScore","info","quickWins","overallColor","i","path","map","_temp","win"],"sources":["../../src/components/MonorepoOverview.tsx"],"sourcesContent":["import { SCORE_GOOD, SCORE_FAIR } from '../lib/constants.js';\n\nimport type { MonorepoReport, PackageReport } from 'sickbay-core';\n\ninterface MonorepoOverviewProps {\n report: MonorepoReport;\n onSelectPackage: (idx: number) => void;\n}\n\nfunction getScoreColorClass(score: number) {\n if (score >= SCORE_GOOD) return 'text-green-400';\n if (score >= SCORE_FAIR) return 'text-yellow-400';\n return 'text-red-400';\n}\n\nfunction getScoreRingClass(score: number) {\n if (score >= SCORE_GOOD) return 'stroke-green-400';\n if (score >= SCORE_FAIR) return 'stroke-yellow-400';\n return 'stroke-red-400';\n}\n\nfunction PackageScoreCard({\n pkg,\n index,\n onClick,\n}: {\n pkg: PackageReport;\n index: number;\n onClick: () => void;\n}) {\n const circumference = 2 * Math.PI * 28;\n const offset = circumference - (pkg.score / 100) * circumference;\n const colorClass = getScoreColorClass(pkg.score);\n const ringClass = getScoreRingClass(pkg.score);\n\n return (\n <button\n onClick={onClick}\n className=\"flex flex-col items-center gap-3 p-4 rounded-lg border border-border bg-surface hover:border-accent/50 transition-all cursor-pointer text-left w-full\"\n >\n <div className=\"relative w-16 h-16\">\n <svg className=\"w-16 h-16 -rotate-90\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"none\" stroke=\"#2a2a2a\" strokeWidth=\"4\" />\n <circle\n cx=\"32\"\n cy=\"32\"\n r=\"28\"\n fill=\"none\"\n strokeWidth=\"4\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n className={`transition-all duration-700 ${ringClass}`}\n />\n </svg>\n <span\n className={`absolute inset-0 flex items-center justify-center text-lg font-bold ${colorClass}`}\n >\n {pkg.score}\n </span>\n </div>\n\n <div className=\"text-center w-full\">\n <div className=\"text-sm font-semibold truncate\">{pkg.name}</div>\n <div className=\"text-xs text-gray-500 mt-0.5\">\n {pkg.framework} · {pkg.relativePath}\n </div>\n </div>\n\n <div className=\"flex gap-3 text-xs w-full justify-center\">\n {pkg.summary.critical > 0 && (\n <span className=\"text-red-400\">{pkg.summary.critical} critical</span>\n )}\n {pkg.summary.warnings > 0 && (\n <span className=\"text-yellow-400\">{pkg.summary.warnings} warnings</span>\n )}\n {pkg.summary.critical === 0 && pkg.summary.warnings === 0 && (\n <span className=\"text-green-400\">✓ clean</span>\n )}\n </div>\n\n <div className=\"text-xs text-gray-500\">{index + 1 === 1 ? 'click to inspect →' : ''}</div>\n </button>\n );\n}\n\n/** Collect the top quick wins across all packages, deduped by fix command */\nfunction collectQuickWins(packages: PackageReport[], limit = 8) {\n const seen = new Set<string>();\n const wins: Array<{ pkg: string; message: string; command?: string }> = [];\n\n for (const pkg of packages) {\n for (const check of pkg.checks) {\n for (const issue of check.issues) {\n if (issue.severity === 'critical' && issue.fix) {\n const key = issue.fix.command ?? issue.fix.description;\n if (!seen.has(key)) {\n seen.add(key);\n wins.push({\n pkg: pkg.name,\n message: issue.message,\n command: issue.fix.command,\n });\n }\n }\n if (wins.length >= limit) return wins;\n }\n }\n }\n return wins;\n}\n\nexport function MonorepoOverview({ report, onSelectPackage }: MonorepoOverviewProps) {\n const quickWins = collectQuickWins(report.packages);\n const overallColor = getScoreColorClass(report.overallScore);\n\n return (\n <div className=\"p-6\">\n {/* Header */}\n <div className=\"mb-6\">\n <div className=\"flex items-baseline gap-4 mb-1\">\n <div className={`text-5xl font-bold ${overallColor}`}>{report.overallScore}</div>\n <div className=\"text-gray-400 text-sm\">\n monorepo health · {report.monorepoType} workspaces · {report.packages.length} packages\n </div>\n </div>\n <div className=\"flex gap-4 text-sm\">\n <span className=\"text-red-400\">{report.summary.critical} critical</span>\n <span className=\"text-yellow-400\">{report.summary.warnings} warnings</span>\n <span className=\"text-gray-500\">{report.summary.info} info</span>\n </div>\n </div>\n\n {/* Package scoreboard */}\n <div className=\"mb-8\">\n <h2 className=\"text-xs text-gray-500 font-mono uppercase tracking-wider mb-3\">packages</h2>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\">\n {report.packages.map((pkg, i) => (\n <PackageScoreCard\n key={pkg.path}\n pkg={pkg}\n index={i}\n onClick={() => onSelectPackage(i)}\n />\n ))}\n </div>\n </div>\n\n {/* Quick wins across all packages */}\n {quickWins.length > 0 && (\n <div>\n <h2 className=\"text-xs text-gray-500 font-mono uppercase tracking-wider mb-3\">\n cross-package quick wins\n </h2>\n <div className=\"space-y-2\">\n {quickWins.map((win) => (\n <div\n key={`${win.pkg}-${win.message}`}\n className=\"flex flex-col gap-0.5 p-3 rounded-sm border border-border bg-surface\"\n >\n <div className=\"flex items-start gap-2\">\n <span className=\"text-red-400 text-xs font-mono shrink-0\">●</span>\n <div>\n <span className=\"text-sm text-gray-300\">{win.message}</span>\n <span className=\"text-xs text-gray-500 ml-2\">({win.pkg})</span>\n </div>\n </div>\n {win.command && (\n <code className=\"text-xs text-green-400 font-mono ml-4 mt-0.5 block\">\n $ {win.command}\n </code>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var e={security:.3,dependencies:.25,"code-quality":.25,performance:.15,git:.05};export{e as t};
2
+ //# sourceMappingURL=constants-DYzuOu1F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-DYzuOu1F.js","names":["WARN_LINES","CRITICAL_LINES","SCORE_GOOD","SCORE_FAIR","DEFAULT_WEIGHTS","Record","security","dependencies","performance","git"],"sources":["../../src/lib/constants.ts"],"sourcesContent":["// Duplicated from sickbay-core/constants to avoid pulling Node.js\n// dependencies into the browser bundle. Keep in sync with core.\n\n// File complexity thresholds\nexport const WARN_LINES = 400;\nexport const CRITICAL_LINES = 600;\n\n// Score thresholds\nexport const SCORE_GOOD = 80;\nexport const SCORE_FAIR = 60;\n\n// Default category weights — duplicated from core to avoid Node.js imports\nexport const DEFAULT_WEIGHTS: Record<string, number> = {\n security: 0.3,\n dependencies: 0.25,\n 'code-quality': 0.25,\n performance: 0.15,\n git: 0.05,\n};\n"],"mappings":"AAYA,IAAaI,EAA0C,CACrDE,SAAU,GACVC,aAAc,IACd,eAAgB,IAChBC,YAAa,IACbC,IAAK,IACN"}