projscan 4.9.2 → 4.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 +226 -1350
- package/dist/analyzers/securityCheck.js +33 -15
- package/dist/analyzers/securityCheck.js.map +1 -1
- package/dist/analyzers/supplyChainCheck.js +9 -2
- package/dist/analyzers/supplyChainCheck.js.map +1 -1
- package/dist/cli/commands/bugHunt.js +3 -1
- package/dist/cli/commands/bugHunt.js.map +1 -1
- package/dist/cli/commands/ci.js +29 -13
- package/dist/cli/commands/ci.js.map +1 -1
- package/dist/cli/commands/dogfood.js +2 -0
- package/dist/cli/commands/dogfood.js.map +1 -1
- package/dist/cli/commands/feedback.js +21 -2
- package/dist/cli/commands/feedback.js.map +1 -1
- package/dist/cli/commands/init.js +3 -0
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/route.js +3 -2
- package/dist/cli/commands/route.js.map +1 -1
- package/dist/core/adoption.js +50 -21
- package/dist/core/adoption.js.map +1 -1
- package/dist/core/agentBrief.js +2 -1
- package/dist/core/agentBrief.js.map +1 -1
- package/dist/core/bugHunt.js +51 -22
- package/dist/core/bugHunt.js.map +1 -1
- package/dist/core/bugHuntHotspotFindings.js +2 -1
- package/dist/core/bugHuntHotspotFindings.js.map +1 -1
- package/dist/core/ciGate.d.ts +10 -0
- package/dist/core/ciGate.js +21 -0
- package/dist/core/ciGate.js.map +1 -0
- package/dist/core/dogfood.d.ts +1 -0
- package/dist/core/dogfood.js +42 -20
- package/dist/core/dogfood.js.map +1 -1
- package/dist/core/dogfoodDiscovery.d.ts +8 -0
- package/dist/core/dogfoodDiscovery.js +119 -0
- package/dist/core/dogfoodDiscovery.js.map +1 -0
- package/dist/core/feedback.js +73 -5
- package/dist/core/feedback.js.map +1 -1
- package/dist/core/fileInspectionReport.js +37 -0
- package/dist/core/fileInspectionReport.js.map +1 -1
- package/dist/core/intentRouterArchitectureKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterArchitectureKeywordWeights.js +69 -0
- package/dist/core/intentRouterArchitectureKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterCatalog.js +85 -31
- package/dist/core/intentRouterCatalog.js.map +1 -1
- package/dist/core/intentRouterDependencyKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterDependencyKeywordWeights.js +100 -0
- package/dist/core/intentRouterDependencyKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterFileImpactKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterFileImpactKeywordWeights.js +92 -0
- package/dist/core/intentRouterFileImpactKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterKeywordEarlyGuards.js +8 -3
- package/dist/core/intentRouterKeywordEarlyGuards.js.map +1 -1
- package/dist/core/intentRouterKeywordSearchGuards.js +28 -24
- package/dist/core/intentRouterKeywordSearchGuards.js.map +1 -1
- package/dist/core/intentRouterKeywordToolGuards.js +43 -0
- package/dist/core/intentRouterKeywordToolGuards.js.map +1 -1
- package/dist/core/intentRouterKeywordWeights.js +40 -1222
- package/dist/core/intentRouterKeywordWeights.js.map +1 -1
- package/dist/core/intentRouterOperationalKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterOperationalKeywordWeights.js +203 -0
- package/dist/core/intentRouterOperationalKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterPlanningSignals.js +4 -1
- package/dist/core/intentRouterPlanningSignals.js.map +1 -1
- package/dist/core/intentRouterPrDiffKeywords.d.ts +4 -0
- package/dist/core/intentRouterPrDiffKeywords.js +64 -0
- package/dist/core/intentRouterPrDiffKeywords.js.map +1 -0
- package/dist/core/intentRouterPrDiffSignals.js +6 -0
- package/dist/core/intentRouterPrDiffSignals.js.map +1 -1
- package/dist/core/intentRouterProductImprovementSignals.d.ts +1 -0
- package/dist/core/intentRouterProductImprovementSignals.js +48 -0
- package/dist/core/intentRouterProductImprovementSignals.js.map +1 -0
- package/dist/core/intentRouterRegressionKeywordMatches.js +3 -0
- package/dist/core/intentRouterRegressionKeywordMatches.js.map +1 -1
- package/dist/core/intentRouterRegressionKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterRegressionKeywordWeights.js +118 -0
- package/dist/core/intentRouterRegressionKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterReleaseSignals.d.ts +1 -0
- package/dist/core/intentRouterReleaseSignals.js +47 -0
- package/dist/core/intentRouterReleaseSignals.js.map +1 -1
- package/dist/core/intentRouterReviewSignals.d.ts +1 -0
- package/dist/core/intentRouterReviewSignals.js +23 -1
- package/dist/core/intentRouterReviewSignals.js.map +1 -1
- package/dist/core/intentRouterSearchKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterSearchKeywordWeights.js +407 -0
- package/dist/core/intentRouterSearchKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterSecurityKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterSecurityKeywordWeights.js +50 -0
- package/dist/core/intentRouterSecurityKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterTrustFeedbackKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterTrustFeedbackKeywordWeights.js +222 -0
- package/dist/core/intentRouterTrustFeedbackKeywordWeights.js.map +1 -0
- package/dist/core/intentRouterUnderstandSignals.js +1 -0
- package/dist/core/intentRouterUnderstandSignals.js.map +1 -1
- package/dist/core/intentRouterWorkSignals.js +3 -0
- package/dist/core/intentRouterWorkSignals.js.map +1 -1
- package/dist/core/intentRouterWorkflowKeywordWeights.d.ts +1 -0
- package/dist/core/intentRouterWorkflowKeywordWeights.js +124 -0
- package/dist/core/intentRouterWorkflowKeywordWeights.js.map +1 -0
- package/dist/core/issueEngine.js +46 -2
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/memory.d.ts +2 -0
- package/dist/core/memory.js +33 -1
- package/dist/core/memory.js.map +1 -1
- package/dist/core/preflightChangedFiles.d.ts +3 -0
- package/dist/core/preflightChangedFiles.js +13 -0
- package/dist/core/preflightChangedFiles.js.map +1 -1
- package/dist/core/preflightEvidence.d.ts +3 -0
- package/dist/core/preflightEvidence.js +3 -0
- package/dist/core/preflightEvidence.js.map +1 -1
- package/dist/core/privacy.d.ts +2 -0
- package/dist/core/privacy.js +10 -0
- package/dist/core/privacy.js.map +1 -1
- package/dist/core/qualityScorecard.js +25 -13
- package/dist/core/qualityScorecard.js.map +1 -1
- package/dist/core/startEvidence.js +26 -1
- package/dist/core/startEvidence.js.map +1 -1
- package/dist/core/startFixedRouteCriteria.js +5 -0
- package/dist/core/startFixedRouteCriteria.js.map +1 -1
- package/dist/core/startInputs.d.ts +3 -0
- package/dist/core/startMissionPolicy.d.ts +1 -1
- package/dist/core/startMissionPolicy.js +18 -7
- package/dist/core/startMissionPolicy.js.map +1 -1
- package/dist/core/startMode.js +17 -4
- package/dist/core/startMode.js.map +1 -1
- package/dist/core/startReportBuilder.js +1 -1
- package/dist/core/startReportBuilder.js.map +1 -1
- package/dist/core/startReviewGate.js +26 -4
- package/dist/core/startReviewGate.js.map +1 -1
- package/dist/core/startRouteActions.js +6 -0
- package/dist/core/startRouteActions.js.map +1 -1
- package/dist/core/understand.js +60 -13
- package/dist/core/understand.js.map +1 -1
- package/dist/core/workplan.js +99 -17
- package/dist/core/workplan.js.map +1 -1
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/reporters/ciIssueDetails.d.ts +10 -0
- package/dist/reporters/ciIssueDetails.js +37 -0
- package/dist/reporters/ciIssueDetails.js.map +1 -0
- package/dist/reporters/consoleCiReporter.d.ts +2 -1
- package/dist/reporters/consoleCiReporter.js +26 -9
- package/dist/reporters/consoleCiReporter.js.map +1 -1
- package/dist/reporters/consoleFileReporter.js +10 -0
- package/dist/reporters/consoleFileReporter.js.map +1 -1
- package/dist/reporters/consoleHealthReporter.js +3 -1
- package/dist/reporters/consoleHealthReporter.js.map +1 -1
- package/dist/reporters/jsonReporter.d.ts +2 -1
- package/dist/reporters/jsonReporter.js +17 -10
- package/dist/reporters/jsonReporter.js.map +1 -1
- package/dist/reporters/markdownFileReporter.js +11 -0
- package/dist/reporters/markdownFileReporter.js.map +1 -1
- package/dist/reporters/markdownHealthReporter.d.ts +2 -1
- package/dist/reporters/markdownHealthReporter.js +5 -5
- package/dist/reporters/markdownHealthReporter.js.map +1 -1
- package/dist/reporters/scoreBreakdownReporter.d.ts +2 -0
- package/dist/reporters/scoreBreakdownReporter.js +24 -0
- package/dist/reporters/scoreBreakdownReporter.js.map +1 -0
- package/dist/tool-manifest.json +2 -2
- package/dist/types/analysis.d.ts +21 -1
- package/dist/types/bugHunt.d.ts +3 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/dogfood.d.ts +15 -1
- package/dist/types/inspection.d.ts +3 -0
- package/dist/types/preflight.d.ts +3 -0
- package/dist/types/startMissionControl.d.ts +3 -0
- package/dist/types/startMissionReview.d.ts +2 -0
- package/dist/utils/ciFailOn.d.ts +5 -0
- package/dist/utils/ciFailOn.js +12 -0
- package/dist/utils/ciFailOn.js.map +1 -0
- package/dist/utils/config.js +3 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/configBasics.d.ts +2 -0
- package/dist/utils/configBasics.js +21 -0
- package/dist/utils/configBasics.js.map +1 -1
- package/dist/utils/configIssueRules.js +64 -0
- package/dist/utils/configIssueRules.js.map +1 -1
- package/dist/utils/scoreCalculator.js +77 -16
- package/dist/utils/scoreCalculator.js.map +1 -1
- package/docs/GUIDE.md +36 -6
- package/docs/demos/projscan-4-1-demo.html +8 -8
- package/docs/demos/projscan-mission-control.tape +2 -2
- package/docs/demos/projscan-mission-proof.tape +9 -5
- package/docs/projscan-mission-control.gif +0 -0
- package/docs/projscan-mission-control.png +0 -0
- package/docs/projscan-mission-proof.gif +0 -0
- package/docs/projscan-proof-router.png +0 -0
- package/package.json +1 -1
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
const BASE_SCORE = 100;
|
|
2
|
+
const SEVERITY_WEIGHTS = {
|
|
3
|
+
error: 20,
|
|
4
|
+
warning: 10,
|
|
5
|
+
info: 3,
|
|
6
|
+
};
|
|
1
7
|
/**
|
|
2
8
|
* Calculate a project health score (0–100) and letter grade from detected issues.
|
|
3
9
|
*
|
|
@@ -14,23 +20,78 @@
|
|
|
14
20
|
* F < 60
|
|
15
21
|
*/
|
|
16
22
|
export function calculateScore(issues) {
|
|
17
|
-
const errors = issues
|
|
18
|
-
const warnings = issues
|
|
19
|
-
const infos = issues
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
+
const errors = countSeverity(issues, 'error');
|
|
24
|
+
const warnings = countSeverity(issues, 'warning');
|
|
25
|
+
const infos = countSeverity(issues, 'info');
|
|
26
|
+
const uncappedPenalty = penaltyFor('error', errors) + penaltyFor('warning', warnings) + penaltyFor('info', infos);
|
|
27
|
+
const totalPenalty = Math.min(BASE_SCORE, uncappedPenalty);
|
|
28
|
+
const score = Math.max(0, BASE_SCORE - uncappedPenalty);
|
|
29
|
+
const grade = gradeForScore(score);
|
|
30
|
+
return {
|
|
31
|
+
score,
|
|
32
|
+
grade,
|
|
33
|
+
errors,
|
|
34
|
+
warnings,
|
|
35
|
+
infos,
|
|
36
|
+
scoreBreakdown: buildScoreBreakdown(issues, {
|
|
37
|
+
score,
|
|
38
|
+
grade,
|
|
39
|
+
errors,
|
|
40
|
+
warnings,
|
|
41
|
+
infos,
|
|
42
|
+
totalPenalty,
|
|
43
|
+
uncappedPenalty,
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function countSeverity(issues, severity) {
|
|
48
|
+
return issues.filter((issue) => issue.severity === severity).length;
|
|
49
|
+
}
|
|
50
|
+
function penaltyFor(severity, count) {
|
|
51
|
+
return count * SEVERITY_WEIGHTS[severity];
|
|
52
|
+
}
|
|
53
|
+
function gradeForScore(score) {
|
|
23
54
|
if (score >= 90)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
return 'A';
|
|
56
|
+
if (score >= 80)
|
|
57
|
+
return 'B';
|
|
58
|
+
if (score >= 70)
|
|
59
|
+
return 'C';
|
|
60
|
+
if (score >= 60)
|
|
61
|
+
return 'D';
|
|
62
|
+
return 'F';
|
|
63
|
+
}
|
|
64
|
+
function buildScoreBreakdown(issues, score) {
|
|
65
|
+
return {
|
|
66
|
+
baseScore: BASE_SCORE,
|
|
67
|
+
finalScore: score.score,
|
|
68
|
+
grade: score.grade,
|
|
69
|
+
totalPenalty: score.totalPenalty,
|
|
70
|
+
uncappedPenalty: score.uncappedPenalty,
|
|
71
|
+
bySeverity: {
|
|
72
|
+
error: severityBreakdown(score.errors, 'error'),
|
|
73
|
+
warning: severityBreakdown(score.warnings, 'warning'),
|
|
74
|
+
info: severityBreakdown(score.infos, 'info'),
|
|
75
|
+
},
|
|
76
|
+
byCategory: categoryBreakdown(issues),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function severityBreakdown(count, severity) {
|
|
80
|
+
const weight = SEVERITY_WEIGHTS[severity];
|
|
81
|
+
return { count, weight, penalty: count * weight };
|
|
82
|
+
}
|
|
83
|
+
function categoryBreakdown(issues) {
|
|
84
|
+
const categories = new Map();
|
|
85
|
+
for (const issue of issues) {
|
|
86
|
+
const category = issue.category || 'uncategorized';
|
|
87
|
+
const current = categories.get(category) ?? { count: 0, penalty: 0 };
|
|
88
|
+
current.count += 1;
|
|
89
|
+
current.penalty += SEVERITY_WEIGHTS[issue.severity];
|
|
90
|
+
categories.set(category, current);
|
|
91
|
+
}
|
|
92
|
+
return [...categories.entries()]
|
|
93
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
94
|
+
.map(([category, value]) => ({ category, ...value }));
|
|
34
95
|
}
|
|
35
96
|
const GRADE_COLORS = {
|
|
36
97
|
A: 'brightgreen',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoreCalculator.js","sourceRoot":"","sources":["../../src/utils/scoreCalculator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,MAAM,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"scoreCalculator.js","sourceRoot":"","sources":["../../src/utils/scoreCalculator.ts"],"names":[],"mappings":"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"}
|
package/docs/GUIDE.md
CHANGED
|
@@ -551,13 +551,14 @@ Natural follow-up to `projscan hotspots` - once hotspots tells you _which_ file
|
|
|
551
551
|
projscan ci
|
|
552
552
|
```
|
|
553
553
|
|
|
554
|
-
A CI-pipeline-friendly health gate. Runs the full health check and exits with code 1 if the score falls below a threshold. No spinners or banners - clean output for CI logs.
|
|
554
|
+
A CI-pipeline-friendly health gate. Runs the full health check and exits with code 1 if the score falls below a threshold and at least one finding meets the `failOn` severity floor. No spinners or banners - clean output for CI logs.
|
|
555
555
|
|
|
556
556
|
**Options:**
|
|
557
557
|
|
|
558
558
|
| Flag | Description | Default |
|
|
559
559
|
| ------------------ | ------------------------------------------------ | ----------------------------------------------------------- |
|
|
560
560
|
| `--min-score <n>` | Minimum passing score (0–100) | `minScore` from `.projscanrc`, else 70 |
|
|
561
|
+
| `--fail-on <severity>` | Lowest severity that can fail a below-threshold gate: `info`, `warning`, or `error` | `failOn` from `.projscanrc`, else `warning` |
|
|
561
562
|
| `--changed-only` | Gate only on issues in files changed vs base ref | off |
|
|
562
563
|
| `--base-ref <ref>` | Git base ref for `--changed-only` | auto (origin/main → origin/master → main → master → HEAD~1) |
|
|
563
564
|
|
|
@@ -566,7 +567,7 @@ A CI-pipeline-friendly health gate. Runs the full health check and exits with co
|
|
|
566
567
|
```bash
|
|
567
568
|
$ projscan ci --min-score 80
|
|
568
569
|
|
|
569
|
-
projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80)
|
|
570
|
+
projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80, failOn: warning)
|
|
570
571
|
```
|
|
571
572
|
|
|
572
573
|
<img src="npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci" width="700">
|
|
@@ -574,7 +575,8 @@ projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80)
|
|
|
574
575
|
**Exit codes:**
|
|
575
576
|
|
|
576
577
|
- `0` - Score meets or exceeds the threshold
|
|
577
|
-
- `
|
|
578
|
+
- `0` - Score is below the threshold but no finding meets the `failOn` floor
|
|
579
|
+
- `1` - Score is below the threshold and at least one finding meets the `failOn` floor
|
|
578
580
|
|
|
579
581
|
**JSON output** (useful for scripts):
|
|
580
582
|
|
|
@@ -582,6 +584,10 @@ projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80)
|
|
|
582
584
|
projscan ci --min-score 70 --format json
|
|
583
585
|
```
|
|
584
586
|
|
|
587
|
+
Every `ci.issues[]` item keeps the original issue fields and adds
|
|
588
|
+
annotation-friendly fields: `ruleId`, `message`, primary `location`, all
|
|
589
|
+
`locations`, and `remediation` when a fix hint is available.
|
|
590
|
+
|
|
585
591
|
**SARIF output** (for GitHub Code Scanning or any SARIF consumer):
|
|
586
592
|
|
|
587
593
|
```bash
|
|
@@ -887,6 +893,9 @@ Use it before broader rollout. The report includes feedback questions for the fi
|
|
|
887
893
|
## Health Score
|
|
888
894
|
|
|
889
895
|
Every `projscan doctor` and `projscan badge` run calculates a health score from 0 to 100 based on detected issues.
|
|
896
|
+
`doctor --format json` and `ci --format json` include `scoreBreakdown` so scripts
|
|
897
|
+
and reviewers can see the base score, per-severity weights, category penalties,
|
|
898
|
+
total penalty, final score, and grade.
|
|
890
899
|
|
|
891
900
|
**Scoring:**
|
|
892
901
|
|
|
@@ -909,7 +918,8 @@ Every `projscan doctor` and `projscan badge` run calculates a health score from
|
|
|
909
918
|
The score appears in all output formats:
|
|
910
919
|
|
|
911
920
|
- **Console**: Shown at the top of the doctor report
|
|
912
|
-
- **JSON**: Included as `health.score` and `health.
|
|
921
|
+
- **JSON**: Included as `health.score`, `health.grade`, and `health.scoreBreakdown`
|
|
922
|
+
fields. CI uses the same structure under `ci.scoreBreakdown`.
|
|
913
923
|
- **Markdown**: Shown as a heading with an auto-generated shields.io badge
|
|
914
924
|
- **HTML**: Shown in the health summary card
|
|
915
925
|
- **SARIF**: Not surfaced directly - SARIF is per-issue, not per-project. The score still drives `ci`'s exit code.
|
|
@@ -1005,6 +1015,7 @@ ProjScan loads a project-wide config from one of:
|
|
|
1005
1015
|
```json
|
|
1006
1016
|
{
|
|
1007
1017
|
"minScore": 80,
|
|
1018
|
+
"failOn": "warning",
|
|
1008
1019
|
"baseRef": "origin/main",
|
|
1009
1020
|
"ignore": ["**/fixtures/**", "**/generated/**"],
|
|
1010
1021
|
"scan": {
|
|
@@ -1013,6 +1024,9 @@ ProjScan loads a project-wide config from one of:
|
|
|
1013
1024
|
"offline": false
|
|
1014
1025
|
},
|
|
1015
1026
|
"disableRules": ["missing-editorconfig", "large-*"],
|
|
1027
|
+
"suppress": {
|
|
1028
|
+
"hardcoded-secret": ["src/firebase.ts"]
|
|
1029
|
+
},
|
|
1016
1030
|
"severityOverrides": {
|
|
1017
1031
|
"missing-prettier": "info"
|
|
1018
1032
|
},
|
|
@@ -1034,12 +1048,14 @@ ProjScan loads a project-wide config from one of:
|
|
|
1034
1048
|
| Field | Type | Effect |
|
|
1035
1049
|
| --------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1036
1050
|
| `minScore` | number (0–100) | Default threshold for `projscan ci`. Clamped to 0–100. |
|
|
1051
|
+
| `failOn` | `'info' \| 'warning' \| 'error'` | Lowest severity that can fail a below-threshold `projscan ci` gate. Default `warning`; set `info` for legacy strictness or `error` for error-only blocking. |
|
|
1037
1052
|
| `baseRef` | string | Default base ref for `--changed-only`. |
|
|
1038
1053
|
| `ignore` | string[] | Extra glob patterns added to the built-in ignore list (`node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.nuxt`, `.cache`, `.turbo`, `.output`). |
|
|
1039
1054
|
| `scan.includeIgnored` | boolean | Explicitly include files hidden by Git ignore rules. Default `false`. |
|
|
1040
1055
|
| `scan.scanEnvValues` | boolean | Explicitly read `.env*` contents during secret-pattern checks. Default `false`; `.env` files are path-only. |
|
|
1041
1056
|
| `scan.offline` | boolean | Block projscan network-capable features: telemetry sending, `audit`, registry checks, and optional semantic model loading. Default `false`. |
|
|
1042
1057
|
| `disableRules` | string[] | Silence rules by id. Exact match (`missing-prettier`) or wildcard prefix (`large-*`). |
|
|
1058
|
+
| `suppress` | `Record<string, string[]>` | Silence a rule only for matching paths/globs, for example `{ "hardcoded-secret": ["src/firebase.ts"] }`. Other rules still run on that file. |
|
|
1043
1059
|
| `severityOverrides` | `Record<string, 'info' \| 'warning' \| 'error'>` | Remap a rule's severity. Useful for downgrading project-specific false positives without disabling them. |
|
|
1044
1060
|
| `reportPolicies` | `Record<string, { reportScope?: string[]; redactPaths?: boolean }>` | Named evidence export presets selected with `--report-policy <name>` on `analyze`, `doctor`, and `ci`. |
|
|
1045
1061
|
| `hotspots.limit` | number (1–100) | Default limit for `projscan hotspots`. |
|
|
@@ -1047,6 +1063,12 @@ ProjScan loads a project-wide config from one of:
|
|
|
1047
1063
|
|
|
1048
1064
|
Invalid JSON in a discovered config file is a hard error - projscan exits rather than silently ignoring it.
|
|
1049
1065
|
|
|
1066
|
+
Use inline suppressions for a single confirmed false positive:
|
|
1067
|
+
|
|
1068
|
+
```ts
|
|
1069
|
+
const firebaseKey = "AIza..." // projscan-ignore-line hardcoded-secret -- Firebase web keys are public identifiers
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1050
1072
|
### Embedded config in `package.json`
|
|
1051
1073
|
|
|
1052
1074
|
If you prefer to keep everything in `package.json`:
|
|
@@ -1564,8 +1586,10 @@ If you'd rather skip Code Scanning, `projscan init github-action` writes a pull-
|
|
|
1564
1586
|
The `ci` command is purpose-built for pipelines:
|
|
1565
1587
|
|
|
1566
1588
|
```bash
|
|
1567
|
-
projscan ci # Fail if score < 70
|
|
1589
|
+
projscan ci # Fail if score < 70 and warning/error findings exist
|
|
1568
1590
|
projscan ci --min-score 80 # Custom threshold
|
|
1591
|
+
projscan ci --fail-on info # Legacy strictness: info can fail the gate
|
|
1592
|
+
projscan ci --fail-on error # Only errors can fail a below-threshold gate
|
|
1569
1593
|
projscan ci --changed-only # Gate only on PR diff
|
|
1570
1594
|
projscan ci --format json # JSON output for scripts
|
|
1571
1595
|
projscan ci --format sarif > projscan.sarif # SARIF for any consumer
|
|
@@ -1577,9 +1601,15 @@ projscan ci --format sarif > projscan.sarif # SARIF for any consumer
|
|
|
1577
1601
|
result=$(projscan ci --min-score 0 --format json)
|
|
1578
1602
|
pass=$(echo "$result" | jq '.ci.pass')
|
|
1579
1603
|
score=$(echo "$result" | jq '.ci.score')
|
|
1580
|
-
echo "
|
|
1604
|
+
fail_on=$(echo "$result" | jq -r '.ci.failOn')
|
|
1605
|
+
echo "Score: $score, Pass: $pass, FailOn: $fail_on"
|
|
1581
1606
|
```
|
|
1582
1607
|
|
|
1608
|
+
For PR annotation tooling, read `.ci.issues[]`. Each issue includes `ruleId`,
|
|
1609
|
+
`severity`, `message`, primary `location`, all `locations`, and `remediation`
|
|
1610
|
+
when available. Gate metadata lives at `.ci.failOn`, `.ci.scorePass`, and
|
|
1611
|
+
`.ci.severityFloorMet`.
|
|
1612
|
+
|
|
1583
1613
|
### Tracking health over time in CI
|
|
1584
1614
|
|
|
1585
1615
|
Combine `ci` with `diff` to track regressions:
|
|
@@ -426,11 +426,11 @@
|
|
|
426
426
|
<section class="hero" aria-label="projscan Mission Control">
|
|
427
427
|
<div class="intro">
|
|
428
428
|
<div>
|
|
429
|
-
<p class="eyebrow">Mission
|
|
429
|
+
<p class="eyebrow">Mission proof loop</p>
|
|
430
430
|
<h1>Resume from saved proof.</h1>
|
|
431
431
|
<p class="lead">
|
|
432
|
-
projscan routes a developer goal, saves the mission, reads
|
|
433
|
-
|
|
432
|
+
projscan routes a developer goal, saves the mission, reads proof state, and tells the
|
|
433
|
+
next agent which proof passed, which work remains, and whether to request version
|
|
434
434
|
review.
|
|
435
435
|
</p>
|
|
436
436
|
<div class="pills" aria-label="Product capabilities">
|
|
@@ -445,7 +445,7 @@
|
|
|
445
445
|
<div class="metric-row" aria-label="Release candidate signals">
|
|
446
446
|
<div class="metric">
|
|
447
447
|
<strong>1 bundle</strong>
|
|
448
|
-
<span>mission
|
|
448
|
+
<span>mission and proof</span>
|
|
449
449
|
</div>
|
|
450
450
|
<div class="metric">
|
|
451
451
|
<strong>45</strong>
|
|
@@ -479,14 +479,14 @@
|
|
|
479
479
|
<span class="line dim">read proof-logs/summary.json and status.jsonl</span>
|
|
480
480
|
|
|
481
481
|
<div class="term-section">
|
|
482
|
-
<span class="line term-heading">
|
|
482
|
+
<span class="line term-heading">Completed Proof</span>
|
|
483
483
|
<span class="line">- Mission proof passed after 3 command(s).</span>
|
|
484
484
|
<span class="line">- 1 reviewer decision recorded.</span>
|
|
485
485
|
<span class="line">- 0 failed gates remain.</span>
|
|
486
486
|
</div>
|
|
487
487
|
|
|
488
488
|
<div class="term-section">
|
|
489
|
-
<span class="line term-heading">
|
|
489
|
+
<span class="line term-heading">Remaining Work</span>
|
|
490
490
|
<span class="line success">Run ./review.sh and choose a reviewer reply.</span>
|
|
491
491
|
<span class="line success">Version candidate: review_candidate</span>
|
|
492
492
|
</div>
|
|
@@ -531,7 +531,7 @@
|
|
|
531
531
|
<h2>Start from saved proof.</h2>
|
|
532
532
|
<p>
|
|
533
533
|
<code>projscan start --mission</code> reads the bundle proof state and gives the next
|
|
534
|
-
agent a focused
|
|
534
|
+
agent a focused proof status and remaining-work handoff.
|
|
535
535
|
</p>
|
|
536
536
|
</article>
|
|
537
537
|
<article class="card">
|
|
@@ -611,7 +611,7 @@
|
|
|
611
611
|
<span class="tag red">Gate</span>
|
|
612
612
|
<span>
|
|
613
613
|
<strong>Version review</strong>
|
|
614
|
-
|
|
614
|
+
Use outcome data to request review or keep fixing failed proof.
|
|
615
615
|
</span>
|
|
616
616
|
</div>
|
|
617
617
|
</div>
|
|
@@ -8,6 +8,6 @@ Set Theme "Catppuccin Mocha"
|
|
|
8
8
|
Set TypingSpeed 35ms
|
|
9
9
|
Set Padding 16
|
|
10
10
|
|
|
11
|
-
Type "projscan start --shortcuts --intent 'is it safe to commit this change?'"
|
|
11
|
+
Type "projscan start --shortcuts --intent 'is it safe to commit this change?' --quiet"
|
|
12
12
|
Enter
|
|
13
|
-
Sleep
|
|
13
|
+
Sleep 24s
|
|
@@ -12,14 +12,18 @@ Type "rm -rf .projscan/vhs-mission"
|
|
|
12
12
|
Enter
|
|
13
13
|
Sleep 500ms
|
|
14
14
|
|
|
15
|
-
Type "projscan start --save-mission .projscan/vhs-mission --intent '
|
|
15
|
+
Type "projscan start --save-mission .projscan/vhs-mission --intent 'what can projscan read?' --quiet"
|
|
16
16
|
Enter
|
|
17
|
-
Sleep
|
|
17
|
+
Sleep 30s
|
|
18
18
|
|
|
19
|
-
Type "
|
|
19
|
+
Type "sh .projscan/vhs-mission/review.sh | sed -n '1,34p'"
|
|
20
20
|
Enter
|
|
21
21
|
Sleep 8s
|
|
22
22
|
|
|
23
|
-
Type "projscan
|
|
23
|
+
Type "projscan mission-proof --mission .projscan/vhs-mission --format markdown --quiet | sed -n '1,32p'"
|
|
24
|
+
Enter
|
|
25
|
+
Sleep 10s
|
|
26
|
+
|
|
27
|
+
Type "projscan start --mission .projscan/vhs-mission --review-gate --quiet | sed -n '1,24p'"
|
|
24
28
|
Enter
|
|
25
|
-
Sleep
|
|
29
|
+
Sleep 24s
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projscan",
|
|
3
3
|
"mcpName": "io.github.abhiyoheswaran1/projscan",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.10.0",
|
|
5
5
|
"description": "Local code intelligence for agent-assisted engineering. Focused daily workflows for repo orientation before edits, proof before handoff or commit, and release-candidate review, with AST-backed evidence through an MCP server and CLI. Runs locally by default.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|