@getcodesentinel/codesentinel 1.11.0 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2463,7 +2463,7 @@ var resolveAutoBaselineRef = async (input) => {
2463
2463
 
2464
2464
  // src/index.ts
2465
2465
  import { readFileSync as readFileSync2 } from "fs";
2466
- import { dirname, resolve as resolve5 } from "path";
2466
+ import { dirname as dirname2, resolve as resolve5 } from "path";
2467
2467
  import { fileURLToPath } from "url";
2468
2468
 
2469
2469
  // src/application/format-analyze-output.ts
@@ -2857,6 +2857,337 @@ var parseLogLevel = (value) => {
2857
2857
  }
2858
2858
  };
2859
2859
 
2860
+ // src/application/check-for-updates.ts
2861
+ import { spawn } from "child_process";
2862
+ import { mkdir, readFile, writeFile } from "fs/promises";
2863
+ import { homedir } from "os";
2864
+ import { dirname, join as join3 } from "path";
2865
+ import { stderr, stdin } from "process";
2866
+ import { clearScreenDown, cursorTo, emitKeypressEvents, moveCursor } from "readline";
2867
+ var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
2868
+ var UPDATE_CACHE_PATH = join3(homedir(), ".cache", "codesentinel", "update-check.json");
2869
+ var SEMVER_PATTERN = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
2870
+ var ANSI = {
2871
+ reset: "\x1B[0m",
2872
+ bold: "\x1B[1m",
2873
+ dim: "\x1B[2m",
2874
+ cyan: "\x1B[36m",
2875
+ green: "\x1B[32m",
2876
+ yellow: "\x1B[33m"
2877
+ };
2878
+ var parsePrereleaseIdentifier = (identifier) => {
2879
+ if (/^\d+$/.test(identifier)) {
2880
+ return Number.parseInt(identifier, 10);
2881
+ }
2882
+ return identifier;
2883
+ };
2884
+ var parseSemver2 = (value) => {
2885
+ const match = SEMVER_PATTERN.exec(value.trim());
2886
+ if (match === null) {
2887
+ return null;
2888
+ }
2889
+ const groups = match.groups;
2890
+ if (groups === void 0) {
2891
+ return null;
2892
+ }
2893
+ const majorRaw = groups["major"];
2894
+ const minorRaw = groups["minor"];
2895
+ const patchRaw = groups["patch"];
2896
+ const prereleaseRaw = groups["prerelease"];
2897
+ if (majorRaw === void 0 || minorRaw === void 0 || patchRaw === void 0) {
2898
+ return null;
2899
+ }
2900
+ const prerelease = prereleaseRaw === void 0 || prereleaseRaw.length === 0 ? [] : prereleaseRaw.split(".").map(parsePrereleaseIdentifier);
2901
+ return {
2902
+ major: Number.parseInt(majorRaw, 10),
2903
+ minor: Number.parseInt(minorRaw, 10),
2904
+ patch: Number.parseInt(patchRaw, 10),
2905
+ prerelease
2906
+ };
2907
+ };
2908
+ var comparePrerelease = (left, right) => {
2909
+ if (left.length === 0 && right.length === 0) {
2910
+ return 0;
2911
+ }
2912
+ if (left.length === 0) {
2913
+ return 1;
2914
+ }
2915
+ if (right.length === 0) {
2916
+ return -1;
2917
+ }
2918
+ const length = Math.max(left.length, right.length);
2919
+ for (let index = 0; index < length; index += 1) {
2920
+ const leftValue = left[index];
2921
+ const rightValue = right[index];
2922
+ if (leftValue === void 0) {
2923
+ return -1;
2924
+ }
2925
+ if (rightValue === void 0) {
2926
+ return 1;
2927
+ }
2928
+ if (typeof leftValue === "number" && typeof rightValue === "number") {
2929
+ if (leftValue !== rightValue) {
2930
+ return leftValue > rightValue ? 1 : -1;
2931
+ }
2932
+ continue;
2933
+ }
2934
+ if (typeof leftValue === "number" && typeof rightValue === "string") {
2935
+ return -1;
2936
+ }
2937
+ if (typeof leftValue === "string" && typeof rightValue === "number") {
2938
+ return 1;
2939
+ }
2940
+ if (leftValue !== rightValue) {
2941
+ return leftValue > rightValue ? 1 : -1;
2942
+ }
2943
+ }
2944
+ return 0;
2945
+ };
2946
+ var compareVersions = (left, right) => {
2947
+ const leftParsed = parseSemver2(left);
2948
+ const rightParsed = parseSemver2(right);
2949
+ if (leftParsed === null || rightParsed === null) {
2950
+ return null;
2951
+ }
2952
+ if (leftParsed.major !== rightParsed.major) {
2953
+ return leftParsed.major > rightParsed.major ? 1 : -1;
2954
+ }
2955
+ if (leftParsed.minor !== rightParsed.minor) {
2956
+ return leftParsed.minor > rightParsed.minor ? 1 : -1;
2957
+ }
2958
+ if (leftParsed.patch !== rightParsed.patch) {
2959
+ return leftParsed.patch > rightParsed.patch ? 1 : -1;
2960
+ }
2961
+ return comparePrerelease(leftParsed.prerelease, rightParsed.prerelease);
2962
+ };
2963
+ var isTruthy = (value) => {
2964
+ if (value === void 0) {
2965
+ return false;
2966
+ }
2967
+ return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
2968
+ };
2969
+ var parseNpmViewVersionOutput = (output) => {
2970
+ const trimmed = output.trim();
2971
+ if (trimmed.length === 0) {
2972
+ return null;
2973
+ }
2974
+ try {
2975
+ const parsed = JSON.parse(trimmed);
2976
+ if (typeof parsed === "string" && parsed.trim().length > 0) {
2977
+ return parsed.trim();
2978
+ }
2979
+ if (Array.isArray(parsed) && parsed.length > 0) {
2980
+ const latest = parsed.at(-1);
2981
+ if (typeof latest === "string" && latest.trim().length > 0) {
2982
+ return latest.trim();
2983
+ }
2984
+ }
2985
+ } catch {
2986
+ return trimmed;
2987
+ }
2988
+ return null;
2989
+ };
2990
+ var readCache = async () => {
2991
+ try {
2992
+ const raw = await readFile(UPDATE_CACHE_PATH, "utf8");
2993
+ const parsed = JSON.parse(raw);
2994
+ if (typeof parsed === "object" && parsed !== null && typeof parsed.lastCheckedAt === "string") {
2995
+ return { lastCheckedAt: parsed.lastCheckedAt };
2996
+ }
2997
+ } catch {
2998
+ return null;
2999
+ }
3000
+ return null;
3001
+ };
3002
+ var writeCache = async (cache) => {
3003
+ await mkdir(dirname(UPDATE_CACHE_PATH), { recursive: true });
3004
+ await writeFile(UPDATE_CACHE_PATH, JSON.stringify(cache), "utf8");
3005
+ };
3006
+ var shouldRunUpdateCheck = (input) => {
3007
+ if (!input.isInteractive) {
3008
+ return false;
3009
+ }
3010
+ if (isTruthy(input.env["CI"])) {
3011
+ return false;
3012
+ }
3013
+ if (isTruthy(input.env["CODESENTINEL_NO_UPDATE_NOTIFIER"])) {
3014
+ return false;
3015
+ }
3016
+ if (input.argv.some((argument) => argument === "--help" || argument === "-h")) {
3017
+ return false;
3018
+ }
3019
+ if (input.argv.some((argument) => argument === "--version" || argument === "-V")) {
3020
+ return false;
3021
+ }
3022
+ if (input.lastCheckedAt === null) {
3023
+ return true;
3024
+ }
3025
+ const lastCheckedMs = Date.parse(input.lastCheckedAt);
3026
+ if (!Number.isFinite(lastCheckedMs)) {
3027
+ return true;
3028
+ }
3029
+ return input.nowMs - lastCheckedMs >= UPDATE_CHECK_INTERVAL_MS;
3030
+ };
3031
+ var runCommand = async (command, args, mode) => {
3032
+ return await new Promise((resolvePromise, reject) => {
3033
+ const child = spawn(command, [...args], {
3034
+ stdio: mode === "inherit" ? "inherit" : ["ignore", "pipe", "pipe"]
3035
+ });
3036
+ let stdoutRaw = "";
3037
+ if (mode === "capture" && child.stdout !== null) {
3038
+ child.stdout.setEncoding("utf8");
3039
+ child.stdout.on("data", (chunk) => {
3040
+ stdoutRaw += chunk;
3041
+ });
3042
+ }
3043
+ child.on("error", (error) => {
3044
+ reject(error);
3045
+ });
3046
+ child.on("close", (code) => {
3047
+ resolvePromise({ code: code ?? 1, stdout: stdoutRaw });
3048
+ });
3049
+ });
3050
+ };
3051
+ var fetchLatestVersion = async (packageName) => {
3052
+ const result = await runCommand("npm", ["view", packageName, "version", "--json"], "capture");
3053
+ if (result.code !== 0) {
3054
+ return null;
3055
+ }
3056
+ return parseNpmViewVersionOutput(result.stdout);
3057
+ };
3058
+ var renderUpdatePrompt = (latestVersion, currentVersion, selectedIndex) => {
3059
+ const options = ["Install update now", "Not now (continue current command)"];
3060
+ const lines = [
3061
+ `${ANSI.cyan}${ANSI.bold}CodeSentinel Update Available${ANSI.reset}`,
3062
+ `${ANSI.dim}Current: ${currentVersion} Latest: ${latestVersion}${ANSI.reset}`,
3063
+ "",
3064
+ ...options.map((option, index) => {
3065
+ const selected = index === selectedIndex;
3066
+ const prefix = selected ? `${ANSI.green}>${ANSI.reset}` : " ";
3067
+ const text = selected ? `${ANSI.bold}${option}${ANSI.reset}` : option;
3068
+ return `${prefix} ${text}`;
3069
+ }),
3070
+ "",
3071
+ `${ANSI.dim}Use \u2191/\u2193 to choose, Enter to confirm.${ANSI.reset}`
3072
+ ];
3073
+ stderr.write(lines.join("\n"));
3074
+ return lines.length;
3075
+ };
3076
+ var promptInstall = async (latestVersion, currentVersion) => {
3077
+ if (!stdin.isTTY || !stderr.isTTY || typeof stdin.setRawMode !== "function") {
3078
+ stderr.write(
3079
+ `New version ${latestVersion} is available (current ${currentVersion}). Run: npm install -g @getcodesentinel/codesentinel@latest
3080
+ `
3081
+ );
3082
+ return "skip";
3083
+ }
3084
+ return await new Promise((resolve6) => {
3085
+ emitKeypressEvents(stdin);
3086
+ let selectedIndex = 0;
3087
+ let renderedLines = 0;
3088
+ const previousRawMode = stdin.isRaw;
3089
+ const clearPromptArea = () => {
3090
+ if (renderedLines > 0) {
3091
+ moveCursor(stderr, 0, -(renderedLines - 1));
3092
+ }
3093
+ cursorTo(stderr, 0);
3094
+ clearScreenDown(stderr);
3095
+ };
3096
+ const redraw = () => {
3097
+ clearPromptArea();
3098
+ renderedLines = renderUpdatePrompt(latestVersion, currentVersion, selectedIndex);
3099
+ };
3100
+ const cleanup = (choice) => {
3101
+ stdin.off("keypress", onKeypress);
3102
+ stdin.pause();
3103
+ if (typeof stdin.setRawMode === "function") {
3104
+ stdin.setRawMode(previousRawMode);
3105
+ }
3106
+ clearPromptArea();
3107
+ if (choice === "install") {
3108
+ stderr.write(`${ANSI.yellow}Installing latest CodeSentinel...${ANSI.reset}
3109
+ `);
3110
+ } else if (renderedLines > 0) {
3111
+ stderr.write("\n");
3112
+ }
3113
+ resolve6(choice);
3114
+ };
3115
+ const onKeypress = (_str, key) => {
3116
+ if (key.ctrl === true && key.name === "c") {
3117
+ cleanup("interrupt");
3118
+ return;
3119
+ }
3120
+ if (key.name === "up") {
3121
+ selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : 1;
3122
+ redraw();
3123
+ return;
3124
+ }
3125
+ if (key.name === "down") {
3126
+ selectedIndex = selectedIndex < 1 ? selectedIndex + 1 : 0;
3127
+ redraw();
3128
+ return;
3129
+ }
3130
+ if (key.name === "return" || key.name === "enter") {
3131
+ cleanup(selectedIndex === 0 ? "install" : "skip");
3132
+ }
3133
+ };
3134
+ stdin.on("keypress", onKeypress);
3135
+ if (typeof stdin.setRawMode === "function") {
3136
+ stdin.setRawMode(true);
3137
+ }
3138
+ stdin.resume();
3139
+ redraw();
3140
+ });
3141
+ };
3142
+ var installLatestVersion = async (packageName) => {
3143
+ const result = await runCommand("npm", ["install", "-g", `${packageName}@latest`], "inherit");
3144
+ return result.code === 0;
3145
+ };
3146
+ var checkForCliUpdates = async (input) => {
3147
+ try {
3148
+ const nowMs = Date.now();
3149
+ const cache = await readCache();
3150
+ const shouldCheck = shouldRunUpdateCheck({
3151
+ argv: input.argv,
3152
+ env: input.env,
3153
+ isInteractive: Boolean(process.stdout.isTTY) && Boolean(process.stdin.isTTY),
3154
+ nowMs,
3155
+ lastCheckedAt: cache?.lastCheckedAt ?? null
3156
+ });
3157
+ if (!shouldCheck) {
3158
+ return;
3159
+ }
3160
+ await writeCache({ lastCheckedAt: new Date(nowMs).toISOString() });
3161
+ const latestVersion = await fetchLatestVersion(input.packageName);
3162
+ if (latestVersion === null) {
3163
+ return;
3164
+ }
3165
+ const comparison = compareVersions(latestVersion, input.currentVersion);
3166
+ if (comparison === null || comparison <= 0) {
3167
+ return;
3168
+ }
3169
+ const choice = await promptInstall(latestVersion, input.currentVersion);
3170
+ if (choice === "interrupt") {
3171
+ process.exit(130);
3172
+ }
3173
+ if (choice !== "install") {
3174
+ return;
3175
+ }
3176
+ const installed = await installLatestVersion(input.packageName);
3177
+ if (installed) {
3178
+ stderr.write(
3179
+ "CodeSentinel updated to latest version. Rerun your command to use the new version.\n"
3180
+ );
3181
+ process.exit(0);
3182
+ } else {
3183
+ stderr.write(
3184
+ "CodeSentinel update failed. You can retry with: npm install -g @getcodesentinel/codesentinel@latest\n"
3185
+ );
3186
+ }
3187
+ } catch {
3188
+ }
3189
+ };
3190
+
2860
3191
  // src/application/run-analyze-command.ts
2861
3192
  import { resolve as resolve3 } from "path";
2862
3193
 
@@ -4098,6 +4429,29 @@ var computeDependencySignalScore = (ownSignals, inheritedSignals, inheritedSigna
4098
4429
  return toUnitInterval(weightedTotal / maxWeightedTotal);
4099
4430
  };
4100
4431
  var clampConfidence = (value) => round45(toUnitInterval(value));
4432
+ var computeExternalMetadataConfidence = (external) => {
4433
+ if (!external.available) {
4434
+ return 0;
4435
+ }
4436
+ return round45(toUnitInterval(0.35 + external.metrics.metadataCoverage * 0.65));
4437
+ };
4438
+ var computeEvolutionHistoryConfidence = (structural, evolution, evolutionByFile) => {
4439
+ if (!evolution.available) {
4440
+ return 0;
4441
+ }
4442
+ const totalFiles = structural.files.length;
4443
+ if (totalFiles === 0) {
4444
+ return 1;
4445
+ }
4446
+ let coveredFiles = 0;
4447
+ for (const file of structural.files) {
4448
+ if (evolutionByFile.has(normalizePath2(file.id))) {
4449
+ coveredFiles += 1;
4450
+ }
4451
+ }
4452
+ const coverage = coveredFiles / totalFiles;
4453
+ return round45(toUnitInterval(0.3 + coverage * 0.7));
4454
+ };
4101
4455
  var buildFactorTraces = (totalScore, inputs) => {
4102
4456
  const positiveInputs = inputs.filter((input) => input.strength > 0);
4103
4457
  const strengthTotal = positiveInputs.reduce((sum, input) => sum + input.strength, 0);
@@ -4198,6 +4552,7 @@ var computeDependencyScores = (external, config) => {
4198
4552
  config.quantileClamp.upper
4199
4553
  );
4200
4554
  const dependencyContexts = /* @__PURE__ */ new Map();
4555
+ const metadataConfidence = computeExternalMetadataConfidence(external);
4201
4556
  const dependencyScores = external.dependencies.map((dependency) => {
4202
4557
  const signalScore = computeDependencySignalScore(
4203
4558
  dependency.ownRiskSignals,
@@ -4232,7 +4587,7 @@ var computeDependencyScores = (external, config) => {
4232
4587
  dependency.busFactor,
4233
4588
  dependency.weeklyDownloads
4234
4589
  ].filter((value) => value !== null).length;
4235
- const confidence = toUnitInterval(0.5 + availableMetricCount * 0.125);
4590
+ const confidence = toUnitInterval((0.5 + availableMetricCount * 0.125) * metadataConfidence);
4236
4591
  dependencyContexts.set(dependency.name, {
4237
4592
  signalScore: round45(signalScore),
4238
4593
  stalenessRisk: round45(stalenessRisk),
@@ -4431,7 +4786,13 @@ var buildFragileClusters = (structural, evolution, fileScoresByFile, config) =>
4431
4786
  var computeRiskSummary = (structural, evolution, external, config, traceCollector) => {
4432
4787
  const collector = traceCollector;
4433
4788
  const dependencyComputation = computeDependencyScores(external, config);
4789
+ const externalMetadataConfidence = computeExternalMetadataConfidence(external);
4434
4790
  const evolutionByFile = mapEvolutionByFile(evolution);
4791
+ const evolutionHistoryConfidence = computeEvolutionHistoryConfidence(
4792
+ structural,
4793
+ evolution,
4794
+ evolutionByFile
4795
+ );
4435
4796
  const evolutionScales = computeEvolutionScales(evolutionByFile, config);
4436
4797
  const cycleFileSet = new Set(
4437
4798
  structural.cycles.flatMap((cycle) => cycle.nodes.map((node) => normalizePath2(node)))
@@ -4615,7 +4976,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4615
4976
  weight: dimensionWeights.evolution,
4616
4977
  amplification: null,
4617
4978
  evidence: [{ kind: "file_metric", target: context.file, metric: "commitCount" }],
4618
- confidence: evolution.available ? 1 : 0
4979
+ confidence: evolution.available ? evolutionHistoryConfidence * (context.rawMetrics.commitCount === null ? 0.5 : 1) : 0
4619
4980
  },
4620
4981
  {
4621
4982
  factorId: "file.external",
@@ -4631,7 +4992,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4631
4992
  weight: dimensionWeights.external,
4632
4993
  amplification: null,
4633
4994
  evidence: [{ kind: "repository_metric", metric: "repositoryExternalPressure" }],
4634
- confidence: external.available ? 0.7 : 0
4995
+ confidence: external.available ? 0.7 * externalMetadataConfidence : 0
4635
4996
  },
4636
4997
  {
4637
4998
  factorId: "file.composite.interactions",
@@ -4759,7 +5120,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4759
5120
  weight: config.dependencyFactorWeights.signals,
4760
5121
  amplification: config.dependencySignals.inheritedSignalMultiplier,
4761
5122
  evidence: [{ kind: "dependency_metric", target: dependency.name, metric: "riskSignals" }],
4762
- confidence: 0.95
5123
+ confidence: 0.95 * externalMetadataConfidence
4763
5124
  },
4764
5125
  {
4765
5126
  factorId: "dependency.staleness",
@@ -4772,7 +5133,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4772
5133
  evidence: [
4773
5134
  { kind: "dependency_metric", target: dependency.name, metric: "daysSinceLastRelease" }
4774
5135
  ],
4775
- confidence: hasMetadata ? 0.9 : 0.5
5136
+ confidence: (hasMetadata ? 0.9 : 0.5) * externalMetadataConfidence
4776
5137
  },
4777
5138
  {
4778
5139
  factorId: "dependency.maintainer_concentration",
@@ -4787,7 +5148,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4787
5148
  evidence: [
4788
5149
  { kind: "dependency_metric", target: dependency.name, metric: "maintainerCount" }
4789
5150
  ],
4790
- confidence: hasMetadata ? 0.9 : 0.5
5151
+ confidence: (hasMetadata ? 0.9 : 0.5) * externalMetadataConfidence
4791
5152
  },
4792
5153
  {
4793
5154
  factorId: "dependency.topology",
@@ -4808,7 +5169,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4808
5169
  evidence: [
4809
5170
  { kind: "dependency_metric", target: dependency.name, metric: "dependencyDepth" }
4810
5171
  ],
4811
- confidence: 1
5172
+ confidence: 1 * externalMetadataConfidence
4812
5173
  },
4813
5174
  {
4814
5175
  factorId: "dependency.bus_factor",
@@ -4819,7 +5180,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4819
5180
  weight: config.dependencyFactorWeights.busFactorRisk,
4820
5181
  amplification: null,
4821
5182
  evidence: [{ kind: "dependency_metric", target: dependency.name, metric: "busFactor" }],
4822
- confidence: context.rawMetrics.busFactor === null ? 0.5 : 0.85
5183
+ confidence: (context.rawMetrics.busFactor === null ? 0.5 : 0.85) * externalMetadataConfidence
4823
5184
  },
4824
5185
  {
4825
5186
  factorId: "dependency.popularity_dampening",
@@ -4832,7 +5193,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4832
5193
  evidence: [
4833
5194
  { kind: "dependency_metric", target: dependency.name, metric: "weeklyDownloads" }
4834
5195
  ],
4835
- confidence: context.rawMetrics.weeklyDownloads === null ? 0.4 : 0.9
5196
+ confidence: (context.rawMetrics.weeklyDownloads === null ? 0.4 : 0.9) * externalMetadataConfidence
4836
5197
  }
4837
5198
  ]);
4838
5199
  collector.record(
@@ -4889,7 +5250,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4889
5250
  weight: dimensionWeights.evolution,
4890
5251
  amplification: null,
4891
5252
  evidence: [{ kind: "repository_metric", metric: "evolutionDimension" }],
4892
- confidence: evolution.available ? 1 : 0
5253
+ confidence: evolution.available ? evolutionHistoryConfidence : 0
4893
5254
  },
4894
5255
  {
4895
5256
  factorId: "repository.external",
@@ -4900,7 +5261,7 @@ var computeRiskSummary = (structural, evolution, external, config, traceCollecto
4900
5261
  weight: dimensionWeights.external,
4901
5262
  amplification: null,
4902
5263
  evidence: [{ kind: "repository_metric", metric: "externalDimension" }],
4903
- confidence: external.available ? 0.8 : 0
5264
+ confidence: external.available ? 0.8 * externalMetadataConfidence : 0
4904
5265
  },
4905
5266
  {
4906
5267
  factorId: "repository.composite.interactions",
@@ -5236,7 +5597,7 @@ var runAnalyzeCommand = async (inputPath, authorIdentityMode, options = {}, logg
5236
5597
  };
5237
5598
 
5238
5599
  // src/application/run-check-command.ts
5239
- import { readFile, writeFile } from "fs/promises";
5600
+ import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
5240
5601
 
5241
5602
  // src/application/build-analysis-snapshot.ts
5242
5603
  var buildAnalysisSnapshot = async (inputPath, authorIdentityMode, options, logger) => {
@@ -5301,7 +5662,7 @@ var runCheckCommand = async (inputPath, authorIdentityMode, options, logger = cr
5301
5662
  let diff;
5302
5663
  if (options.baselinePath !== void 0) {
5303
5664
  logger.info(`loading baseline snapshot: ${options.baselinePath}`);
5304
- const baselineRaw = await readFile(options.baselinePath, "utf8");
5665
+ const baselineRaw = await readFile2(options.baselinePath, "utf8");
5305
5666
  try {
5306
5667
  baseline = parseSnapshot(baselineRaw);
5307
5668
  } catch (error) {
@@ -5327,7 +5688,7 @@ var runCheckCommand = async (inputPath, authorIdentityMode, options, logger = cr
5327
5688
  options.outputFormat
5328
5689
  );
5329
5690
  if (options.outputPath !== void 0) {
5330
- await writeFile(options.outputPath, rendered, "utf8");
5691
+ await writeFile2(options.outputPath, rendered, "utf8");
5331
5692
  logger.info(`check output written: ${options.outputPath}`);
5332
5693
  }
5333
5694
  return {
@@ -5340,7 +5701,7 @@ var runCheckCommand = async (inputPath, authorIdentityMode, options, logger = cr
5340
5701
  };
5341
5702
 
5342
5703
  // src/application/run-ci-command.ts
5343
- import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
5704
+ import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
5344
5705
  import { relative as relative2, resolve as resolve4 } from "path";
5345
5706
  var isPathOutsideBase = (value) => {
5346
5707
  return value === ".." || value.startsWith("../") || value.startsWith("..\\");
@@ -5366,7 +5727,7 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
5366
5727
  logger
5367
5728
  );
5368
5729
  if (options.snapshotPath !== void 0) {
5369
- await writeFile2(options.snapshotPath, JSON.stringify(current, null, 2), "utf8");
5730
+ await writeFile3(options.snapshotPath, JSON.stringify(current, null, 2), "utf8");
5370
5731
  logger.info(`snapshot written: ${options.snapshotPath}`);
5371
5732
  }
5372
5733
  let baseline;
@@ -5438,7 +5799,7 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
5438
5799
  diff = compareSnapshots(current, baseline);
5439
5800
  } else if (options.baselinePath !== void 0) {
5440
5801
  logger.info(`loading baseline snapshot: ${options.baselinePath}`);
5441
- const baselineRaw = await readFile2(options.baselinePath, "utf8");
5802
+ const baselineRaw = await readFile3(options.baselinePath, "utf8");
5442
5803
  try {
5443
5804
  baseline = parseSnapshot(baselineRaw);
5444
5805
  } catch (error) {
@@ -5460,7 +5821,7 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
5460
5821
 
5461
5822
  ${ciMarkdown}`;
5462
5823
  if (options.reportPath !== void 0) {
5463
- await writeFile2(options.reportPath, markdownSummary, "utf8");
5824
+ await writeFile3(options.reportPath, markdownSummary, "utf8");
5464
5825
  logger.info(`report written: ${options.reportPath}`);
5465
5826
  }
5466
5827
  const machineReadable = {
@@ -5472,7 +5833,7 @@ ${ciMarkdown}`;
5472
5833
  exitCode: gateResult.exitCode
5473
5834
  };
5474
5835
  if (options.jsonOutputPath !== void 0) {
5475
- await writeFile2(options.jsonOutputPath, JSON.stringify(machineReadable, null, 2), "utf8");
5836
+ await writeFile3(options.jsonOutputPath, JSON.stringify(machineReadable, null, 2), "utf8");
5476
5837
  logger.info(`ci machine output written: ${options.jsonOutputPath}`);
5477
5838
  }
5478
5839
  return {
@@ -5486,7 +5847,7 @@ ${ciMarkdown}`;
5486
5847
  };
5487
5848
 
5488
5849
  // src/application/run-report-command.ts
5489
- import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
5850
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
5490
5851
  var runReportCommand = async (inputPath, authorIdentityMode, options, logger = createSilentLogger()) => {
5491
5852
  logger.info("building analysis snapshot");
5492
5853
  const current = await buildAnalysisSnapshot(
@@ -5499,7 +5860,7 @@ var runReportCommand = async (inputPath, authorIdentityMode, options, logger = c
5499
5860
  logger
5500
5861
  );
5501
5862
  if (options.snapshotPath !== void 0) {
5502
- await writeFile3(options.snapshotPath, JSON.stringify(current, null, 2), "utf8");
5863
+ await writeFile4(options.snapshotPath, JSON.stringify(current, null, 2), "utf8");
5503
5864
  logger.info(`snapshot written: ${options.snapshotPath}`);
5504
5865
  }
5505
5866
  let report;
@@ -5507,14 +5868,14 @@ var runReportCommand = async (inputPath, authorIdentityMode, options, logger = c
5507
5868
  report = createReport(current);
5508
5869
  } else {
5509
5870
  logger.info(`loading baseline snapshot: ${options.comparePath}`);
5510
- const baselineRaw = await readFile3(options.comparePath, "utf8");
5871
+ const baselineRaw = await readFile4(options.comparePath, "utf8");
5511
5872
  const baseline = parseSnapshot(baselineRaw);
5512
5873
  const diff = compareSnapshots(current, baseline);
5513
5874
  report = createReport(current, diff);
5514
5875
  }
5515
5876
  const rendered = formatReport(report, options.format);
5516
5877
  if (options.outputPath !== void 0) {
5517
- await writeFile3(options.outputPath, rendered, "utf8");
5878
+ await writeFile4(options.outputPath, rendered, "utf8");
5518
5879
  logger.info(`report written: ${options.outputPath}`);
5519
5880
  }
5520
5881
  return { report, rendered };
@@ -5568,7 +5929,7 @@ var runExplainCommand = async (inputPath, authorIdentityMode, options, logger =
5568
5929
 
5569
5930
  // src/index.ts
5570
5931
  var program = new Command();
5571
- var packageJsonPath = resolve5(dirname(fileURLToPath(import.meta.url)), "../package.json");
5932
+ var packageJsonPath = resolve5(dirname2(fileURLToPath(import.meta.url)), "../package.json");
5572
5933
  var { version } = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
5573
5934
  var parseRecentWindowDays = (value) => {
5574
5935
  const parsed = Number.parseInt(value, 10);
@@ -5886,5 +6247,11 @@ if (argv.length <= 2) {
5886
6247
  program.outputHelp();
5887
6248
  process.exit(0);
5888
6249
  }
6250
+ await checkForCliUpdates({
6251
+ packageName: "@getcodesentinel/codesentinel",
6252
+ currentVersion: version,
6253
+ argv: process.argv,
6254
+ env: process.env
6255
+ });
5889
6256
  await program.parseAsync(argv);
5890
6257
  //# sourceMappingURL=index.js.map