@greenarmor/ges 1.2.3 → 1.2.5

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.
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized, readJsonFile, writeJsonFile } from "../utils/project.js";
3
+ import { recordActivity } from "@greenarmor/ges-core";
3
4
  import { getPacksForProjectType, getAllPacks } from "@greenarmor/ges-policy-engine";
4
5
  import { generateScoreFile, formatScoreOutput } from "@greenarmor/ges-scoring-engine";
5
6
  import { runAudit, runAuditIncremental, deduplicateFindings } from "@greenarmor/ges-audit-engine";
@@ -107,6 +108,14 @@ export const auditCommand = new Command("audit")
107
108
  if (critical.length > 0) {
108
109
  console.log(" !! Critical issues must be resolved before deployment. !!\n");
109
110
  }
111
+ recordActivity(root, {
112
+ source: "cli",
113
+ action: "audit",
114
+ title: `Compliance audit completed`,
115
+ description: `Scanned ${scannedFiles} files, found ${findings.length} findings (${critical.length} critical, ${high.length} high, ${medium.length} medium, ${low.length} low). Overall score: ${scoreData.overall}%.`,
116
+ status: critical.length > 0 ? "failed" : findings.length > 0 ? "partial" : "success",
117
+ details: { findings_count: findings.length, score: scoreData.overall, files_scanned: scannedFiles },
118
+ });
110
119
  if (options.ci && critical.length > 0) {
111
120
  process.exit(1);
112
121
  }
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized, readJsonFile, writeJsonFile } from "../utils/project.js";
3
+ import { recordActivity } from "@greenarmor/ges-core";
3
4
  import { getAllPacks } from "@greenarmor/ges-policy-engine";
4
5
  import * as path from "node:path";
5
6
  const VALID_STATUSES = ["pass", "fail", "warning", "not-applicable", "not-implemented"];
@@ -38,4 +39,11 @@ export const controlCommand = new Command("control")
38
39
  console.log(` Reason: ${options.reason || `Manually set to ${normalizedStatus}`}`);
39
40
  console.log(`\n Override saved to: ${overridePath}`);
40
41
  console.log(` Run 'ges audit' to see the updated compliance score.\n`);
42
+ recordActivity(root, {
43
+ source: "cli",
44
+ action: "control_override",
45
+ title: `Control ${controlId} → ${normalizedStatus}`,
46
+ description: `Manually set control ${control.name} (${controlId}) to ${normalizedStatus}. Reason: ${options.reason || `Manually set to ${normalizedStatus}`}`,
47
+ details: { controls_affected: [controlId] },
48
+ });
41
49
  });
@@ -2,20 +2,27 @@ 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";
5
+ import { appendFixHistory, createFixHistoryEntry, recordActivity, loadControlsFromDisk, loadControlOverrides, applyOverridesToControls } from "@greenarmor/ges-core";
6
6
  import { getAllPacks } from "@greenarmor/ges-policy-engine";
7
7
  import * as fs from "node:fs";
8
8
  import * as path from "node:path";
9
9
  function loadProjectControls(root) {
10
10
  try {
11
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);
12
+ let inMemoryControls = [];
13
+ if (fs.existsSync(configPath)) {
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
+ inMemoryControls = filtered.flatMap((p) => p.controls);
19
+ }
20
+ const diskControls = loadControlsFromDisk(root);
21
+ const seenIds = new Set(inMemoryControls.map(c => c.id));
22
+ const extraFromDisk = diskControls.filter(c => !seenIds.has(c.id));
23
+ const controls = [...inMemoryControls, ...extraFromDisk];
24
+ const overrides = loadControlOverrides(root);
25
+ return applyOverridesToControls(controls, overrides);
19
26
  }
20
27
  catch {
21
28
  return [];
@@ -154,6 +161,14 @@ export const fixCommand = new Command("fix")
154
161
  console.log(" 2. Review changes: git diff");
155
162
  console.log(" 3. Re-run audit: ges audit");
156
163
  console.log("");
164
+ recordActivity(root, {
165
+ source: "cli",
166
+ action: "fix",
167
+ title: `Auto-fix ${dryRun ? "planned" : "applied"}: ${applied} fixes`,
168
+ description: `${dryRun ? "Planned" : "Applied"} ${applied} fix(es) across ${actions.length} action(s)${failed > 0 ? ` (${failed} failed)` : ""}. Scanned ${scannedFiles} files, ${findings.length} findings found.`,
169
+ status: failed > 0 ? "partial" : "success",
170
+ details: { fixes_applied: applied, findings_count: findings.length, files_scanned: scannedFiles },
171
+ });
157
172
  if (options.ci && (findings.length > 0 && failed < findings.length) === false && findings.length > 0) {
158
173
  process.exit(1);
159
174
  }
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized, readJsonFile, writeFileSync } from "../utils/project.js";
3
+ import { recordActivity } from "@greenarmor/ges-core";
3
4
  import { generateComplianceDocs, generateSecurityDocs } from "@greenarmor/ges-doc-generator";
4
5
  import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
5
6
  import { showNextStepsMenu } from "../utils/next-steps.js";
@@ -22,6 +23,8 @@ export const generateCommand = new Command("generate")
22
23
  console.log(" Specify --docs, --workflows, or --all");
23
24
  return;
24
25
  }
26
+ let docCount = 0;
27
+ let wfCount = 0;
25
28
  if (doDocs) {
26
29
  console.log(" Generating compliance documents...");
27
30
  const complianceDocs = generateComplianceDocs(config.project_name, config.project_type);
@@ -33,6 +36,7 @@ export const generateCommand = new Command("generate")
33
36
  for (const doc of securityDocs) {
34
37
  writeFileSync(path.join(root, doc.filePath), doc.content);
35
38
  }
39
+ docCount = complianceDocs.length + securityDocs.length;
36
40
  console.log(" ✓ Documents generated");
37
41
  }
38
42
  if (doWorkflows) {
@@ -41,8 +45,16 @@ export const generateCommand = new Command("generate")
41
45
  for (const wf of workflows) {
42
46
  writeFileSync(path.join(root, wf.filePath), wf.content);
43
47
  }
48
+ wfCount = workflows.length;
44
49
  console.log(" ✓ Workflows generated");
45
50
  }
46
51
  console.log("");
52
+ recordActivity(root, {
53
+ source: "cli",
54
+ action: "generate",
55
+ title: `Generated ${docCount} docs, ${wfCount} workflows`,
56
+ description: `Regenerated ${doDocs ? `${docCount} documents` : ""}${doDocs && doWorkflows ? " and " : ""}${doWorkflows ? `${wfCount} CI/CD workflows` : ""} for ${config.project_name}.`,
57
+ details: { files_count: docCount + wfCount },
58
+ });
47
59
  await showNextStepsMenu("generate");
48
60
  });
@@ -1,6 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized } from "../utils/project.js";
3
3
  import { installHooks, uninstallHooks } from "@greenarmor/ges-git-hooks";
4
+ import { recordActivity } from "@greenarmor/ges-core";
4
5
  export const hooksCommand = new Command("hooks")
5
6
  .description("Manage GESF git hooks (pre-commit compliance enforcement)")
6
7
  .addCommand(new Command("install")
@@ -24,6 +25,12 @@ export const hooksCommand = new Command("hooks")
24
25
  console.log(" The hook will run 'ges audit' before allowing commits.");
25
26
  console.log(" To bypass: git commit --no-verify");
26
27
  console.log(" To remove: ges hooks uninstall\n");
28
+ recordActivity(root, {
29
+ source: "cli",
30
+ action: "hooks_install",
31
+ title: `Git hooks installed (${result.installed.length})`,
32
+ description: `Installed pre-commit hook that runs 'ges audit' before each commit.`,
33
+ });
27
34
  }))
28
35
  .addCommand(new Command("uninstall")
29
36
  .description("Remove the GESF pre-commit hook")
@@ -37,4 +44,10 @@ export const hooksCommand = new Command("hooks")
37
44
  console.log(` [!] ${s}`);
38
45
  }
39
46
  console.log("\n Pre-commit hook removed.\n");
47
+ recordActivity(root, {
48
+ source: "cli",
49
+ action: "hooks_uninstall",
50
+ title: `Git hooks removed`,
51
+ description: `Removed pre-commit hook.`,
52
+ });
40
53
  }));
@@ -2,6 +2,7 @@ import { Command } from "commander";
2
2
  import { input, select, checkbox } from "../utils/prompts.js";
3
3
  import { PROJECT_TYPES, FRAMEWORKS, DEFAULT_FRAMEWORKS, GES_DIR, COMPLIANCE_DIR, SECURITY_DIR, CONTROLS_DIR, POLICIES_DIR, CHECKLISTS_DIR, DOCS_DIR, REPORTS_DIR, } from "@greenarmor/ges-core";
4
4
  import { CLI_VERSION } from "../utils/version.js";
5
+ import { recordActivity } from "@greenarmor/ges-core";
5
6
  import { getPacksForProjectType } from "@greenarmor/ges-policy-engine";
6
7
  import { generateComplianceDocs, generateSecurityDocs, generateConfigJson, generateMetadataJson, generateFrameworkVersionJson, generateScoreJson, } from "@greenarmor/ges-doc-generator";
7
8
  import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
@@ -118,5 +119,12 @@ export const initCommand = new Command("init")
118
119
  console.log(" 1. Review generated compliance documents");
119
120
  console.log(" 2. Run 'ges audit' to evaluate your project");
120
121
  console.log(" 3. Run 'ges score' to see your compliance score\n");
122
+ recordActivity(process.cwd(), {
123
+ source: "cli",
124
+ action: "init",
125
+ title: `Project initialized: ${projectName}`,
126
+ description: `Initialized GESF for ${projectType} project with frameworks: ${selectedFrameworks.join(", ")}. Installed ${packs.length} policy packs: ${packs.map(p => p.id).join(", ")}.`,
127
+ details: { packs_affected: packs.map(p => p.id), frameworks_added: selectedFrameworks.map((f) => String(f)) },
128
+ });
121
129
  await showNextStepsMenu("init");
122
130
  });
@@ -1,6 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { getAllPacks, listPackIds } from "@greenarmor/ges-policy-engine";
3
3
  import { ensureGESInitialized, writeFileSync } from "../utils/project.js";
4
+ import { addFrameworkToConfig, removeFrameworkFromConfig, recordActivity } from "@greenarmor/ges-core";
4
5
  import { showNextStepsMenu } from "../utils/next-steps.js";
5
6
  import * as fs from "node:fs";
6
7
  import * as path from "node:path";
@@ -34,7 +35,19 @@ policyCmd
34
35
  const packDir = path.join(root, "controls", pack.id);
35
36
  fs.mkdirSync(packDir, { recursive: true });
36
37
  writeFileSync(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
37
- console.log(`\n ✓ Installed policy pack: ${pack.id} (${pack.controls.length} controls)\n`);
38
+ const addedToConfig = addFrameworkToConfig(root, pack.id.toUpperCase());
39
+ console.log(`\n ✓ Installed policy pack: ${pack.id} (${pack.controls.length} controls)`);
40
+ if (addedToConfig) {
41
+ console.log(` ✓ Added ${pack.id.toUpperCase()} to project frameworks in .ges/config.json`);
42
+ }
43
+ console.log(" ✓ Dashboard will now reflect this pack's controls\n");
44
+ recordActivity(root, {
45
+ source: "cli",
46
+ action: "policy_install",
47
+ title: `Installed pack: ${pack.name}`,
48
+ description: `Installed ${pack.controls.length} controls from ${pack.id} pack.${addedToConfig ? ` Added ${pack.id.toUpperCase()} to config frameworks.` : ""}`,
49
+ details: { packs_affected: [pack.id], frameworks_added: addedToConfig ? [pack.id.toUpperCase()] : [] },
50
+ });
38
51
  await showNextStepsMenu("policy-install");
39
52
  });
40
53
  policyCmd
@@ -48,7 +61,15 @@ policyCmd
48
61
  process.exit(1);
49
62
  }
50
63
  fs.rmSync(packDir, { recursive: true, force: true });
64
+ removeFrameworkFromConfig(root, packId.toUpperCase());
51
65
  console.log(`\n ✓ Removed policy pack: ${packId}\n`);
66
+ recordActivity(root, {
67
+ source: "cli",
68
+ action: "policy_remove",
69
+ title: `Removed pack: ${packId}`,
70
+ description: `Removed ${packId} pack and its controls from the project.`,
71
+ details: { packs_affected: [packId] },
72
+ });
52
73
  await showNextStepsMenu("policy-remove");
53
74
  });
54
75
  export const policyCommand = policyCmd;
@@ -1,6 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized } from "../utils/project.js";
3
3
  import { runAllScansWithSbom, formatScanResults, formatSbomResults, detectProject } from "@greenarmor/ges-scanner-integration";
4
+ import { recordActivity } from "@greenarmor/ges-core";
4
5
  import { showNextStepsMenu } from "../utils/next-steps.js";
5
6
  export const scanCommand = new Command("scan")
6
7
  .description("Run security scans")
@@ -18,6 +19,13 @@ export const scanCommand = new Command("scan")
18
19
  const results = runAllScansWithSbom(detection);
19
20
  console.log(formatScanResults(results));
20
21
  console.log(formatSbomResults(results));
22
+ recordActivity(root, {
23
+ source: "cli",
24
+ action: "scan",
25
+ title: `Security scans completed (${results.length} tools)`,
26
+ description: `Ran ${results.length} scanner(s) for ${detail} ecosystem. ${results.filter(r => r.status === "pass").length} passed, ${results.filter(r => r.status === "fail").length} failed.`,
27
+ status: results.some(r => r.status === "fail") ? "partial" : "success",
28
+ });
21
29
  if (options.ci) {
22
30
  const failed = results.filter(r => r.status === "fail");
23
31
  if (failed.length > 0) {
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { ensureGESInitialized, readJsonFile } from "../utils/project.js";
3
+ import { recordActivity } from "@greenarmor/ges-core";
3
4
  import { formatScoreOutput } from "@greenarmor/ges-scoring-engine";
4
5
  import { showNextStepsMenu } from "../utils/next-steps.js";
5
6
  import * as path from "node:path";
@@ -22,5 +23,12 @@ export const scoreCommand = new Command("score")
22
23
  console.log(formatScoreOutput(score));
23
24
  console.log(` Last evaluated: ${score.evaluated_at}\n`);
24
25
  }
26
+ recordActivity(root, {
27
+ source: "cli",
28
+ action: "score",
29
+ title: `Score displayed: ${score.overall}% (${score.overall_grade})`,
30
+ description: `Compliance score: ${score.overall}% (Grade ${score.overall_grade}) across ${Object.keys(score.frameworks).length} frameworks.`,
31
+ details: { score: score.overall },
32
+ });
25
33
  await showNextStepsMenu("score");
26
34
  });
@@ -2,6 +2,7 @@ import { Command } from "commander";
2
2
  import { ensureGESInitialized, readJsonFile } from "../utils/project.js";
3
3
  import { ProjectConfigSchema } from "@greenarmor/ges-core";
4
4
  import { GES_DIR } from "@greenarmor/ges-core";
5
+ import { recordActivity } from "@greenarmor/ges-core";
5
6
  import { showNextStepsMenu } from "../utils/next-steps.js";
6
7
  import * as fs from "node:fs";
7
8
  import * as path from "node:path";
@@ -59,6 +60,13 @@ export const validateCommand = new Command("validate")
59
60
  }
60
61
  }
61
62
  console.log(hasErrors ? "\n Validation failed.\n" : "\n All validations passed.\n");
63
+ recordActivity(root, {
64
+ source: "cli",
65
+ action: "validate",
66
+ title: `Validation ${hasErrors ? "failed" : "passed"}`,
67
+ description: hasErrors ? "Configuration or directory structure has issues." : "All configuration, controls, and directories validated successfully.",
68
+ status: hasErrors ? "failed" : "success",
69
+ });
62
70
  if (hasErrors)
63
71
  process.exit(1);
64
72
  await showNextStepsMenu("validate");
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.3",
7
- "@greenarmor/ges-cicd-generator": "1.2.3",
8
- "@greenarmor/ges-compliance-engine": "1.2.3",
9
- "@greenarmor/ges-core": "1.2.3",
10
- "@greenarmor/ges-doc-generator": "1.2.3",
11
- "@greenarmor/ges-git-hooks": "1.2.3",
12
- "@greenarmor/ges-mcp-server": "1.2.3",
13
- "@greenarmor/ges-policy-engine": "1.2.3",
14
- "@greenarmor/ges-report-generator": "1.2.3",
15
- "@greenarmor/ges-rules-engine": "1.2.3",
16
- "@greenarmor/ges-scanner-integration": "1.2.3",
17
- "@greenarmor/ges-scoring-engine": "1.2.3",
18
- "@greenarmor/ges-web-dashboard": "1.2.3",
6
+ "@greenarmor/ges-audit-engine": "1.2.5",
7
+ "@greenarmor/ges-cicd-generator": "1.2.5",
8
+ "@greenarmor/ges-compliance-engine": "1.2.5",
9
+ "@greenarmor/ges-core": "1.2.5",
10
+ "@greenarmor/ges-doc-generator": "1.2.5",
11
+ "@greenarmor/ges-git-hooks": "1.2.5",
12
+ "@greenarmor/ges-mcp-server": "1.2.5",
13
+ "@greenarmor/ges-policy-engine": "1.2.5",
14
+ "@greenarmor/ges-report-generator": "1.2.5",
15
+ "@greenarmor/ges-rules-engine": "1.2.5",
16
+ "@greenarmor/ges-scanner-integration": "1.2.5",
17
+ "@greenarmor/ges-scoring-engine": "1.2.5",
18
+ "@greenarmor/ges-web-dashboard": "1.2.5",
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.3",
56
+ "version": "1.2.5",
57
57
  "scripts": {
58
58
  "build": "tsc",
59
59
  "clean": "rm -rf dist tsconfig.tsbuildinfo",