@getcodesentinel/codesentinel 1.9.5 → 1.10.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.
- package/README.md +6 -1
- package/dist/index.js +88 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,6 +178,9 @@ codesentinel analyze . --author-identity likely_merge
|
|
|
178
178
|
# Deterministic: strict email identity, no heuristic merging
|
|
179
179
|
codesentinel analyze . --author-identity strict_email
|
|
180
180
|
|
|
181
|
+
# Tune recency window (days) used for evolution volatility
|
|
182
|
+
codesentinel analyze . --recent-window-days 60
|
|
183
|
+
|
|
181
184
|
# Quiet mode (only JSON output)
|
|
182
185
|
codesentinel analyze . --log-level silent
|
|
183
186
|
|
|
@@ -203,6 +206,7 @@ codesentinel explain . --module src/components
|
|
|
203
206
|
# Explain in markdown or json
|
|
204
207
|
codesentinel explain . --format md
|
|
205
208
|
codesentinel explain . --format json
|
|
209
|
+
codesentinel explain . --recent-window-days 60
|
|
206
210
|
|
|
207
211
|
# Report generation (human + machine readable)
|
|
208
212
|
codesentinel report .
|
|
@@ -223,6 +227,7 @@ Notes:
|
|
|
223
227
|
- At `info`/`debug`, structural, evolution, and dependency stages report progress so long analyses are observable.
|
|
224
228
|
- `--output summary` (default) prints a compact result for terminal use.
|
|
225
229
|
- `--output json` (or `--json`) prints the full analysis object.
|
|
230
|
+
- `--recent-window-days <days>` customizes the git recency window used to compute `recentVolatility` (default: `30`).
|
|
226
231
|
|
|
227
232
|
When running through pnpm, pass CLI arguments after `--`:
|
|
228
233
|
|
|
@@ -318,7 +323,7 @@ Exit codes:
|
|
|
318
323
|
|
|
319
324
|
Text/markdown output includes:
|
|
320
325
|
|
|
321
|
-
- repository score and risk band (`low|moderate|high|very_high`)
|
|
326
|
+
- repository score and risk band (`low|moderate|elevated|high|very_high`)
|
|
322
327
|
- plain-language primary drivers
|
|
323
328
|
- concrete evidence values behind those drivers
|
|
324
329
|
- intersected signals (composite interaction terms)
|
package/dist/index.js
CHANGED
|
@@ -4992,7 +4992,7 @@ var createEvolutionProgressReporter = (logger) => {
|
|
|
4992
4992
|
}
|
|
4993
4993
|
};
|
|
4994
4994
|
};
|
|
4995
|
-
var collectAnalysisInputs = async (inputPath, authorIdentityMode, logger = createSilentLogger()) => {
|
|
4995
|
+
var collectAnalysisInputs = async (inputPath, authorIdentityMode, options = {}, logger = createSilentLogger()) => {
|
|
4996
4996
|
const invocationCwd = process.env["INIT_CWD"] ?? process.cwd();
|
|
4997
4997
|
const targetPath = resolveTargetPath(inputPath, invocationCwd);
|
|
4998
4998
|
logger.info(`analyzing repository: ${targetPath}`);
|
|
@@ -5008,7 +5008,10 @@ var collectAnalysisInputs = async (inputPath, authorIdentityMode, logger = creat
|
|
|
5008
5008
|
const evolution = analyzeRepositoryEvolutionFromGit(
|
|
5009
5009
|
{
|
|
5010
5010
|
repositoryPath: targetPath,
|
|
5011
|
-
config: {
|
|
5011
|
+
config: {
|
|
5012
|
+
authorIdentityMode,
|
|
5013
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5014
|
+
}
|
|
5012
5015
|
},
|
|
5013
5016
|
createEvolutionProgressReporter(logger)
|
|
5014
5017
|
);
|
|
@@ -5037,8 +5040,8 @@ var collectAnalysisInputs = async (inputPath, authorIdentityMode, logger = creat
|
|
|
5037
5040
|
external
|
|
5038
5041
|
};
|
|
5039
5042
|
};
|
|
5040
|
-
var runAnalyzeCommand = async (inputPath, authorIdentityMode, logger = createSilentLogger()) => {
|
|
5041
|
-
const analysisInputs = await collectAnalysisInputs(inputPath, authorIdentityMode, logger);
|
|
5043
|
+
var runAnalyzeCommand = async (inputPath, authorIdentityMode, options = {}, logger = createSilentLogger()) => {
|
|
5044
|
+
const analysisInputs = await collectAnalysisInputs(inputPath, authorIdentityMode, options, logger);
|
|
5042
5045
|
logger.info("computing risk summary");
|
|
5043
5046
|
const risk = computeRepositoryRiskSummary(analysisInputs);
|
|
5044
5047
|
logger.info(`analysis completed (repositoryScore=${risk.repositoryScore})`);
|
|
@@ -5053,7 +5056,14 @@ import { readFile, writeFile } from "fs/promises";
|
|
|
5053
5056
|
|
|
5054
5057
|
// src/application/build-analysis-snapshot.ts
|
|
5055
5058
|
var buildAnalysisSnapshot = async (inputPath, authorIdentityMode, options, logger) => {
|
|
5056
|
-
const analysisInputs = await collectAnalysisInputs(
|
|
5059
|
+
const analysisInputs = await collectAnalysisInputs(
|
|
5060
|
+
inputPath,
|
|
5061
|
+
authorIdentityMode,
|
|
5062
|
+
{
|
|
5063
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5064
|
+
},
|
|
5065
|
+
logger
|
|
5066
|
+
);
|
|
5057
5067
|
const evaluation = evaluateRepositoryRisk(analysisInputs, { explain: options.includeTrace });
|
|
5058
5068
|
const summary = {
|
|
5059
5069
|
...analysisInputs,
|
|
@@ -5064,7 +5074,8 @@ var buildAnalysisSnapshot = async (inputPath, authorIdentityMode, options, logge
|
|
|
5064
5074
|
...evaluation.trace === void 0 ? {} : { trace: evaluation.trace },
|
|
5065
5075
|
analysisConfig: {
|
|
5066
5076
|
authorIdentityMode,
|
|
5067
|
-
includeTrace: options.includeTrace
|
|
5077
|
+
includeTrace: options.includeTrace,
|
|
5078
|
+
recentWindowDays: analysisInputs.evolution.available ? analysisInputs.evolution.metrics.recentWindowDays : options.recentWindowDays ?? null
|
|
5068
5079
|
}
|
|
5069
5080
|
});
|
|
5070
5081
|
};
|
|
@@ -5096,7 +5107,10 @@ var runCheckCommand = async (inputPath, authorIdentityMode, options, logger = cr
|
|
|
5096
5107
|
const current = await buildAnalysisSnapshot(
|
|
5097
5108
|
inputPath,
|
|
5098
5109
|
authorIdentityMode,
|
|
5099
|
-
{
|
|
5110
|
+
{
|
|
5111
|
+
includeTrace: options.includeTrace,
|
|
5112
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5113
|
+
},
|
|
5100
5114
|
logger
|
|
5101
5115
|
);
|
|
5102
5116
|
let baseline;
|
|
@@ -5163,7 +5177,10 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
|
|
|
5163
5177
|
const current = await buildAnalysisSnapshot(
|
|
5164
5178
|
inputPath,
|
|
5165
5179
|
authorIdentityMode,
|
|
5166
|
-
{
|
|
5180
|
+
{
|
|
5181
|
+
includeTrace: options.includeTrace,
|
|
5182
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5183
|
+
},
|
|
5167
5184
|
logger
|
|
5168
5185
|
);
|
|
5169
5186
|
if (options.snapshotPath !== void 0) {
|
|
@@ -5218,7 +5235,10 @@ var runCiCommand = async (inputPath, authorIdentityMode, options, logger = creat
|
|
|
5218
5235
|
return buildAnalysisSnapshot(
|
|
5219
5236
|
baselineTargetPath,
|
|
5220
5237
|
authorIdentityMode,
|
|
5221
|
-
{
|
|
5238
|
+
{
|
|
5239
|
+
includeTrace: options.includeTrace,
|
|
5240
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5241
|
+
},
|
|
5222
5242
|
logger
|
|
5223
5243
|
);
|
|
5224
5244
|
}
|
|
@@ -5290,7 +5310,10 @@ var runReportCommand = async (inputPath, authorIdentityMode, options, logger = c
|
|
|
5290
5310
|
const current = await buildAnalysisSnapshot(
|
|
5291
5311
|
inputPath,
|
|
5292
5312
|
authorIdentityMode,
|
|
5293
|
-
{
|
|
5313
|
+
{
|
|
5314
|
+
includeTrace: options.includeTrace,
|
|
5315
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5316
|
+
},
|
|
5294
5317
|
logger
|
|
5295
5318
|
);
|
|
5296
5319
|
if (options.snapshotPath !== void 0) {
|
|
@@ -5336,7 +5359,14 @@ var selectTargets = (trace, summary, options) => {
|
|
|
5336
5359
|
);
|
|
5337
5360
|
};
|
|
5338
5361
|
var runExplainCommand = async (inputPath, authorIdentityMode, options, logger = createSilentLogger()) => {
|
|
5339
|
-
const analysisInputs = await collectAnalysisInputs(
|
|
5362
|
+
const analysisInputs = await collectAnalysisInputs(
|
|
5363
|
+
inputPath,
|
|
5364
|
+
authorIdentityMode,
|
|
5365
|
+
{
|
|
5366
|
+
...options.recentWindowDays === void 0 ? {} : { recentWindowDays: options.recentWindowDays }
|
|
5367
|
+
},
|
|
5368
|
+
logger
|
|
5369
|
+
);
|
|
5340
5370
|
logger.info("computing explainable risk summary");
|
|
5341
5371
|
const evaluation = evaluateRepositoryRisk(analysisInputs, { explain: true });
|
|
5342
5372
|
if (evaluation.trace === void 0) {
|
|
@@ -5358,6 +5388,13 @@ var runExplainCommand = async (inputPath, authorIdentityMode, options, logger =
|
|
|
5358
5388
|
var program = new Command();
|
|
5359
5389
|
var packageJsonPath = resolve5(dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
5360
5390
|
var { version } = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
5391
|
+
var parseRecentWindowDays = (value) => {
|
|
5392
|
+
const parsed = Number.parseInt(value, 10);
|
|
5393
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
5394
|
+
throw new Error("--recent-window-days must be a positive integer");
|
|
5395
|
+
}
|
|
5396
|
+
return parsed;
|
|
5397
|
+
};
|
|
5361
5398
|
program.name("codesentinel").description("Structural and evolutionary risk analysis for TypeScript/JavaScript codebases").version(version);
|
|
5362
5399
|
program.command("analyze").argument("[path]", "path to the project to analyze").addOption(
|
|
5363
5400
|
new Option(
|
|
@@ -5371,10 +5408,20 @@ program.command("analyze").argument("[path]", "path to the project to analyze").
|
|
|
5371
5408
|
).choices(["silent", "error", "warn", "info", "debug"]).default(parseLogLevel(process.env["CODESENTINEL_LOG_LEVEL"]))
|
|
5372
5409
|
).addOption(
|
|
5373
5410
|
new Option("--output <mode>", "output mode: summary (default) or json (full analysis object)").choices(["summary", "json"]).default("summary")
|
|
5374
|
-
).option("--json", "shortcut for --output json").
|
|
5411
|
+
).option("--json", "shortcut for --output json").addOption(
|
|
5412
|
+
new Option(
|
|
5413
|
+
"--recent-window-days <days>",
|
|
5414
|
+
"git recency window in days used for evolution volatility metrics"
|
|
5415
|
+
).argParser(parseRecentWindowDays).default(30)
|
|
5416
|
+
).action(
|
|
5375
5417
|
async (path, options) => {
|
|
5376
5418
|
const logger = createStderrLogger(options.logLevel);
|
|
5377
|
-
const summary = await runAnalyzeCommand(
|
|
5419
|
+
const summary = await runAnalyzeCommand(
|
|
5420
|
+
path,
|
|
5421
|
+
options.authorIdentity,
|
|
5422
|
+
{ recentWindowDays: options.recentWindowDays },
|
|
5423
|
+
logger
|
|
5424
|
+
);
|
|
5378
5425
|
const outputMode = options.json === true ? "json" : options.output;
|
|
5379
5426
|
process.stdout.write(`${formatAnalyzeOutput(summary, outputMode)}
|
|
5380
5427
|
`);
|
|
@@ -5391,6 +5438,11 @@ program.command("explain").argument("[path]", "path to the project to analyze").
|
|
|
5391
5438
|
"log verbosity: silent, error, warn, info, debug (logs are written to stderr)"
|
|
5392
5439
|
).choices(["silent", "error", "warn", "info", "debug"]).default(parseLogLevel(process.env["CODESENTINEL_LOG_LEVEL"]))
|
|
5393
5440
|
).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").addOption(
|
|
5441
|
+
new Option(
|
|
5442
|
+
"--recent-window-days <days>",
|
|
5443
|
+
"git recency window in days used for evolution volatility metrics"
|
|
5444
|
+
).argParser(parseRecentWindowDays).default(30)
|
|
5445
|
+
).addOption(
|
|
5394
5446
|
new Option("--format <mode>", "output format: text, json, md").choices(["text", "json", "md"]).default("md")
|
|
5395
5447
|
).action(
|
|
5396
5448
|
async (path, options) => {
|
|
@@ -5400,6 +5452,7 @@ program.command("explain").argument("[path]", "path to the project to analyze").
|
|
|
5400
5452
|
...options.file === void 0 ? {} : { file: options.file },
|
|
5401
5453
|
...options.module === void 0 ? {} : { module: options.module },
|
|
5402
5454
|
top: Number.isFinite(top) ? top : 5,
|
|
5455
|
+
recentWindowDays: options.recentWindowDays,
|
|
5403
5456
|
format: options.format
|
|
5404
5457
|
};
|
|
5405
5458
|
const result = await runExplainCommand(path, options.authorIdentity, explainOptions, logger);
|
|
@@ -5449,7 +5502,12 @@ program.command("report").argument("[path]", "path to the project to analyze").a
|
|
|
5449
5502
|
).choices(["silent", "error", "warn", "info", "debug"]).default(parseLogLevel(process.env["CODESENTINEL_LOG_LEVEL"]))
|
|
5450
5503
|
).addOption(
|
|
5451
5504
|
new Option("--format <mode>", "output format: text, json, md").choices(["text", "json", "md"]).default("md")
|
|
5452
|
-
).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").
|
|
5505
|
+
).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(
|
|
5506
|
+
new Option(
|
|
5507
|
+
"--recent-window-days <days>",
|
|
5508
|
+
"git recency window in days used for evolution volatility metrics"
|
|
5509
|
+
).argParser(parseRecentWindowDays).default(30)
|
|
5510
|
+
).action(
|
|
5453
5511
|
async (path, options) => {
|
|
5454
5512
|
const logger = createStderrLogger(options.logLevel);
|
|
5455
5513
|
const result = await runReportCommand(
|
|
@@ -5460,7 +5518,8 @@ program.command("report").argument("[path]", "path to the project to analyze").a
|
|
|
5460
5518
|
...options.output === void 0 ? {} : { outputPath: options.output },
|
|
5461
5519
|
...options.compare === void 0 ? {} : { comparePath: options.compare },
|
|
5462
5520
|
...options.snapshot === void 0 ? {} : { snapshotPath: options.snapshot },
|
|
5463
|
-
includeTrace: options.trace
|
|
5521
|
+
includeTrace: options.trace,
|
|
5522
|
+
recentWindowDays: options.recentWindowDays
|
|
5464
5523
|
},
|
|
5465
5524
|
logger
|
|
5466
5525
|
);
|
|
@@ -5525,7 +5584,12 @@ program.command("check").argument("[path]", "path to the project to analyze").ad
|
|
|
5525
5584
|
new Option("--fail-on <level>", "failing severity threshold").choices(["error", "warn"]).default("error")
|
|
5526
5585
|
).addOption(
|
|
5527
5586
|
new Option("--format <mode>", "output format: text, json, md").choices(["text", "json", "md"]).default("text")
|
|
5528
|
-
).option("--output <path>", "write check output to a file path").option("--no-trace", "disable trace embedding in generated snapshot").
|
|
5587
|
+
).option("--output <path>", "write check output to a file path").option("--no-trace", "disable trace embedding in generated snapshot").addOption(
|
|
5588
|
+
new Option(
|
|
5589
|
+
"--recent-window-days <days>",
|
|
5590
|
+
"git recency window in days used for evolution volatility metrics"
|
|
5591
|
+
).argParser(parseRecentWindowDays).default(30)
|
|
5592
|
+
).action(
|
|
5529
5593
|
async (path, options) => {
|
|
5530
5594
|
const logger = createStderrLogger(options.logLevel);
|
|
5531
5595
|
try {
|
|
@@ -5536,6 +5600,7 @@ program.command("check").argument("[path]", "path to the project to analyze").ad
|
|
|
5536
5600
|
{
|
|
5537
5601
|
...options.compare === void 0 ? {} : { baselinePath: options.compare },
|
|
5538
5602
|
includeTrace: options.trace,
|
|
5603
|
+
recentWindowDays: options.recentWindowDays,
|
|
5539
5604
|
gateConfig,
|
|
5540
5605
|
outputFormat: options.format,
|
|
5541
5606
|
...options.output === void 0 ? {} : { outputPath: options.output }
|
|
@@ -5584,7 +5649,12 @@ program.command("ci").argument("[path]", "path to the project to analyze").addOp
|
|
|
5584
5649
|
"comma-separated default branch candidates for auto baseline resolution (for example: main,master)"
|
|
5585
5650
|
).option("--snapshot <path>", "write current snapshot JSON to path").option("--report <path>", "write markdown CI summary report").option("--json-output <path>", "write machine-readable CI JSON output").option("--max-repo-delta <value>", "maximum allowed normalized repository score increase").option("--no-new-cycles", "fail if new structural cycles are introduced").option("--no-new-high-risk-deps", "fail if new high-risk direct dependencies are introduced").option("--max-new-hotspots <count>", "maximum allowed number of new hotspots").option("--new-hotspot-score-threshold <score>", "minimum hotspot score to count as new hotspot").option("--max-repo-score <score>", "absolute repository score limit (0..100)").addOption(
|
|
5586
5651
|
new Option("--fail-on <level>", "failing severity threshold").choices(["error", "warn"]).default("error")
|
|
5587
|
-
).option("--no-trace", "disable trace embedding in generated snapshot").
|
|
5652
|
+
).option("--no-trace", "disable trace embedding in generated snapshot").addOption(
|
|
5653
|
+
new Option(
|
|
5654
|
+
"--recent-window-days <days>",
|
|
5655
|
+
"git recency window in days used for evolution volatility metrics"
|
|
5656
|
+
).argParser(parseRecentWindowDays).default(30)
|
|
5657
|
+
).action(
|
|
5588
5658
|
async (path, options) => {
|
|
5589
5659
|
const logger = createStderrLogger(options.logLevel);
|
|
5590
5660
|
try {
|
|
@@ -5602,6 +5672,7 @@ program.command("ci").argument("[path]", "path to the project to analyze").addOp
|
|
|
5602
5672
|
...options.report === void 0 ? {} : { reportPath: options.report },
|
|
5603
5673
|
...options.jsonOutput === void 0 ? {} : { jsonOutputPath: options.jsonOutput },
|
|
5604
5674
|
includeTrace: options.trace,
|
|
5675
|
+
recentWindowDays: options.recentWindowDays,
|
|
5605
5676
|
gateConfig
|
|
5606
5677
|
},
|
|
5607
5678
|
logger
|