@greenarmor/ges-mcp-server 1.5.0 → 1.5.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.
Files changed (2) hide show
  1. package/dist/server.js +24 -23
  2. package/package.json +12 -12
package/dist/server.js CHANGED
@@ -13,6 +13,7 @@ import { addFrameworkToConfig, removeFrameworkFromConfig, loadControlsFromDisk,
13
13
  import { loadGovernanceRecords, createGovernanceRecord, addGovernanceRecord, findGovernanceRecord, setGovernanceApproval, addGovernanceEvidence, createEvidenceRef, verifyGovernanceRecord, setGovernanceRiskAssessment, setGovernancePolicyBasis, setGovernanceReviewCycle, setGovernanceDataInventory, setGovernanceComplianceLinks, setGovernanceCommittee, } from "@greenarmor/ges-core";
14
14
  import { loadFixAssignments, createFixAssignment, addFixAssignment, resolveFixAssignment, findFixAssignmentsForRecord, } from "@greenarmor/ges-core";
15
15
  import { ProjectConfigSchema } from "@greenarmor/ges-core";
16
+ import { safeWriteJson, safeWriteFile } from "@greenarmor/ges-core";
16
17
  import { generateComplianceDocs, generateSecurityDocs, generateConfigJson, generateMetadataJson, generateFrameworkVersionJson, generateScoreJson } from "@greenarmor/ges-doc-generator";
17
18
  import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
18
19
  import { detectProject, runAllScansWithSbom, formatScanResults, formatSbomResults } from "@greenarmor/ges-scanner-integration";
@@ -1214,7 +1215,7 @@ export function applyAutoFixAction(root, action) {
1214
1215
  const dir = path.dirname(fullPath);
1215
1216
  if (!fs.existsSync(dir))
1216
1217
  fs.mkdirSync(dir, { recursive: true });
1217
- fs.writeFileSync(fullPath, action.content || "", "utf-8");
1218
+ safeWriteFile(fullPath, action.content || "");
1218
1219
  return { applied: true, action };
1219
1220
  }
1220
1221
  case "modify": {
@@ -1225,7 +1226,7 @@ export function applyAutoFixAction(root, action) {
1225
1226
  if (action.search && !content.includes(action.search)) {
1226
1227
  return { applied: false, action, error: "Search string not found" };
1227
1228
  }
1228
- fs.writeFileSync(fullPath, content.replace(action.search || "", action.replace || ""), "utf-8");
1229
+ safeWriteFile(fullPath, content.replace(action.search || "", action.replace || ""));
1229
1230
  return { applied: true, action };
1230
1231
  }
1231
1232
  case "append": {
@@ -2528,10 +2529,10 @@ export function handleRequest(request) {
2528
2529
  const auditedControls = updateControlsFromFindings(overriddenControls, findings);
2529
2530
  const score = generateScoreFile(auditedControls, frameworks, findings);
2530
2531
  try {
2531
- fs.writeFileSync(path.join(projectPath, ".ges", "last-audit.json"), JSON.stringify({
2532
+ safeWriteJson(path.join(projectPath, ".ges", "last-audit.json"), {
2532
2533
  findings, scannedFiles, timestamp: new Date().toISOString(),
2533
- }, null, 2));
2534
- fs.writeFileSync(path.join(projectPath, ".ges", "score.json"), JSON.stringify(score, null, 2));
2534
+ });
2535
+ safeWriteJson(path.join(projectPath, ".ges", "score.json"), score);
2535
2536
  const metaPath = path.join(projectPath, ".ges", "metadata.json");
2536
2537
  let meta = {};
2537
2538
  try {
@@ -2539,7 +2540,7 @@ export function handleRequest(request) {
2539
2540
  }
2540
2541
  catch { /* ignore */ }
2541
2542
  meta.last_audit = new Date().toISOString();
2542
- fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
2543
+ safeWriteJson(metaPath, meta);
2543
2544
  }
2544
2545
  catch { /* ignore persistence errors */ }
2545
2546
  const critical = findings.filter(f => f.severity === "critical");
@@ -2681,9 +2682,9 @@ export function handleRequest(request) {
2681
2682
  const { findings: rawFindings, scannedFiles } = runAudit(projectPath);
2682
2683
  const findings = deduplicateFindings(rawFindings);
2683
2684
  try {
2684
- fs.writeFileSync(path.join(projectPath, ".ges", "last-audit.json"), JSON.stringify({
2685
+ safeWriteJson(path.join(projectPath, ".ges", "last-audit.json"), {
2685
2686
  findings, scannedFiles, timestamp: new Date().toISOString(),
2686
- }, null, 2));
2687
+ });
2687
2688
  }
2688
2689
  catch { /* ignore persistence errors */ }
2689
2690
  if (findings.length === 0) {
@@ -2885,7 +2886,7 @@ export function handleRequest(request) {
2885
2886
  const dir = path.dirname(overridePath);
2886
2887
  if (!fs.existsSync(dir))
2887
2888
  fs.mkdirSync(dir, { recursive: true });
2888
- fs.writeFileSync(overridePath, JSON.stringify(overrides, null, 2), "utf-8");
2889
+ safeWriteJson(overridePath, overrides);
2889
2890
  const lines = [
2890
2891
  `# Control Override Applied\n`,
2891
2892
  `**Control**: ${controlId}`,
@@ -3031,7 +3032,7 @@ export function handleRequest(request) {
3031
3032
  const outputName = args.output || "badge.svg";
3032
3033
  const outputPath = path.resolve(projectPath, outputName);
3033
3034
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
3034
- fs.writeFileSync(outputPath, svg);
3035
+ safeWriteFile(outputPath, svg);
3035
3036
  const explainer = generateScoreExplainer(score);
3036
3037
  const lines = [];
3037
3038
  lines.push(`# Compliance Badge Generated\n`);
@@ -3044,7 +3045,7 @@ export function handleRequest(request) {
3044
3045
  const readmeContent = fs.readFileSync(readmePath, "utf-8");
3045
3046
  const relativeBadgePath = path.relative(path.dirname(readmePath), outputPath);
3046
3047
  const updated = injectBadgeIntoReadme(readmeContent, relativeBadgePath, explainer);
3047
- fs.writeFileSync(readmePath, updated);
3048
+ safeWriteFile(readmePath, updated);
3048
3049
  lines.push(`Badge injected into ${readmeName}`);
3049
3050
  }
3050
3051
  else {
@@ -3125,13 +3126,13 @@ export function handleRequest(request) {
3125
3126
  };
3126
3127
  fs.mkdirSync(gesDir, { recursive: true });
3127
3128
  const configJson = generateConfigJson(config);
3128
- fs.writeFileSync(path.join(gesDir, "config.json"), configJson.content);
3129
+ safeWriteFile(path.join(gesDir, "config.json"), configJson.content);
3129
3130
  const metadataJson = generateMetadataJson(config);
3130
- fs.writeFileSync(path.join(gesDir, "metadata.json"), metadataJson.content);
3131
+ safeWriteFile(path.join(gesDir, "metadata.json"), metadataJson.content);
3131
3132
  const frameworkVersionJson = generateFrameworkVersionJson();
3132
- fs.writeFileSync(path.join(gesDir, "framework-version.json"), frameworkVersionJson.content);
3133
+ safeWriteFile(path.join(gesDir, "framework-version.json"), frameworkVersionJson.content);
3133
3134
  const scoreJson = generateScoreJson();
3134
- fs.writeFileSync(path.join(gesDir, "score.json"), scoreJson.content);
3135
+ safeWriteFile(path.join(gesDir, "score.json"), scoreJson.content);
3135
3136
  const dirs = [COMPLIANCE_DIR, SECURITY_DIR, CONTROLS_DIR, POLICIES_DIR, CHECKLISTS_DIR, DOCS_DIR, REPORTS_DIR, ".dev-logs"];
3136
3137
  for (const dir of dirs) {
3137
3138
  fs.mkdirSync(path.join(projectPath, dir), { recursive: true });
@@ -3145,20 +3146,20 @@ export function handleRequest(request) {
3145
3146
  }
3146
3147
  }
3147
3148
  else {
3148
- fs.writeFileSync(gitignorePath, `# GESF developer logs (developer-only, not for remote)\n${devLogsIgnore}\n`);
3149
+ safeWriteFile(gitignorePath, `# GESF developer logs (developer-only, not for remote)\n${devLogsIgnore}\n`);
3149
3150
  }
3150
- fs.writeFileSync(path.join(projectPath, ".dev-logs", "README.md"), `# Developer Logs\n\nThis directory is part of GESF — the Green Engineering Standard Framework.\n\nIt stores development notes, session logs, AI assistant recommendations, and release notes for your project.\n\n**This directory is gitignored and intended for developers only. Do not submit to remote.**\n`);
3151
+ safeWriteFile(path.join(projectPath, ".dev-logs", "README.md"), `# Developer Logs\n\nThis directory is part of GESF — the Green Engineering Standard Framework.\n\nIt stores development notes, session logs, AI assistant recommendations, and release notes for your project.\n\n**This directory is gitignored and intended for developers only. Do not submit to remote.**\n`);
3151
3152
  const complianceDocs = generateComplianceDocs(projectName, projectType);
3152
3153
  for (const doc of complianceDocs) {
3153
3154
  const filePath = path.join(projectPath, COMPLIANCE_DIR, doc.filePath);
3154
3155
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
3155
- fs.writeFileSync(filePath, doc.content);
3156
+ safeWriteFile(filePath, doc.content);
3156
3157
  }
3157
3158
  const securityDocs = generateSecurityDocs(projectName, projectType);
3158
3159
  for (const doc of securityDocs) {
3159
3160
  const filePath = path.join(projectPath, SECURITY_DIR, doc.filePath);
3160
3161
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
3161
- fs.writeFileSync(filePath, doc.content);
3162
+ safeWriteFile(filePath, doc.content);
3162
3163
  }
3163
3164
  const installedPackIds = new Set();
3164
3165
  // Domain packs from project type
@@ -3189,7 +3190,7 @@ export function handleRequest(request) {
3189
3190
  if (pack) {
3190
3191
  const packDir = path.join(projectPath, CONTROLS_DIR, pack.id);
3191
3192
  fs.mkdirSync(packDir, { recursive: true });
3192
- fs.writeFileSync(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
3193
+ safeWriteFile(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
3193
3194
  packs.push(pack);
3194
3195
  }
3195
3196
  }
@@ -3197,7 +3198,7 @@ export function handleRequest(request) {
3197
3198
  const workflowsDir = path.join(projectPath, ".github", "workflows");
3198
3199
  fs.mkdirSync(workflowsDir, { recursive: true });
3199
3200
  for (const wf of workflows) {
3200
- fs.writeFileSync(path.join(workflowsDir, wf.filePath.replace(/^\.github\/workflows\//, "")), wf.content);
3201
+ safeWriteFile(path.join(workflowsDir, wf.filePath.replace(/^\.github\/workflows\//, "")), wf.content);
3201
3202
  }
3202
3203
  const lines = [];
3203
3204
  lines.push(`# GESF Project Initialized\n`);
@@ -3628,7 +3629,7 @@ export function handleRequest(request) {
3628
3629
  }
3629
3630
  const packDir = path.join(projectPath, CONTROLS_DIR, pack.id);
3630
3631
  fs.mkdirSync(packDir, { recursive: true });
3631
- fs.writeFileSync(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
3632
+ safeWriteJson(path.join(packDir, "controls.json"), pack.controls);
3632
3633
  const frameworksAdded = [];
3633
3634
  for (const fw of pack.frameworks) {
3634
3635
  if (addFrameworkToConfig(projectPath, fw)) {
@@ -3731,7 +3732,7 @@ export function handleRequest(request) {
3731
3732
  resultText = `A pre-commit hook already exists at ${hookPath}. Not overwriting.\nManually add 'npx ges audit --ci' to your pre-commit hook.`;
3732
3733
  break;
3733
3734
  }
3734
- fs.writeFileSync(hookPath, hookContent);
3735
+ safeWriteFile(hookPath, hookContent);
3735
3736
  fs.chmodSync(hookPath, 0o755);
3736
3737
  resultText = `✅ Installed pre-commit hook at ${hookPath}\n\nThe hook will run 'ges audit --ci' before allowing commits.\n- To bypass: \`git commit --no-verify\`\n- To remove: use \`install_hooks\` with action: "uninstall"`;
3737
3738
  recordActivity(projectPath, {
package/package.json CHANGED
@@ -3,17 +3,17 @@
3
3
  "ges-mcp": "dist/server.js"
4
4
  },
5
5
  "dependencies": {
6
- "@greenarmor/ges-audit-engine": "1.5.0",
7
- "@greenarmor/ges-cicd-generator": "1.5.0",
8
- "@greenarmor/ges-compliance-engine": "1.5.0",
9
- "@greenarmor/ges-core": "1.5.0",
10
- "@greenarmor/ges-doc-generator": "1.5.0",
11
- "@greenarmor/ges-policy-engine": "1.5.0",
12
- "@greenarmor/ges-report-generator": "1.5.0",
13
- "@greenarmor/ges-rules-engine": "1.5.0",
14
- "@greenarmor/ges-scanner-integration": "1.5.0",
15
- "@greenarmor/ges-scoring-engine": "1.5.0",
16
- "@greenarmor/ges-web-dashboard": "1.5.0"
6
+ "@greenarmor/ges-audit-engine": "1.5.2",
7
+ "@greenarmor/ges-cicd-generator": "1.5.2",
8
+ "@greenarmor/ges-compliance-engine": "1.5.2",
9
+ "@greenarmor/ges-core": "1.5.2",
10
+ "@greenarmor/ges-doc-generator": "1.5.2",
11
+ "@greenarmor/ges-policy-engine": "1.5.2",
12
+ "@greenarmor/ges-report-generator": "1.5.2",
13
+ "@greenarmor/ges-rules-engine": "1.5.2",
14
+ "@greenarmor/ges-scanner-integration": "1.5.2",
15
+ "@greenarmor/ges-scoring-engine": "1.5.2",
16
+ "@greenarmor/ges-web-dashboard": "1.5.2"
17
17
  },
18
18
  "description": "GESF MCP Server - AI Compliance Assistant for GDPR, OWASP, NIST, CIS. Check compliance, generate policies, assess risks via MCP protocol.",
19
19
  "devDependencies": {
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "type": "module",
69
69
  "types": "./dist/index.d.ts",
70
- "version": "1.5.0",
70
+ "version": "1.5.2",
71
71
  "scripts": {
72
72
  "build": "tsc",
73
73
  "clean": "rm -rf dist bundle tsconfig.tsbuildinfo",