sickbay 1.15.6 → 1.15.8
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/{DiffApp-UCBWNYDV.js → DiffApp-ECF2VINH.js} +2 -2
- package/dist/{DoctorApp-SUPQ73LO.js → DoctorApp-OPZBSIE6.js} +3 -3
- package/dist/{FixApp-DUD426JB.js → FixApp-TMRUKUJD.js} +3 -3
- package/dist/{StatsApp-X2Y7LMG5.js → StatsApp-LXJWX24A.js} +3 -3
- package/dist/{TrendApp-CYONZAVG.js → TrendApp-B7UGRJGC.js} +3 -3
- package/dist/{TuiApp-NQGIS2T6.js → TuiApp-P5ESVGCB.js} +24 -8
- package/dist/{chunk-XSQZTZWJ.js → chunk-7Z6JB75D.js} +7 -6
- package/dist/{chunk-L7KHKFWR.js → chunk-O3BKUV2D.js} +1 -1
- package/dist/{chunk-UFTUJIJ2.js → chunk-Q6CVOYTA.js} +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/{dist-YK4FYTB4.js → dist-LK2SSQPX.js} +1 -1
- package/dist/index.js +38 -25
- package/dist/{init-FA6F4WTV.js → init-5A3DUVIL.js} +1 -1
- package/dist/{resolve-package-4UT4RYHY.js → resolve-package-MCBFGKN5.js} +2 -2
- package/dist/web/assets/{ChatDrawer-Dqewz3Yz.js → ChatDrawer-dCdqFiGs.js} +2 -2
- package/dist/web/assets/ChatDrawer-dCdqFiGs.js.map +1 -0
- package/dist/web/assets/{DependencyGraph-DS5sXNvY.js → DependencyGraph-BSJPytrP.js} +2 -2
- package/dist/web/assets/{DependencyGraph-DS5sXNvY.js.map → DependencyGraph-BSJPytrP.js.map} +1 -1
- package/dist/web/assets/{MonorepoOverview-vTq9TL11.js → MonorepoOverview-DDbHHZi0.js} +2 -2
- package/dist/web/assets/MonorepoOverview-DDbHHZi0.js.map +1 -0
- package/dist/web/assets/constants-DYzuOu1F.js +2 -0
- package/dist/web/assets/constants-DYzuOu1F.js.map +1 -0
- package/dist/web/assets/graph-viz-7--E40m7.js +2 -0
- package/dist/web/assets/{graph-viz-Ls9Hbzox.js.map → graph-viz-7--E40m7.js.map} +1 -1
- package/dist/web/assets/index-DeUgBZv8.js +16 -0
- package/dist/web/assets/index-DeUgBZv8.js.map +1 -0
- package/dist/web/assets/{markdown-BkROfETq.js → markdown-oPAUxr3B.js} +8 -8
- package/dist/web/assets/{markdown-BkROfETq.js.map → markdown-oPAUxr3B.js.map} +1 -1
- package/dist/web/assets/react-DeNSbYyc.js +16 -0
- package/dist/web/assets/{react-BEi4PGB1.js.map → react-DeNSbYyc.js.map} +1 -1
- package/dist/web/index.html +4 -3
- package/dist/{web-TCEOS752.js → web-H2AR7HV5.js} +46 -12
- package/package.json +5 -5
- package/dist/web/assets/ChatDrawer-Dqewz3Yz.js.map +0 -1
- package/dist/web/assets/MonorepoOverview-vTq9TL11.js.map +0 -1
- package/dist/web/assets/graph-viz-Ls9Hbzox.js +0 -2
- package/dist/web/assets/index-B_XNCPiK.js +0 -16
- package/dist/web/assets/index-B_XNCPiK.js.map +0 -1
- package/dist/web/assets/react-BEi4PGB1.js +0 -16
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Header
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
4
4
|
|
|
5
5
|
// src/components/DiffApp.tsx
|
|
6
6
|
import React, { useState, useEffect } from "react";
|
|
@@ -119,7 +119,7 @@ function DiffApp({ projectPath, branch, jsonOutput, checks, verbose }) {
|
|
|
119
119
|
useEffect(() => {
|
|
120
120
|
(async () => {
|
|
121
121
|
try {
|
|
122
|
-
const { runSickbay } = await import("./dist-
|
|
122
|
+
const { runSickbay } = await import("./dist-LK2SSQPX.js");
|
|
123
123
|
const currentReport = await runSickbay({
|
|
124
124
|
projectPath,
|
|
125
125
|
checks,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3BKUV2D.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
7
7
|
import {
|
|
8
8
|
detectPackageManager,
|
|
9
9
|
detectProject
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7Z6JB75D.js";
|
|
11
11
|
|
|
12
12
|
// src/components/DoctorApp.tsx
|
|
13
13
|
import React, { useState, useEffect } from "react";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3BKUV2D.js";
|
|
4
4
|
import {
|
|
5
5
|
ProgressList
|
|
6
6
|
} from "./chunk-MBVA75EM.js";
|
|
7
7
|
import {
|
|
8
8
|
Header
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
10
10
|
import {
|
|
11
11
|
runSickbay
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7Z6JB75D.js";
|
|
13
13
|
|
|
14
14
|
// src/components/FixApp.tsx
|
|
15
15
|
import React, { useState, useEffect, useCallback } from "react";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shortName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3BKUV2D.js";
|
|
4
4
|
import {
|
|
5
5
|
Header
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
7
7
|
import {
|
|
8
8
|
detectProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7Z6JB75D.js";
|
|
10
10
|
|
|
11
11
|
// src/components/StatsApp.tsx
|
|
12
12
|
import React, { useState, useEffect } from "react";
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-SHO3ZXTH.js";
|
|
5
5
|
import {
|
|
6
6
|
shortName
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-O3BKUV2D.js";
|
|
8
8
|
import {
|
|
9
9
|
Header
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
11
|
+
import "./chunk-7Z6JB75D.js";
|
|
12
12
|
import {
|
|
13
13
|
detectRegressions,
|
|
14
14
|
loadHistory
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
detectMonorepo,
|
|
15
15
|
runSickbay,
|
|
16
16
|
runSickbayMonorepo
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7Z6JB75D.js";
|
|
18
18
|
import {
|
|
19
19
|
loadHistory
|
|
20
20
|
} from "./chunk-3OR2GFVE.js";
|
|
@@ -99,11 +99,17 @@ function useGitStatus(projectPath, pollInterval = 1e4) {
|
|
|
99
99
|
const [status, setStatus] = useState(null);
|
|
100
100
|
const intervalRef = useRef(void 0);
|
|
101
101
|
useEffect(() => {
|
|
102
|
-
|
|
102
|
+
let mounted = true;
|
|
103
|
+
fetchGitStatus(projectPath).then((s) => {
|
|
104
|
+
if (mounted) setStatus(s);
|
|
105
|
+
});
|
|
103
106
|
intervalRef.current = setInterval(() => {
|
|
104
|
-
fetchGitStatus(projectPath).then(
|
|
107
|
+
fetchGitStatus(projectPath).then((s) => {
|
|
108
|
+
if (mounted) setStatus(s);
|
|
109
|
+
});
|
|
105
110
|
}, pollInterval);
|
|
106
111
|
return () => {
|
|
112
|
+
mounted = false;
|
|
107
113
|
if (intervalRef.current) clearInterval(intervalRef.current);
|
|
108
114
|
};
|
|
109
115
|
}, [projectPath, pollInterval]);
|
|
@@ -237,6 +243,8 @@ function useFileWatcher({
|
|
|
237
243
|
const debounceRef = useRef2(void 0);
|
|
238
244
|
const pendingRef = useRef2([]);
|
|
239
245
|
const watcherRef = useRef2(null);
|
|
246
|
+
const onFilesChangedRef = useRef2(onFilesChanged);
|
|
247
|
+
onFilesChangedRef.current = onFilesChanged;
|
|
240
248
|
useEffect3(() => {
|
|
241
249
|
if (!enabled) return;
|
|
242
250
|
let mounted = true;
|
|
@@ -266,7 +274,7 @@ function useFileWatcher({
|
|
|
266
274
|
debounceRef.current = setTimeout(() => {
|
|
267
275
|
const files = [...pendingRef.current];
|
|
268
276
|
pendingRef.current = [];
|
|
269
|
-
|
|
277
|
+
onFilesChangedRef.current?.(files);
|
|
270
278
|
}, debounceMs);
|
|
271
279
|
});
|
|
272
280
|
} catch {
|
|
@@ -332,7 +340,15 @@ function useSickbayRunner({ projectPath, checks, quotes }) {
|
|
|
332
340
|
const result2 = await runSickbayMonorepo({
|
|
333
341
|
projectPath,
|
|
334
342
|
checks,
|
|
335
|
-
quotes
|
|
343
|
+
quotes,
|
|
344
|
+
onPackageStart: (name) => {
|
|
345
|
+
setProgress((prev) => [...prev, { name, status: "running" }]);
|
|
346
|
+
},
|
|
347
|
+
onPackageComplete: (pkg) => {
|
|
348
|
+
setProgress(
|
|
349
|
+
(prev) => prev.map((p) => p.name === pkg.name ? { ...p, status: "done" } : p)
|
|
350
|
+
);
|
|
351
|
+
}
|
|
336
352
|
});
|
|
337
353
|
setMonorepoReport(result2);
|
|
338
354
|
const rolledUp = rollUpMonorepoReport(result2);
|
|
@@ -689,7 +705,7 @@ function TuiApp({
|
|
|
689
705
|
return () => timers.forEach(clearTimeout);
|
|
690
706
|
}, []);
|
|
691
707
|
useEffect7(() => {
|
|
692
|
-
checkForUpdate("1.15.
|
|
708
|
+
checkForUpdate("1.15.7").then((info) => {
|
|
693
709
|
if (info) setUpdateInfo(info);
|
|
694
710
|
});
|
|
695
711
|
}, []);
|
|
@@ -715,7 +731,7 @@ function TuiApp({
|
|
|
715
731
|
} catch {
|
|
716
732
|
}
|
|
717
733
|
try {
|
|
718
|
-
const { getDependencyTree } = await import("./dist-
|
|
734
|
+
const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
|
|
719
735
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
720
736
|
const tree = await getDependencyTree(projectPath, result.projectInfo.packageManager);
|
|
721
737
|
saveDepTree(projectPath, tree);
|
|
@@ -819,7 +835,7 @@ function TuiApp({
|
|
|
819
835
|
const webReport = monorepoReportRef.current ?? reportRef.current;
|
|
820
836
|
if (!webReport) return;
|
|
821
837
|
try {
|
|
822
|
-
const { serveWeb } = await import("./web-
|
|
838
|
+
const { serveWeb } = await import("./web-H2AR7HV5.js");
|
|
823
839
|
const { default: openBrowser } = await import("open");
|
|
824
840
|
let aiService;
|
|
825
841
|
if (withAI && process.env.ANTHROPIC_API_KEY && !monorepoReportRef.current) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ../../packages/core/dist/index.js
|
|
2
2
|
import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
|
|
3
|
-
import { basename as basename3, join as join38
|
|
3
|
+
import { basename as basename3, join as join38 } from "path";
|
|
4
4
|
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
5
5
|
import { join, extname } from "path";
|
|
6
6
|
import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
|
|
@@ -75,7 +75,7 @@ import { join as join29 } from "path";
|
|
|
75
75
|
import { readFileSync as readFileSync25, existsSync as existsSync20 } from "fs";
|
|
76
76
|
import { join as join30 } from "path";
|
|
77
77
|
import { existsSync as existsSync21 } from "fs";
|
|
78
|
-
import { dirname as dirname4, join as join31
|
|
78
|
+
import { dirname as dirname4, join as join31 } from "path";
|
|
79
79
|
import { execa as execa10 } from "execa";
|
|
80
80
|
import { execa as execa11 } from "execa";
|
|
81
81
|
import { existsSync as existsSync22, readFileSync as readFileSync26, readdirSync as readdirSync16, statSync as statSync15 } from "fs";
|
|
@@ -2362,7 +2362,7 @@ var CoverageRunner = class extends BaseRunner {
|
|
|
2362
2362
|
category: this.category,
|
|
2363
2363
|
name: "Tests & Coverage",
|
|
2364
2364
|
score: Math.round(avg),
|
|
2365
|
-
status: avg >=
|
|
2365
|
+
status: avg >= lineTarget ? "pass" : avg >= 50 ? "warning" : "fail",
|
|
2366
2366
|
issues,
|
|
2367
2367
|
toolsUsed: ["coverage"],
|
|
2368
2368
|
duration: elapsed(),
|
|
@@ -4116,7 +4116,7 @@ function filterPnpmAdvisories(advisories, projectPath) {
|
|
|
4116
4116
|
if (!workspaceRoot || workspaceRoot === projectPath) {
|
|
4117
4117
|
return advisories;
|
|
4118
4118
|
}
|
|
4119
|
-
const importerPrefix =
|
|
4119
|
+
const importerPrefix = relativeFromRoot(workspaceRoot, projectPath).replace(/\//g, "__");
|
|
4120
4120
|
const filtered = {};
|
|
4121
4121
|
for (const [id, advisory] of Object.entries(advisories)) {
|
|
4122
4122
|
const isRelevant = advisory.findings.some(
|
|
@@ -5428,7 +5428,7 @@ async function runSickbayMonorepo(options = {}) {
|
|
|
5428
5428
|
}
|
|
5429
5429
|
const rootConfig = await loadConfig(rootPath);
|
|
5430
5430
|
const configMeta = resolveConfigMeta(rootConfig);
|
|
5431
|
-
const
|
|
5431
|
+
const packageResults = await Promise.allSettled(
|
|
5432
5432
|
monorepoInfo.packagePaths.map(async (pkgPath) => {
|
|
5433
5433
|
const pkgConfig = await loadConfig(pkgPath);
|
|
5434
5434
|
const mergedConfig = mergeConfigs(rootConfig, pkgConfig);
|
|
@@ -5438,7 +5438,7 @@ async function runSickbayMonorepo(options = {}) {
|
|
|
5438
5438
|
const packageReport = {
|
|
5439
5439
|
name: report.projectInfo.name,
|
|
5440
5440
|
path: pkgPath,
|
|
5441
|
-
relativePath:
|
|
5441
|
+
relativePath: relativeFromRoot(rootPath, pkgPath),
|
|
5442
5442
|
framework: report.projectInfo.framework,
|
|
5443
5443
|
runtime: context.runtime,
|
|
5444
5444
|
checks: report.checks,
|
|
@@ -5452,6 +5452,7 @@ async function runSickbayMonorepo(options = {}) {
|
|
|
5452
5452
|
return packageReport;
|
|
5453
5453
|
})
|
|
5454
5454
|
);
|
|
5455
|
+
const packageReports = packageResults.filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
5455
5456
|
const overallScore = packageReports.length > 0 ? Math.round(packageReports.reduce((sum, p) => sum + p.score, 0) / packageReports.length) : 0;
|
|
5456
5457
|
const summary = packageReports.reduce(
|
|
5457
5458
|
(acc, p) => ({
|
|
@@ -11,7 +11,7 @@ var ASCII_ART = `
|
|
|
11
11
|
A vitals health check for your app
|
|
12
12
|
`.trim();
|
|
13
13
|
function Header({ projectName }) {
|
|
14
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.15.
|
|
14
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "green" }, ASCII_ART), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " v", "1.15.7")), 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 '
|
|
1
|
+
export { Category, CheckConfig, SickbayConfig, SuppressionRule, defineConfig } from 'sickbay-core';
|
package/dist/config.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
} from "./chunk-TYG7ZQBP.js";
|
|
9
9
|
import {
|
|
10
10
|
Header
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Q6CVOYTA.js";
|
|
12
12
|
import {
|
|
13
13
|
getScoreEmoji,
|
|
14
14
|
runSickbay,
|
|
15
15
|
runSickbayMonorepo
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-7Z6JB75D.js";
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { existsSync } from "fs";
|
|
@@ -190,7 +190,7 @@ function App({
|
|
|
190
190
|
setMonorepoReport(r);
|
|
191
191
|
setProjectName(`monorepo (${r.packages.length} packages)`);
|
|
192
192
|
try {
|
|
193
|
-
const { getDependencyTree } = await import("./dist-
|
|
193
|
+
const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
|
|
194
194
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
195
195
|
const packages = {};
|
|
196
196
|
for (const pkg of r.packages) {
|
|
@@ -202,7 +202,7 @@ function App({
|
|
|
202
202
|
if (openWeb) {
|
|
203
203
|
setPhase("opening-web");
|
|
204
204
|
try {
|
|
205
|
-
const { serveWeb } = await import("./web-
|
|
205
|
+
const { serveWeb } = await import("./web-H2AR7HV5.js");
|
|
206
206
|
const { default: openBrowser } = await import("open");
|
|
207
207
|
let aiService;
|
|
208
208
|
if (enableAI && process.env.ANTHROPIC_API_KEY) {
|
|
@@ -259,7 +259,7 @@ function App({
|
|
|
259
259
|
} catch {
|
|
260
260
|
}
|
|
261
261
|
try {
|
|
262
|
-
const { getDependencyTree } = await import("./dist-
|
|
262
|
+
const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
|
|
263
263
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
264
264
|
const tree = await getDependencyTree(projectPath, r.projectInfo.packageManager);
|
|
265
265
|
saveDepTree(projectPath, tree);
|
|
@@ -268,7 +268,7 @@ function App({
|
|
|
268
268
|
if (openWeb) {
|
|
269
269
|
setPhase("opening-web");
|
|
270
270
|
try {
|
|
271
|
-
const { serveWeb } = await import("./web-
|
|
271
|
+
const { serveWeb } = await import("./web-H2AR7HV5.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,12 @@ if (existsSync(globalConfigPath)) {
|
|
|
317
317
|
}
|
|
318
318
|
config({ debug: false, quiet: true });
|
|
319
319
|
var program = new Command();
|
|
320
|
-
program.name("sickbay").description("React project health check CLI").version("1.15.
|
|
320
|
+
program.name("sickbay").description("React project health check CLI").version("1.15.7", "-v, --version").enablePositionalOptions().passThroughOptions().option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single named package (monorepo only)").option("--json", "output raw JSON report").option("--web", "open web dashboard after scan").option("--no-ai", "disable AI features").option("--no-quotes", "suppress personality quotes in output").option("--verbose", "show verbose output").action(async (options) => {
|
|
321
|
+
if (!existsSync(options.path)) {
|
|
322
|
+
process.stderr.write(`Error: path does not exist: ${options.path}
|
|
323
|
+
`);
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
321
326
|
if (options.path && options.path !== process.cwd()) {
|
|
322
327
|
const projectEnvPath = join(options.path, ".env");
|
|
323
328
|
if (existsSync(projectEnvPath)) {
|
|
@@ -327,13 +332,21 @@ program.name("sickbay").description("React project health check CLI").version("1
|
|
|
327
332
|
const updatePromise = (async () => {
|
|
328
333
|
try {
|
|
329
334
|
const { checkForUpdate } = await import("./update-check-M7IFOMLJ.js");
|
|
330
|
-
return await checkForUpdate("1.15.
|
|
335
|
+
return await checkForUpdate("1.15.7");
|
|
331
336
|
} catch {
|
|
332
337
|
return null;
|
|
333
338
|
}
|
|
334
339
|
})();
|
|
335
340
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
336
|
-
const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2 } = await import("./dist-
|
|
341
|
+
const { detectMonorepo, runSickbay: runSickbay2, runSickbayMonorepo: runSickbayMonorepo2, getAvailableChecks } = await import("./dist-LK2SSQPX.js");
|
|
342
|
+
if (checks && checks.length > 0) {
|
|
343
|
+
const knownNames = new Set(getAvailableChecks().map((c) => c.name));
|
|
344
|
+
const unknown = checks.filter((c) => !knownNames.has(c));
|
|
345
|
+
if (unknown.length > 0) {
|
|
346
|
+
process.stderr.write(`Warning: unknown check ID(s): ${unknown.join(", ")}
|
|
347
|
+
`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
337
350
|
const monorepoInfo = await detectMonorepo(options.path);
|
|
338
351
|
if (options.package && monorepoInfo.isMonorepo) {
|
|
339
352
|
const { readFileSync } = await import("fs");
|
|
@@ -397,7 +410,7 @@ program.name("sickbay").description("React project health check CLI").version("1
|
|
|
397
410
|
} catch {
|
|
398
411
|
}
|
|
399
412
|
try {
|
|
400
|
-
const { getDependencyTree } = await import("./dist-
|
|
413
|
+
const { getDependencyTree } = await import("./dist-LK2SSQPX.js");
|
|
401
414
|
const { saveDepTree } = await import("./history-XLNVZEDI.js");
|
|
402
415
|
const tree = await getDependencyTree(options.path, report.projectInfo.packageManager);
|
|
403
416
|
saveDepTree(options.path, tree);
|
|
@@ -424,16 +437,16 @@ program.command("init").description("Initialize .sickbay/ folder and run an init
|
|
|
424
437
|
"add newly available checks to existing config without touching existing entries"
|
|
425
438
|
).option("--reset-config", "regenerate config from scratch (overwrites existing)").action(async (options) => {
|
|
426
439
|
if (options.resetConfig) {
|
|
427
|
-
const { generateConfigFile } = await import("./init-
|
|
440
|
+
const { generateConfigFile } = await import("./init-5A3DUVIL.js");
|
|
428
441
|
await generateConfigFile(options.path, { force: true });
|
|
429
442
|
return;
|
|
430
443
|
}
|
|
431
444
|
if (options.sync) {
|
|
432
|
-
const { syncConfigFile } = await import("./init-
|
|
445
|
+
const { syncConfigFile } = await import("./init-5A3DUVIL.js");
|
|
433
446
|
await syncConfigFile(options.path);
|
|
434
447
|
return;
|
|
435
448
|
}
|
|
436
|
-
const { initSickbay } = await import("./init-
|
|
449
|
+
const { initSickbay } = await import("./init-5A3DUVIL.js");
|
|
437
450
|
await initSickbay(options.path);
|
|
438
451
|
});
|
|
439
452
|
program.command("fix").description("Interactively fix issues found by sickbay scan").option("-p, --path <path>", "project path to analyze", process.cwd()).option("-c, --checks <checks>", "comma-separated list of checks to run").option("--package <name>", "scope to a single package (monorepo only)").option("--all", "apply all available fixes without prompting").option("--dry-run", "show what would be fixed without executing").option("--verbose", "show verbose output").action(async (options) => {
|
|
@@ -443,9 +456,9 @@ program.command("fix").description("Interactively fix issues found by sickbay sc
|
|
|
443
456
|
config({ path: projectEnvPath, override: true });
|
|
444
457
|
}
|
|
445
458
|
}
|
|
446
|
-
const { resolveProject } = await import("./resolve-package-
|
|
459
|
+
const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
|
|
447
460
|
const resolution = await resolveProject(options.path, options.package);
|
|
448
|
-
const { FixApp } = await import("./FixApp-
|
|
461
|
+
const { FixApp } = await import("./FixApp-TMRUKUJD.js");
|
|
449
462
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
450
463
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
451
464
|
render(
|
|
@@ -468,10 +481,10 @@ program.command("trend").description("Show score history and trends over time").
|
|
|
468
481
|
config({ path: projectEnvPath, override: true });
|
|
469
482
|
}
|
|
470
483
|
}
|
|
471
|
-
const { resolveProject } = await import("./resolve-package-
|
|
484
|
+
const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
|
|
472
485
|
const resolution = await resolveProject(options.path, options.package);
|
|
473
486
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
474
|
-
const { TrendApp } = await import("./TrendApp-
|
|
487
|
+
const { TrendApp } = await import("./TrendApp-B7UGRJGC.js");
|
|
475
488
|
render(
|
|
476
489
|
React7.createElement(TrendApp, {
|
|
477
490
|
projectPath,
|
|
@@ -490,10 +503,10 @@ program.command("stats").description("Show a quick codebase overview and project
|
|
|
490
503
|
config({ path: projectEnvPath, override: true });
|
|
491
504
|
}
|
|
492
505
|
}
|
|
493
|
-
const { resolveProject } = await import("./resolve-package-
|
|
506
|
+
const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
|
|
494
507
|
const resolution = await resolveProject(options.path, options.package);
|
|
495
508
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
496
|
-
const { StatsApp } = await import("./StatsApp-
|
|
509
|
+
const { StatsApp } = await import("./StatsApp-LXJWX24A.js");
|
|
497
510
|
render(
|
|
498
511
|
React7.createElement(StatsApp, {
|
|
499
512
|
projectPath,
|
|
@@ -505,7 +518,7 @@ program.command("stats").description("Show a quick codebase overview and project
|
|
|
505
518
|
);
|
|
506
519
|
});
|
|
507
520
|
program.command("tui").description("Launch the persistent developer dashboard").option("-p, --path <path>", "project path to monitor", process.cwd()).option("--no-watch", "disable file-watching auto-refresh").option("--no-quotes", "suppress personality quotes in output").option("--refresh <seconds>", "auto-refresh interval in seconds", "300").option("-c, --checks <checks>", "comma-separated list of checks to run").action(async (options) => {
|
|
508
|
-
const { TuiApp } = await import("./TuiApp-
|
|
521
|
+
const { TuiApp } = await import("./TuiApp-P5ESVGCB.js");
|
|
509
522
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
510
523
|
render(
|
|
511
524
|
React7.createElement(TuiApp, {
|
|
@@ -525,10 +538,10 @@ program.command("doctor").description("Diagnose project setup and configuration
|
|
|
525
538
|
config({ path: projectEnvPath, override: true });
|
|
526
539
|
}
|
|
527
540
|
}
|
|
528
|
-
const { resolveProject } = await import("./resolve-package-
|
|
541
|
+
const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
|
|
529
542
|
const resolution = await resolveProject(options.path, options.package);
|
|
530
543
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
531
|
-
const { DoctorApp } = await import("./DoctorApp-
|
|
544
|
+
const { DoctorApp } = await import("./DoctorApp-OPZBSIE6.js");
|
|
532
545
|
render(
|
|
533
546
|
React7.createElement(DoctorApp, {
|
|
534
547
|
projectPath,
|
|
@@ -541,13 +554,13 @@ program.command("doctor").description("Diagnose project setup and configuration
|
|
|
541
554
|
);
|
|
542
555
|
});
|
|
543
556
|
program.command("badge").description("Generate a health score badge for your README").option("-p, --path <path>", "project path", process.cwd()).option("--package <name>", "scope to a single package (monorepo only)").option("--html", "output HTML <img> tag instead of markdown").option("--url", "output bare badge URL only").option("--label <text>", "custom badge label", "sickbay").option("--scan", "run a fresh scan instead of using last report").action(async (options) => {
|
|
544
|
-
const { resolveProject } = await import("./resolve-package-
|
|
557
|
+
const { resolveProject } = await import("./resolve-package-MCBFGKN5.js");
|
|
545
558
|
const resolution = await resolveProject(options.path, options.package);
|
|
546
559
|
const projectPath = resolution.isMonorepo ? resolution.targetPath ?? options.path : resolution.targetPath;
|
|
547
560
|
const { loadScoreFromLastReport, badgeUrl, badgeMarkdown, badgeHtml } = await import("./badge-KQ73KEIN.js");
|
|
548
561
|
let score = options.scan ? null : loadScoreFromLastReport(projectPath);
|
|
549
562
|
if (score === null) {
|
|
550
|
-
const { runSickbay: runSickbay2 } = await import("./dist-
|
|
563
|
+
const { runSickbay: runSickbay2 } = await import("./dist-LK2SSQPX.js");
|
|
551
564
|
const report = await runSickbay2({ projectPath, quotes: false });
|
|
552
565
|
try {
|
|
553
566
|
const { saveEntry, saveLastReport } = await import("./history-XLNVZEDI.js");
|
|
@@ -580,7 +593,7 @@ program.command("diff <branch>").description("Compare health score against anoth
|
|
|
580
593
|
}
|
|
581
594
|
}
|
|
582
595
|
const checks = options.checks ? options.checks.split(",").map((s) => s.trim()) : void 0;
|
|
583
|
-
const { DiffApp } = await import("./DiffApp-
|
|
596
|
+
const { DiffApp } = await import("./DiffApp-ECF2VINH.js");
|
|
584
597
|
render(
|
|
585
598
|
React7.createElement(DiffApp, {
|
|
586
599
|
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-
|
|
2
|
-
//# sourceMappingURL=ChatDrawer-
|
|
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":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{i as t}from"./markdown-
|
|
2
|
-
//# sourceMappingURL=DependencyGraph-
|
|
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
|