@getcodesentinel/codesentinel 1.20.0 → 1.21.0
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Satoshi,Avenir Next,Segoe UI,Helvetica Neue,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 210 33% 98%;--foreground: 222 47% 11%;--card: 0 0% 100%;--card-foreground: 222 47% 11%;--popover: 0 0% 100%;--popover-foreground: 222 47% 11%;--primary: 221 83% 53%;--primary-foreground: 210 40% 98%;--secondary: 210 40% 96%;--secondary-foreground: 222 47% 11%;--muted: 210 40% 96%;--muted-foreground: 215 16% 47%;--accent: 201 94% 94%;--accent-foreground: 222 47% 11%;--destructive: 0 84% 60%;--destructive-foreground: 210 40% 98%;--border: 214 32% 91%;--input: 214 32% 91%;--ring: 221 83% 53%;--radius: 1rem}*{border-color:hsl(var(--border))}body{min-height:100vh;background-color:hsl(var(--background));font-family:Satoshi,Avenir Next,Segoe UI,Helvetica Neue,sans-serif;color:hsl(var(--foreground));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-image:radial-gradient(circle at top left,rgba(59,130,246,.16),transparent 24rem),radial-gradient(circle at top right,rgba(20,184,166,.1),transparent 20rem),linear-gradient(180deg,#ffffffe6,#f8fafc)}#root{min-height:100vh}.absolute{position:absolute}.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-6{margin-top:1.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.min-h-40{min-height:10rem}.min-h-screen{min-height:100vh}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-3\.5{width:.875rem}.w-36{width:9rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[220px\]{min-width:220px}.min-w-\[260px\]{min-width:260px}.min-w-\[320px\]{min-width:320px}.min-w-\[880px\]{min-width:880px}.min-w-\[920px\]{min-width:920px}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.break-words{overflow-wrap:break-word}.rounded-2xl{border-radius:1rem}.rounded-\[28px\]{border-radius:28px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-500\/20{border-color:#f59e0b33}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border) / .5)}.border-border\/60{border-color:hsl(var(--border) / .6)}.border-border\/80{border-color:hsl(var(--border) / .8)}.border-emerald-500\/20{border-color:#10b98133}.border-rose-500\/20{border-color:#f43f5e33}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-background\/70{background-color:hsl(var(--background) / .7)}.bg-background\/80{background-color:hsl(var(--background) / .8)}.bg-border{background-color:hsl(var(--border))}.bg-border\/70{background-color:hsl(var(--border) / .7)}.bg-card\/60{background-color:hsl(var(--card) / .6)}.bg-card\/70{background-color:hsl(var(--card) / .7)}.bg-card\/80{background-color:hsl(var(--card) / .8)}.bg-card\/90{background-color:hsl(var(--card) / .9)}.bg-emerald-500\/10{background-color:#10b9811a}.bg-rose-500\/10{background-color:#f43f5e1a}.bg-secondary{background-color:hsl(var(--secondary))}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-950{--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white\/70{background-color:#ffffffb3}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-sky-500{--tw-gradient-from: #0ea5e9 var(--tw-gradient-from-position);--tw-gradient-to: rgb(14 165 233 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-cyan-500{--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #06b6d4 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-emerald-500{--tw-gradient-to: #10b981 var(--tw-gradient-to-position)}.p-0\.5{padding:.125rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.tracking-\[0\.16em\]{letter-spacing:.16em}.tracking-\[0\.18em\]{letter-spacing:.18em}.tracking-\[0\.28em\]{letter-spacing:.28em}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-rose-700{--tw-text-opacity: 1;color:rgb(190 18 60 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-50{--tw-text-opacity: 1;color:rgb(248 250 252 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-panel{--tw-shadow: 0 20px 50px -32px rgba(15, 23, 42, .35);--tw-shadow-colored: 0 20px 50px -32px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.hover\:bg-muted\/40:hover{background-color:hsl(var(--muted) / .4)}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=open\]\:bg-muted\/50[data-state=open]{background-color:hsl(var(--muted) / .5)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@media(min-width:640px){.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:p-8{padding:2rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-5xl{font-size:3rem;line-height:1}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-\[1\.05fr_0\.95fr\]{grid-template-columns:1.05fr .95fr}.lg\:grid-cols-\[1\.1fr_0\.9fr\]{grid-template-columns:1.1fr .9fr}.lg\:grid-cols-\[1\.3fr_0\.7fr\]{grid-template-columns:1.3fr .7fr}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media(min-width:1280px){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}.\[\&_tr\]\:border-border\/60 tr{border-color:hsl(var(--border) / .6)}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>CodeSentinel Report</title>
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-BarpZIgq.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Vsiw9fTu.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/dist/index.js
CHANGED
|
@@ -1753,6 +1753,7 @@ var analyzeDependencyCandidateFromRegistry = async (input) => {
|
|
|
1753
1753
|
};
|
|
1754
1754
|
|
|
1755
1755
|
// ../reporter/dist/index.js
|
|
1756
|
+
import { basename, posix } from "path";
|
|
1756
1757
|
var SNAPSHOT_SCHEMA_VERSION = "codesentinel.snapshot.v1";
|
|
1757
1758
|
var REPORT_SCHEMA_VERSION = "codesentinel.report.v1";
|
|
1758
1759
|
var RISK_MODEL_VERSION = "deterministic-v1";
|
|
@@ -1914,6 +1915,11 @@ var compareSnapshots = (current, baseline) => {
|
|
|
1914
1915
|
}
|
|
1915
1916
|
};
|
|
1916
1917
|
};
|
|
1918
|
+
var toPosixDirname = (value) => {
|
|
1919
|
+
const normalized = value.replaceAll("\\", "/");
|
|
1920
|
+
const directory = posix.dirname(normalized);
|
|
1921
|
+
return directory === "." ? "root" : directory;
|
|
1922
|
+
};
|
|
1917
1923
|
var findTraceTarget = (snapshot, targetType, targetId) => snapshot.trace?.targets.find(
|
|
1918
1924
|
(target) => target.targetType === targetType && target.targetId === targetId
|
|
1919
1925
|
);
|
|
@@ -1959,14 +1965,27 @@ var suggestedActions = (target) => {
|
|
|
1959
1965
|
}
|
|
1960
1966
|
return [...new Set(actions)].slice(0, 3);
|
|
1961
1967
|
};
|
|
1962
|
-
var
|
|
1968
|
+
var hotspotReason = (factors) => {
|
|
1969
|
+
if (factors.length === 0) {
|
|
1970
|
+
return "Limited trace data available for this hotspot.";
|
|
1971
|
+
}
|
|
1972
|
+
return factors.slice(0, 2).map((factor) => `${factor.label} (${factor.contribution})`).join(" + ");
|
|
1973
|
+
};
|
|
1974
|
+
var hotspotItems = (snapshot) => snapshot.analysis.risk.hotspots.slice(0, 10).map((hotspot, index) => {
|
|
1963
1975
|
const fileScore = snapshot.analysis.risk.fileScores.find((item) => item.file === hotspot.file);
|
|
1976
|
+
const evolutionMetrics = snapshot.analysis.evolution.available ? snapshot.analysis.evolution.files.find((item) => item.filePath === hotspot.file) : void 0;
|
|
1964
1977
|
const traceTarget = findTraceTarget(snapshot, "file", hotspot.file);
|
|
1965
1978
|
const factors = toRenderedFactors(traceTarget);
|
|
1966
1979
|
return {
|
|
1980
|
+
rank: index + 1,
|
|
1967
1981
|
target: hotspot.file,
|
|
1982
|
+
module: toPosixDirname(hotspot.file),
|
|
1968
1983
|
score: hotspot.score,
|
|
1969
1984
|
normalizedScore: fileScore?.normalizedScore ?? round43(hotspot.score / 100),
|
|
1985
|
+
commitCount: evolutionMetrics?.commitCount ?? null,
|
|
1986
|
+
churnTotal: evolutionMetrics?.churnTotal ?? null,
|
|
1987
|
+
riskContributions: hotspot.factors,
|
|
1988
|
+
reason: hotspotReason(factors),
|
|
1970
1989
|
topFactors: factors,
|
|
1971
1990
|
suggestedActions: suggestedActions(traceTarget),
|
|
1972
1991
|
biggestLevers: (traceTarget?.reductionLevers ?? []).slice(0, 3).map((lever) => `${factorLabel(lever.factorId)} (${lever.estimatedImpact})`)
|
|
@@ -1987,6 +2006,51 @@ var repositoryConfidence = (snapshot) => {
|
|
|
1987
2006
|
);
|
|
1988
2007
|
return round43(weighted / weight);
|
|
1989
2008
|
};
|
|
2009
|
+
var normalizeDependencyScope = (scope) => {
|
|
2010
|
+
switch (scope) {
|
|
2011
|
+
case "prod":
|
|
2012
|
+
case "dev":
|
|
2013
|
+
return scope;
|
|
2014
|
+
default:
|
|
2015
|
+
return "unknown";
|
|
2016
|
+
}
|
|
2017
|
+
};
|
|
2018
|
+
var topStructuralFiles = (snapshot, selector) => [...snapshot.analysis.structural.files].sort((a, b) => selector(b) - selector(a) || a.relativePath.localeCompare(b.relativePath)).slice(0, 5).map((file) => ({
|
|
2019
|
+
file: file.relativePath,
|
|
2020
|
+
module: toPosixDirname(file.relativePath),
|
|
2021
|
+
value: selector(file)
|
|
2022
|
+
}));
|
|
2023
|
+
var cycleDetails = (snapshot) => snapshot.analysis.structural.cycles.map((cycle, index) => {
|
|
2024
|
+
const nodes = [...cycle.nodes].sort((a, b) => a.localeCompare(b));
|
|
2025
|
+
return {
|
|
2026
|
+
id: `cycle-${index + 1}`,
|
|
2027
|
+
size: nodes.length,
|
|
2028
|
+
nodes,
|
|
2029
|
+
path: nodes.join(" -> ")
|
|
2030
|
+
};
|
|
2031
|
+
});
|
|
2032
|
+
var riskyDependencies = (snapshot) => {
|
|
2033
|
+
if (!snapshot.analysis.external.available) {
|
|
2034
|
+
return [];
|
|
2035
|
+
}
|
|
2036
|
+
const dependencyByName = new Map(
|
|
2037
|
+
snapshot.analysis.external.dependencies.map((dependency) => [dependency.name, dependency])
|
|
2038
|
+
);
|
|
2039
|
+
return snapshot.analysis.risk.dependencyScores.map((score) => {
|
|
2040
|
+
const dependency = dependencyByName.get(score.dependency);
|
|
2041
|
+
const riskSignals = [.../* @__PURE__ */ new Set([...score.ownRiskSignals, ...score.inheritedRiskSignals])];
|
|
2042
|
+
return {
|
|
2043
|
+
name: score.dependency,
|
|
2044
|
+
score: score.score,
|
|
2045
|
+
normalizedScore: score.normalizedScore,
|
|
2046
|
+
dependencyScope: normalizeDependencyScope(dependency?.dependencyScope),
|
|
2047
|
+
direct: dependency?.direct ?? false,
|
|
2048
|
+
resolvedVersion: dependency?.resolvedVersion ?? null,
|
|
2049
|
+
riskSignals,
|
|
2050
|
+
reason: riskSignals.length === 0 ? "Derived from aggregate dependency risk signals." : riskSignals.join(", ")
|
|
2051
|
+
};
|
|
2052
|
+
}).filter((dependency) => dependency.score > 0).sort((a, b) => b.score - a.score || a.name.localeCompare(b.name)).slice(0, 20);
|
|
2053
|
+
};
|
|
1990
2054
|
var repositoryDimensionScores = (snapshot) => {
|
|
1991
2055
|
const target = findTraceTarget(snapshot, "repository", snapshot.analysis.structural.targetPath);
|
|
1992
2056
|
if (target === void 0) {
|
|
@@ -2019,6 +2083,7 @@ var createReport = (snapshot, diff) => {
|
|
|
2019
2083
|
schemaVersion: REPORT_SCHEMA_VERSION,
|
|
2020
2084
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2021
2085
|
repository: {
|
|
2086
|
+
name: basename(snapshot.analysis.structural.targetPath) || snapshot.analysis.structural.targetPath,
|
|
2022
2087
|
targetPath: snapshot.analysis.structural.targetPath,
|
|
2023
2088
|
riskScore: snapshot.analysis.risk.riskScore,
|
|
2024
2089
|
normalizedScore: snapshot.analysis.risk.normalizedScore,
|
|
@@ -2034,6 +2099,12 @@ var createReport = (snapshot, diff) => {
|
|
|
2034
2099
|
cycles: snapshot.analysis.structural.cycles.map(
|
|
2035
2100
|
(cycle) => [...cycle.nodes].sort((a, b) => a.localeCompare(b)).join(" -> ")
|
|
2036
2101
|
),
|
|
2102
|
+
cycleDetails: cycleDetails(snapshot),
|
|
2103
|
+
fanInOutExtremes: {
|
|
2104
|
+
highestFanIn: topStructuralFiles(snapshot, (file) => file.fanIn),
|
|
2105
|
+
highestFanOut: topStructuralFiles(snapshot, (file) => file.fanOut),
|
|
2106
|
+
deepestFiles: topStructuralFiles(snapshot, (file) => file.depth)
|
|
2107
|
+
},
|
|
2037
2108
|
fragileClusters: snapshot.analysis.risk.fragileClusters.map((cluster) => ({
|
|
2038
2109
|
id: cluster.id,
|
|
2039
2110
|
kind: cluster.kind,
|
|
@@ -2057,7 +2128,8 @@ var createReport = (snapshot, diff) => {
|
|
|
2057
2128
|
),
|
|
2058
2129
|
abandonedDependencies: [...external.abandonedDependencies].sort(
|
|
2059
2130
|
(a, b) => a.localeCompare(b)
|
|
2060
|
-
)
|
|
2131
|
+
),
|
|
2132
|
+
riskyDependencies: riskyDependencies(snapshot)
|
|
2061
2133
|
},
|
|
2062
2134
|
appendix: {
|
|
2063
2135
|
snapshotSchemaVersion: snapshot.schemaVersion,
|
|
@@ -2298,7 +2370,7 @@ var formatReport = (report, format) => {
|
|
|
2298
2370
|
|
|
2299
2371
|
// ../governance/dist/index.js
|
|
2300
2372
|
import { mkdirSync, rmSync } from "fs";
|
|
2301
|
-
import { basename, join as join5, resolve } from "path";
|
|
2373
|
+
import { basename as basename2, join as join5, resolve } from "path";
|
|
2302
2374
|
import { execFile } from "child_process";
|
|
2303
2375
|
import { promisify } from "util";
|
|
2304
2376
|
var EXIT_CODES = {
|
|
@@ -2911,9 +2983,9 @@ var resolveAutoBaselineRef = async (input) => {
|
|
|
2911
2983
|
|
|
2912
2984
|
// src/index.ts
|
|
2913
2985
|
import { readFileSync as readFileSync2 } from "fs";
|
|
2914
|
-
import { readFile as
|
|
2915
|
-
import { dirname as
|
|
2916
|
-
import { fileURLToPath } from "url";
|
|
2986
|
+
import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
|
|
2987
|
+
import { dirname as dirname3, resolve as resolve6 } from "path";
|
|
2988
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2917
2989
|
|
|
2918
2990
|
// src/application/format-analyze-output.ts
|
|
2919
2991
|
var toHealthTier2 = (score) => {
|
|
@@ -3558,7 +3630,7 @@ var promptInstall = async (packageName, latestVersion, currentVersion) => {
|
|
|
3558
3630
|
);
|
|
3559
3631
|
return "skip";
|
|
3560
3632
|
}
|
|
3561
|
-
return await new Promise((
|
|
3633
|
+
return await new Promise((resolve7) => {
|
|
3562
3634
|
emitKeypressEvents(stdin);
|
|
3563
3635
|
let selectedIndex = 0;
|
|
3564
3636
|
const previousRawMode = stdin.isRaw;
|
|
@@ -3583,7 +3655,7 @@ var promptInstall = async (packageName, latestVersion, currentVersion) => {
|
|
|
3583
3655
|
} else {
|
|
3584
3656
|
stderr.write("\n");
|
|
3585
3657
|
}
|
|
3586
|
-
|
|
3658
|
+
resolve7(choice);
|
|
3587
3659
|
};
|
|
3588
3660
|
const onKeypress = (_str, key) => {
|
|
3589
3661
|
if (key.ctrl === true && key.name === "c") {
|
|
@@ -3777,7 +3849,7 @@ var promptSelection = async (currentVersion, actions) => {
|
|
|
3777
3849
|
if (!stdin2.isTTY || !stderr2.isTTY || typeof stdin2.setRawMode !== "function") {
|
|
3778
3850
|
return "exit";
|
|
3779
3851
|
}
|
|
3780
|
-
return await new Promise((
|
|
3852
|
+
return await new Promise((resolve7) => {
|
|
3781
3853
|
emitKeypressEvents2(stdin2);
|
|
3782
3854
|
let selectedIndex = 0;
|
|
3783
3855
|
const previousRawMode = stdin2.isRaw;
|
|
@@ -3792,7 +3864,7 @@ var promptSelection = async (currentVersion, actions) => {
|
|
|
3792
3864
|
stdin2.setRawMode(previousRawMode);
|
|
3793
3865
|
clearTerminal();
|
|
3794
3866
|
showCursor2();
|
|
3795
|
-
|
|
3867
|
+
resolve7(selection);
|
|
3796
3868
|
};
|
|
3797
3869
|
const onKeypress = (_str, key) => {
|
|
3798
3870
|
if (key.ctrl === true && key.name === "c") {
|
|
@@ -3885,7 +3957,7 @@ var waitForReturnToMenu = async () => {
|
|
|
3885
3957
|
}
|
|
3886
3958
|
stderr2.write(`
|
|
3887
3959
|
${PROMPT_PADDING}Press enter to return to the menu...`);
|
|
3888
|
-
await new Promise((
|
|
3960
|
+
await new Promise((resolve7) => {
|
|
3889
3961
|
emitKeypressEvents2(stdin2);
|
|
3890
3962
|
const previousRawMode = stdin2.isRaw;
|
|
3891
3963
|
const cleanup = () => {
|
|
@@ -3894,7 +3966,7 @@ ${PROMPT_PADDING}Press enter to return to the menu...`);
|
|
|
3894
3966
|
stdin2.setRawMode(previousRawMode);
|
|
3895
3967
|
showCursor2();
|
|
3896
3968
|
stderr2.write("\n");
|
|
3897
|
-
|
|
3969
|
+
resolve7();
|
|
3898
3970
|
};
|
|
3899
3971
|
const onKeypress = (_str, key) => {
|
|
3900
3972
|
if (key.ctrl === true && key.name === "c") {
|
|
@@ -3912,7 +3984,7 @@ ${PROMPT_PADDING}Press enter to return to the menu...`);
|
|
|
3912
3984
|
});
|
|
3913
3985
|
};
|
|
3914
3986
|
var runCliCommand = async (scriptPath2, args) => {
|
|
3915
|
-
return await new Promise((
|
|
3987
|
+
return await new Promise((resolve7, reject) => {
|
|
3916
3988
|
const child = spawn2(process.execPath, [...process.execArgv, scriptPath2, ...args], {
|
|
3917
3989
|
stdio: ["inherit", "pipe", "pipe"],
|
|
3918
3990
|
env: {
|
|
@@ -3926,7 +3998,7 @@ var runCliCommand = async (scriptPath2, args) => {
|
|
|
3926
3998
|
reject(error);
|
|
3927
3999
|
});
|
|
3928
4000
|
child.on("close", (code) => {
|
|
3929
|
-
|
|
4001
|
+
resolve7(code ?? 1);
|
|
3930
4002
|
});
|
|
3931
4003
|
});
|
|
3932
4004
|
};
|
|
@@ -7640,7 +7712,114 @@ ${ciMarkdown}`;
|
|
|
7640
7712
|
};
|
|
7641
7713
|
|
|
7642
7714
|
// src/application/run-report-command.ts
|
|
7643
|
-
import {
|
|
7715
|
+
import { join as join8 } from "path";
|
|
7716
|
+
import { readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
|
|
7717
|
+
|
|
7718
|
+
// src/application/html-report.ts
|
|
7719
|
+
import { mkdir as mkdir3, readFile as readFile5, rm, stat as stat2, writeFile as writeFile5 } from "fs/promises";
|
|
7720
|
+
import { dirname as dirname2, join as join7, resolve as resolve5 } from "path";
|
|
7721
|
+
import { fileURLToPath } from "url";
|
|
7722
|
+
var HTML_REPORT_DIR = ".codesentinel/report";
|
|
7723
|
+
var getBundledHtmlAppPath = () => resolve5(dirname2(fileURLToPath(import.meta.url)), "html-report-app");
|
|
7724
|
+
var serializeReportBootstrap = (report) => `window.__CODESENTINEL_REPORT__ = ${JSON.stringify(report).replaceAll("</", "<\\/")};
|
|
7725
|
+
`;
|
|
7726
|
+
var escapeInlineScript = (script) => script.replaceAll("</script", "<\\/script").replaceAll("<script", "\\x3Cscript").replaceAll("<!--", "\\x3C!--").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
|
|
7727
|
+
var ensureDirectory = async (directoryPath) => {
|
|
7728
|
+
await mkdir3(directoryPath, { recursive: true });
|
|
7729
|
+
};
|
|
7730
|
+
var readReferencedAssets = async (appPath, indexHtml) => {
|
|
7731
|
+
const stylesheetPaths = [
|
|
7732
|
+
...indexHtml.matchAll(/<link[^>]+rel=["']stylesheet["'][^>]+href=["']([^"']+)["'][^>]*>/g)
|
|
7733
|
+
].map((match) => match[1]).filter((value) => value !== void 0);
|
|
7734
|
+
const styles = await Promise.all(
|
|
7735
|
+
stylesheetPaths.map(async (href) => readFile5(resolve5(appPath, href), "utf8"))
|
|
7736
|
+
);
|
|
7737
|
+
const scriptPaths = [...indexHtml.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*><\/script>/g)].map((match) => match[1]).filter((value) => value !== void 0);
|
|
7738
|
+
const scripts = await Promise.all(
|
|
7739
|
+
scriptPaths.map(async (src) => readFile5(resolve5(appPath, src), "utf8"))
|
|
7740
|
+
);
|
|
7741
|
+
return { styles, scripts };
|
|
7742
|
+
};
|
|
7743
|
+
var inlineBuiltHtml = async (appPath, report) => {
|
|
7744
|
+
const indexHtml = await readFile5(resolve5(appPath, "index.html"), "utf8");
|
|
7745
|
+
const { styles, scripts } = await readReferencedAssets(appPath, indexHtml);
|
|
7746
|
+
const htmlWithoutExternalAssets = indexHtml.replace(/\s*<link[^>]+rel=["']stylesheet["'][^>]*>\s*/g, "").replace(/\s*<script[^>]+src=["'][^"']+["'][^>]*><\/script>\s*/g, "");
|
|
7747
|
+
const inlineStyles = styles.map((style) => `<style>
|
|
7748
|
+
${style}
|
|
7749
|
+
</style>`).join("\n");
|
|
7750
|
+
const bootstrapScript = `<script>
|
|
7751
|
+
${serializeReportBootstrap(report)}</script>`;
|
|
7752
|
+
const inlineScripts = scripts.map((script) => `<script>
|
|
7753
|
+
${escapeInlineScript(script)}
|
|
7754
|
+
</script>`).join("\n");
|
|
7755
|
+
return htmlWithoutExternalAssets.replace("</head>", () => `${inlineStyles === "" ? "" : `${inlineStyles}
|
|
7756
|
+
`}</head>`).replace(
|
|
7757
|
+
"</body>",
|
|
7758
|
+
() => `${bootstrapScript}
|
|
7759
|
+
${inlineScripts === "" ? "" : `${inlineScripts}
|
|
7760
|
+
`}</body>`
|
|
7761
|
+
);
|
|
7762
|
+
};
|
|
7763
|
+
var assertHtmlAppAssets = async (assetPath) => {
|
|
7764
|
+
const assetStats = await stat2(assetPath).catch(() => void 0);
|
|
7765
|
+
if (assetStats === void 0 || !assetStats.isDirectory()) {
|
|
7766
|
+
throw new Error(
|
|
7767
|
+
`html_report_assets_missing: expected built app at ${assetPath}. Run the workspace build first.`
|
|
7768
|
+
);
|
|
7769
|
+
}
|
|
7770
|
+
};
|
|
7771
|
+
var resolveHtmlReportOutputPath = (repositoryPath, outputPath) => {
|
|
7772
|
+
const invocationCwd = process.env["INIT_CWD"] ?? process.cwd();
|
|
7773
|
+
return resolve5(invocationCwd, outputPath ?? join7(repositoryPath, HTML_REPORT_DIR));
|
|
7774
|
+
};
|
|
7775
|
+
var writeHtmlReportBundle = async (report, options) => {
|
|
7776
|
+
const bundledAppPath = options.bundledAppPath ?? getBundledHtmlAppPath();
|
|
7777
|
+
await assertHtmlAppAssets(bundledAppPath);
|
|
7778
|
+
const outputPath = resolveHtmlReportOutputPath(options.repositoryPath, options.outputPath);
|
|
7779
|
+
await rm(outputPath, { recursive: true, force: true });
|
|
7780
|
+
await ensureDirectory(outputPath);
|
|
7781
|
+
await writeFile5(
|
|
7782
|
+
resolve5(outputPath, "index.html"),
|
|
7783
|
+
await inlineBuiltHtml(bundledAppPath, report),
|
|
7784
|
+
"utf8"
|
|
7785
|
+
);
|
|
7786
|
+
return outputPath;
|
|
7787
|
+
};
|
|
7788
|
+
|
|
7789
|
+
// src/application/open-path.ts
|
|
7790
|
+
import { spawn as spawn3 } from "child_process";
|
|
7791
|
+
import { platform } from "os";
|
|
7792
|
+
var openCommandForPlatform = (targetPath) => {
|
|
7793
|
+
switch (platform()) {
|
|
7794
|
+
case "darwin":
|
|
7795
|
+
return { command: "open", args: [targetPath] };
|
|
7796
|
+
case "win32":
|
|
7797
|
+
return { command: "cmd", args: ["/c", "start", "", targetPath] };
|
|
7798
|
+
case "linux":
|
|
7799
|
+
return { command: "xdg-open", args: [targetPath] };
|
|
7800
|
+
default:
|
|
7801
|
+
return void 0;
|
|
7802
|
+
}
|
|
7803
|
+
};
|
|
7804
|
+
var openPath = async (targetPath) => {
|
|
7805
|
+
const command = openCommandForPlatform(targetPath);
|
|
7806
|
+
if (command === void 0) {
|
|
7807
|
+
return false;
|
|
7808
|
+
}
|
|
7809
|
+
return new Promise((resolve7) => {
|
|
7810
|
+
const child = spawn3(command.command, command.args, {
|
|
7811
|
+
detached: true,
|
|
7812
|
+
stdio: "ignore"
|
|
7813
|
+
});
|
|
7814
|
+
child.once("error", () => resolve7(false));
|
|
7815
|
+
child.once("spawn", () => {
|
|
7816
|
+
child.unref();
|
|
7817
|
+
resolve7(true);
|
|
7818
|
+
});
|
|
7819
|
+
});
|
|
7820
|
+
};
|
|
7821
|
+
|
|
7822
|
+
// src/application/run-report-command.ts
|
|
7644
7823
|
var runReportCommand = async (inputPath, authorIdentityMode, options, logger = createSilentLogger()) => {
|
|
7645
7824
|
logger.info("building analysis snapshot");
|
|
7646
7825
|
const current = await buildAnalysisSnapshot(
|
|
@@ -7654,7 +7833,7 @@ var runReportCommand = async (inputPath, authorIdentityMode, options, logger = c
|
|
|
7654
7833
|
logger
|
|
7655
7834
|
);
|
|
7656
7835
|
if (options.snapshotPath !== void 0) {
|
|
7657
|
-
await
|
|
7836
|
+
await writeFile6(options.snapshotPath, JSON.stringify(current, null, 2), "utf8");
|
|
7658
7837
|
logger.info(`snapshot written: ${options.snapshotPath}`);
|
|
7659
7838
|
}
|
|
7660
7839
|
let report;
|
|
@@ -7662,17 +7841,39 @@ var runReportCommand = async (inputPath, authorIdentityMode, options, logger = c
|
|
|
7662
7841
|
report = createReport(current);
|
|
7663
7842
|
} else {
|
|
7664
7843
|
logger.info(`loading baseline snapshot: ${options.comparePath}`);
|
|
7665
|
-
const baselineRaw = await
|
|
7844
|
+
const baselineRaw = await readFile6(options.comparePath, "utf8");
|
|
7666
7845
|
const baseline = parseSnapshot(baselineRaw);
|
|
7667
7846
|
const diff = compareSnapshots(current, baseline);
|
|
7668
7847
|
report = createReport(current, diff);
|
|
7669
7848
|
}
|
|
7849
|
+
if (options.format === "html") {
|
|
7850
|
+
const bundlePath = await writeHtmlReportBundle(report, {
|
|
7851
|
+
repositoryPath: current.analysis.structural.targetPath,
|
|
7852
|
+
...options.outputPath === void 0 ? {} : { outputPath: options.outputPath }
|
|
7853
|
+
});
|
|
7854
|
+
if (options.open === true) {
|
|
7855
|
+
const opened = await openPath(join8(bundlePath, "index.html"));
|
|
7856
|
+
if (!opened) {
|
|
7857
|
+
logger.warn("unable to open html report automatically on this platform");
|
|
7858
|
+
}
|
|
7859
|
+
}
|
|
7860
|
+
logger.info(`html report written: ${bundlePath}`);
|
|
7861
|
+
return {
|
|
7862
|
+
report,
|
|
7863
|
+
rendered: bundlePath,
|
|
7864
|
+
outputPath: bundlePath
|
|
7865
|
+
};
|
|
7866
|
+
}
|
|
7670
7867
|
const rendered = formatReport(report, options.format);
|
|
7671
7868
|
if (options.outputPath !== void 0) {
|
|
7672
|
-
await
|
|
7869
|
+
await writeFile6(options.outputPath, rendered, "utf8");
|
|
7673
7870
|
logger.info(`report written: ${options.outputPath}`);
|
|
7674
7871
|
}
|
|
7675
|
-
return {
|
|
7872
|
+
return {
|
|
7873
|
+
report,
|
|
7874
|
+
rendered,
|
|
7875
|
+
...options.outputPath === void 0 ? {} : { outputPath: options.outputPath }
|
|
7876
|
+
};
|
|
7676
7877
|
};
|
|
7677
7878
|
|
|
7678
7879
|
// src/application/run-explain-command.ts
|
|
@@ -7742,7 +7943,7 @@ var runExplainCommand = async (inputPath, authorIdentityMode, options, logger =
|
|
|
7742
7943
|
|
|
7743
7944
|
// src/index.ts
|
|
7744
7945
|
var program = new Command();
|
|
7745
|
-
var packageJsonPath =
|
|
7946
|
+
var packageJsonPath = resolve6(dirname3(fileURLToPath2(import.meta.url)), "../package.json");
|
|
7746
7947
|
var { version } = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
7747
7948
|
var parseRecentWindowDays = (value) => {
|
|
7748
7949
|
const parsed = Number.parseInt(value, 10);
|
|
@@ -7988,8 +8189,8 @@ program.command("report").argument("[path]", "path to the project to analyze").a
|
|
|
7988
8189
|
"log verbosity: silent, error, warn, info, debug (logs are written to stderr)"
|
|
7989
8190
|
).choices(["silent", "error", "warn", "info", "debug"]).default(parseLogLevel(process.env["CODESENTINEL_LOG_LEVEL"]))
|
|
7990
8191
|
).addOption(
|
|
7991
|
-
new Option("--format <mode>", "output format: text, json, md").choices(["text", "json", "md"]).default("md")
|
|
7992
|
-
).option("--output <path>", "write rendered report to a file path").option("--compare <baseline>", "compare against a baseline snapshot JSON file").option("--snapshot <path>", "write current snapshot JSON artifact").option("--no-trace", "disable trace embedding in generated snapshot").addOption(
|
|
8192
|
+
new Option("--format <mode>", "output format: text, json, md, html").choices(["text", "json", "md", "html"]).default("md")
|
|
8193
|
+
).option("--output <path>", "write rendered report to a file path").option("--open", "open the generated HTML report in the default browser").option("--compare <baseline>", "compare against a baseline snapshot JSON file").option("--snapshot <path>", "write current snapshot JSON artifact").option("--no-trace", "disable trace embedding in generated snapshot").addOption(
|
|
7993
8194
|
new Option(
|
|
7994
8195
|
"--recent-window-days <days>",
|
|
7995
8196
|
"git recency window in days used for evolution volatility metrics"
|
|
@@ -8005,14 +8206,20 @@ program.command("report").argument("[path]", "path to the project to analyze").a
|
|
|
8005
8206
|
...options.output === void 0 ? {} : { outputPath: options.output },
|
|
8006
8207
|
...options.compare === void 0 ? {} : { comparePath: options.compare },
|
|
8007
8208
|
...options.snapshot === void 0 ? {} : { snapshotPath: options.snapshot },
|
|
8209
|
+
...options.open === void 0 ? {} : { open: options.open },
|
|
8008
8210
|
includeTrace: options.trace,
|
|
8009
8211
|
scoringProfile: options.scoringProfile,
|
|
8010
8212
|
recentWindowDays: options.recentWindowDays
|
|
8011
8213
|
},
|
|
8012
8214
|
logger
|
|
8013
8215
|
);
|
|
8014
|
-
if (options.output === void 0) {
|
|
8216
|
+
if (options.output === void 0 && options.format !== "html") {
|
|
8015
8217
|
process.stdout.write(`${result.rendered}
|
|
8218
|
+
`);
|
|
8219
|
+
return;
|
|
8220
|
+
}
|
|
8221
|
+
if (options.format === "html") {
|
|
8222
|
+
process.stdout.write(`${result.outputPath ?? result.rendered}
|
|
8016
8223
|
`);
|
|
8017
8224
|
}
|
|
8018
8225
|
}
|
|
@@ -8031,7 +8238,9 @@ program.command("run").argument("[path]", "path to the project to analyze").addO
|
|
|
8031
8238
|
new Option("--format <mode>", "combined output format: text, md, json").choices(["text", "md", "json"]).default("md")
|
|
8032
8239
|
).addOption(
|
|
8033
8240
|
new Option("--detail <level>", "run detail level: compact (default), standard, full").choices(["compact", "standard", "full"]).default("compact")
|
|
8034
|
-
).option("--file <path>", "explain a specific file target").option("--module <name>", "explain a specific module target").option("--top <count>", "number of top hotspots to explain when no target is selected", "5").option("--compare <baseline>", "compare against a baseline snapshot JSON file").option("--snapshot <path>", "write current snapshot JSON artifact").
|
|
8241
|
+
).option("--file <path>", "explain a specific file target").option("--module <name>", "explain a specific module target").option("--top <count>", "number of top hotspots to explain when no target is selected", "5").option("--compare <baseline>", "compare against a baseline snapshot JSON file").option("--snapshot <path>", "write current snapshot JSON artifact").addOption(
|
|
8242
|
+
new Option("--report <format>", "write an additional report bundle during the run").choices(["html"]).default(void 0)
|
|
8243
|
+
).option("--report-output <path>", "output path for the generated report bundle").option("--open", "open the generated HTML report in the default browser").option("--no-trace", "disable trace embedding in generated snapshot").addOption(
|
|
8035
8244
|
new Option(
|
|
8036
8245
|
"--recent-window-days <days>",
|
|
8037
8246
|
"git recency window in days used for evolution volatility metrics"
|
|
@@ -8058,13 +8267,28 @@ program.command("run").argument("[path]", "path to the project to analyze").addO
|
|
|
8058
8267
|
...options.trace === true ? { trace: explain.trace } : {}
|
|
8059
8268
|
});
|
|
8060
8269
|
if (options.snapshot !== void 0) {
|
|
8061
|
-
await
|
|
8270
|
+
await writeFile7(options.snapshot, JSON.stringify(snapshot, null, 2), "utf8");
|
|
8062
8271
|
logger.info(`snapshot written: ${options.snapshot}`);
|
|
8063
8272
|
}
|
|
8064
8273
|
const report = options.compare === void 0 ? createReport(snapshot) : createReport(
|
|
8065
8274
|
snapshot,
|
|
8066
|
-
compareSnapshots(snapshot, parseSnapshot(await
|
|
8275
|
+
compareSnapshots(snapshot, parseSnapshot(await readFile7(options.compare, "utf8")))
|
|
8067
8276
|
);
|
|
8277
|
+
if (options.report === "html") {
|
|
8278
|
+
const htmlOutputPath = await writeHtmlReportBundle(report, {
|
|
8279
|
+
repositoryPath: explain.summary.structural.targetPath,
|
|
8280
|
+
...options.reportOutput === void 0 ? {} : { outputPath: options.reportOutput }
|
|
8281
|
+
});
|
|
8282
|
+
if (options.open === true) {
|
|
8283
|
+
const opened = await openPath(`${htmlOutputPath}/index.html`);
|
|
8284
|
+
if (!opened) {
|
|
8285
|
+
logger.warn("unable to open html report automatically on this platform");
|
|
8286
|
+
}
|
|
8287
|
+
}
|
|
8288
|
+
logger.info(`html report written: ${htmlOutputPath}`);
|
|
8289
|
+
} else if (options.open === true) {
|
|
8290
|
+
logger.warn("--open has no effect unless --report html is set");
|
|
8291
|
+
}
|
|
8068
8292
|
if (options.format === "json") {
|
|
8069
8293
|
const analyzeSummaryOutput = formatAnalyzeOutput(explain.summary, "summary");
|
|
8070
8294
|
if (options.detail === "compact") {
|