@greenarmor/ges 1.2.0 → 1.2.2

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.
@@ -51,6 +51,18 @@ export const auditCommand = new Command("audit")
51
51
  const auditedControls = updateControlsFromFindings(updatedControls, findings);
52
52
  const scoreData = generateScoreFile(auditedControls, frameworks, findings);
53
53
  writeJsonFile(path.join(root, ".ges", "score.json"), scoreData);
54
+ writeJsonFile(path.join(root, ".ges", "last-audit.json"), {
55
+ findings,
56
+ scannedFiles,
57
+ timestamp: new Date().toISOString(),
58
+ });
59
+ try {
60
+ const metaPath = path.join(root, ".ges", "metadata.json");
61
+ const meta = readJsonFile(metaPath) || {};
62
+ meta.last_audit = new Date().toISOString();
63
+ writeJsonFile(metaPath, meta);
64
+ }
65
+ catch { /* ignore metadata errors */ }
54
66
  const critical = findings.filter(f => f.severity === "critical");
55
67
  const high = findings.filter(f => f.severity === "high");
56
68
  const medium = findings.filter(f => f.severity === "medium");
@@ -2,6 +2,25 @@ import { Command } from "commander";
2
2
  import { ensureGESInitialized } from "../utils/project.js";
3
3
  import { runAudit, deduplicateFindings } from "@greenarmor/ges-audit-engine";
4
4
  import { createAutoFixPlan, applyAutoFixAction, getNpmInstallsFromActions } from "@greenarmor/ges-mcp-server";
5
+ import { appendFixHistory, createFixHistoryEntry } from "@greenarmor/ges-core";
6
+ import { getAllPacks } from "@greenarmor/ges-policy-engine";
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+ function loadProjectControls(root) {
10
+ try {
11
+ const configPath = path.join(root, ".ges", "config.json");
12
+ if (!fs.existsSync(configPath))
13
+ return [];
14
+ const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
15
+ const fwLower = new Set(config.frameworks.map((f) => f.toLowerCase()));
16
+ const allPacks = getAllPacks();
17
+ const filtered = allPacks.filter(pack => fwLower.has(pack.id.toLowerCase()));
18
+ return filtered.flatMap((p) => p.controls);
19
+ }
20
+ catch {
21
+ return [];
22
+ }
23
+ }
5
24
  export const fixCommand = new Command("fix")
6
25
  .description("Automatically fix security and compliance findings")
7
26
  .option("-d, --dry-run", "Show what would be fixed without making changes")
@@ -14,6 +33,13 @@ export const fixCommand = new Command("fix")
14
33
  console.log(" Scanning project files...");
15
34
  const { findings: rawFindings, scannedFiles } = runAudit(root);
16
35
  const findings = deduplicateFindings(rawFindings);
36
+ const projectControls = loadProjectControls(root);
37
+ try {
38
+ fs.writeFileSync(path.join(root, ".ges", "last-audit.json"), JSON.stringify({
39
+ findings, scannedFiles, timestamp: new Date().toISOString(),
40
+ }, null, 2));
41
+ }
42
+ catch { /* ignore persistence errors */ }
17
43
  console.log(` Scanned ${scannedFiles} files`);
18
44
  console.log(` Found ${findings.length} findings\n`);
19
45
  if (findings.length === 0) {
@@ -45,11 +71,35 @@ export const fixCommand = new Command("fix")
45
71
  }
46
72
  let applied = 0;
47
73
  let failed = 0;
74
+ const historyEntries = [];
48
75
  for (const action of actions) {
76
+ const matchingFindings = findings.filter(f => f.ruleId === action.ruleId);
77
+ const primaryFinding = matchingFindings[0];
78
+ const matchedControls = primaryFinding
79
+ ? projectControls.filter((c) => primaryFinding.controlIds.includes(c.id))
80
+ : [];
49
81
  if (dryRun) {
50
82
  console.log(` [${action.type}] ${action.filePath}`);
51
83
  console.log(` ${action.description} [${action.ruleId}]`);
52
84
  applied++;
85
+ historyEntries.push(createFixHistoryEntry({
86
+ source: "cli",
87
+ dry_run: true,
88
+ finding: primaryFinding ?? {
89
+ ruleId: action.ruleId,
90
+ severity: "medium",
91
+ category: "",
92
+ title: action.description,
93
+ file: "",
94
+ evidence: "",
95
+ description: action.description,
96
+ controlIds: [],
97
+ fix: action.description,
98
+ },
99
+ action,
100
+ controls: matchedControls,
101
+ applied: false,
102
+ }));
53
103
  }
54
104
  else {
55
105
  const result = applyAutoFixAction(root, action);
@@ -62,8 +112,31 @@ export const fixCommand = new Command("fix")
62
112
  console.log(` ${result.error}`);
63
113
  failed++;
64
114
  }
115
+ historyEntries.push(createFixHistoryEntry({
116
+ source: "cli",
117
+ dry_run: false,
118
+ finding: primaryFinding ?? {
119
+ ruleId: action.ruleId,
120
+ severity: "medium",
121
+ category: "",
122
+ title: action.description,
123
+ file: "",
124
+ evidence: "",
125
+ description: action.description,
126
+ controlIds: [],
127
+ fix: action.description,
128
+ },
129
+ action,
130
+ controls: matchedControls,
131
+ applied: result.applied,
132
+ error: result.applied ? undefined : result.error,
133
+ }));
65
134
  }
66
135
  }
136
+ if (historyEntries.length > 0 && !dryRun) {
137
+ appendFixHistory(root, historyEntries);
138
+ console.log(`\n Fix history recorded in .ges/fix-history.json`);
139
+ }
67
140
  console.log("");
68
141
  console.log(` Fixes ${dryRun ? "planned" : "applied"}: ${applied}${failed > 0 ? ` (${failed} failed)` : ""}`);
69
142
  if (npmInstalls.length > 0) {
package/package.json CHANGED
@@ -3,19 +3,19 @@
3
3
  "ges": "./dist/cli.js"
4
4
  },
5
5
  "dependencies": {
6
- "@greenarmor/ges-audit-engine": "1.2.0",
7
- "@greenarmor/ges-cicd-generator": "1.2.0",
8
- "@greenarmor/ges-compliance-engine": "1.2.0",
9
- "@greenarmor/ges-core": "1.2.0",
10
- "@greenarmor/ges-doc-generator": "1.2.0",
11
- "@greenarmor/ges-git-hooks": "1.2.0",
12
- "@greenarmor/ges-mcp-server": "1.2.0",
13
- "@greenarmor/ges-policy-engine": "1.2.0",
14
- "@greenarmor/ges-report-generator": "1.2.0",
15
- "@greenarmor/ges-rules-engine": "1.2.0",
16
- "@greenarmor/ges-scanner-integration": "1.2.0",
17
- "@greenarmor/ges-scoring-engine": "1.2.0",
18
- "@greenarmor/ges-web-dashboard": "1.2.0",
6
+ "@greenarmor/ges-audit-engine": "1.2.2",
7
+ "@greenarmor/ges-cicd-generator": "1.2.2",
8
+ "@greenarmor/ges-compliance-engine": "1.2.2",
9
+ "@greenarmor/ges-core": "1.2.2",
10
+ "@greenarmor/ges-doc-generator": "1.2.2",
11
+ "@greenarmor/ges-git-hooks": "1.2.2",
12
+ "@greenarmor/ges-mcp-server": "1.2.2",
13
+ "@greenarmor/ges-policy-engine": "1.2.2",
14
+ "@greenarmor/ges-report-generator": "1.2.2",
15
+ "@greenarmor/ges-rules-engine": "1.2.2",
16
+ "@greenarmor/ges-scanner-integration": "1.2.2",
17
+ "@greenarmor/ges-scoring-engine": "1.2.2",
18
+ "@greenarmor/ges-web-dashboard": "1.2.2",
19
19
  "commander": "^13.0.0"
20
20
  },
21
21
  "description": "Green Engineering Standard Framework - Compliance-as-Code CLI",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "type": "module",
55
55
  "types": "./dist/index.d.ts",
56
- "version": "1.2.0",
56
+ "version": "1.2.2",
57
57
  "scripts": {
58
58
  "build": "tsc",
59
59
  "clean": "rm -rf dist tsconfig.tsbuildinfo",