@nodatachat/guard 2.1.0 → 2.2.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/dist/cli.js CHANGED
@@ -22,7 +22,6 @@ const activation_1 = require("./activation");
22
22
  const code_scanner_1 = require("./code-scanner");
23
23
  const db_scanner_1 = require("./db-scanner");
24
24
  const reporter_1 = require("./reporter");
25
- const registry_1 = require("./fixers/registry");
26
25
  const scheduler_1 = require("./fixers/scheduler");
27
26
  const VERSION = "2.0.0";
28
27
  async function main() {
@@ -35,10 +34,8 @@ async function main() {
35
34
  let failOn = null;
36
35
  let outputDir = process.cwd();
37
36
  let skipSend = false;
38
- let fixMode = "none";
39
37
  let schedulePreset;
40
38
  let ciProvider;
41
- let onlyFixers;
42
39
  for (let i = 0; i < args.length; i++) {
43
40
  switch (args[i]) {
44
41
  case "--license-key":
@@ -63,13 +60,14 @@ async function main() {
63
60
  skipSend = true;
64
61
  break;
65
62
  case "--fix-plan":
66
- fixMode = "plan";
63
+ console.log("\n ⚠ --fix-plan is deprecated. Capsule provides recommendations only.\n Run without this flag to see recommendations.\n");
67
64
  break;
68
65
  case "--fix":
69
- fixMode = "apply";
66
+ console.log("\n ⚠ --fix is deprecated. Capsule does not modify your code.\n Recommendations are provided in the scan output.\n");
70
67
  break;
71
68
  case "--fix-only":
72
- onlyFixers = args[++i]?.split(",");
69
+ i++;
70
+ console.log("\n ⚠ --fix-only is deprecated. Capsule provides recommendations only.\n");
73
71
  break;
74
72
  case "--schedule":
75
73
  schedulePreset = args[++i] || "weekly";
@@ -283,102 +281,48 @@ async function main() {
283
281
  console.log(" Your data never left your machine.");
284
282
  console.log(" Diff the two files to verify.\n");
285
283
  }
286
- // ── Step 8: Capsule — Fix Plan / Apply ──
287
- if (fixMode !== "none") {
288
- const config = loadOrCreateConfig(projectDir, { dbUrl, failOn });
289
- const fixerContext = {
290
- projectDir,
291
- dbUrl,
292
- config,
293
- scanResults: {
294
- piiFields: piiFields.map(f => ({
295
- table: f.table, column: f.column, pii_type: f.pii_type,
296
- encrypted: f.encrypted, encryption_pattern: f.encryption_pattern,
297
- })),
298
- routes: routes.map(r => ({ path: r.path, has_auth: r.has_auth, auth_type: r.auth_type })),
299
- secrets: secrets.map(s => ({
300
- file: s.file, line: s.line, type: s.type,
301
- severity: s.severity, is_env_interpolated: s.is_env_interpolated,
302
- })),
303
- rls: dbResult?.rls || [],
304
- framework: stack.framework,
305
- database: stack.database,
306
- },
307
- stack: {
308
- framework: stack.framework,
309
- database: stack.database,
310
- language: "typescript",
311
- hosting: "vercel",
312
- },
313
- };
314
- const capsuleResult = await (0, registry_1.runCapsule)(fixerContext, {
315
- mode: fixMode === "plan" ? "plan" : "apply",
316
- fixers: onlyFixers,
317
- dryRun: fixMode === "plan",
318
- }, (msg) => log(ciMode, msg));
319
- if (!ciMode) {
284
+ // ── Step 8: Recommendations ──
285
+ // NOTE: Capsule does NOT auto-fix code. We provide recommendations only.
286
+ // Applying fixes requires understanding of the target system — tables,
287
+ // relationships, business logic — and must be done by the customer's team.
288
+ if (!ciMode) {
289
+ const topFindings = metadata.findings || [];
290
+ if (topFindings.length > 0) {
320
291
  console.log("");
321
292
  console.log(" ══════════════════════════════════════");
322
- console.log(` CAPSULE ${fixMode === "plan" ? "PLAN" : "RESULTS"}`);
293
+ console.log(" RECOMMENDATIONS");
323
294
  console.log(" ══════════════════════════════════════");
324
- console.log(` Total actions: ${capsuleResult.totalActions}`);
325
- if (fixMode === "apply") {
326
- console.log(` Applied: ${capsuleResult.applied}`);
327
- console.log(` Failed: ${capsuleResult.failed}`);
328
- console.log(` Skipped: ${capsuleResult.skipped}`);
295
+ console.log(` ${topFindings.length} issues found. Top priorities:\n`);
296
+ const shown = topFindings.slice(0, 10);
297
+ for (const f of shown) {
298
+ const sev = f.severity === "critical" ? "\x1b[31mCRITICAL\x1b[0m"
299
+ : f.severity === "high" ? "\x1b[33mHIGH\x1b[0m"
300
+ : "\x1b[36mMEDIUM\x1b[0m";
301
+ console.log(` ${sev} ${f.title}`);
302
+ console.log(` \x1b[32m→ ${f.fix_suggestion}\x1b[0m`);
303
+ if (f.soc_control)
304
+ console.log(` SOC: ${f.soc_control}`);
305
+ console.log("");
329
306
  }
330
- console.log(` Manual pending: ${capsuleResult.manualPending}`);
331
- console.log(` Est. impact: +${capsuleResult.estimatedScoreImpact}% score`);
332
- console.log(` Proof hash: ${capsuleResult.proofHash.slice(0, 16)}...`);
333
- console.log(" ──────────────────────────────────────");
334
- // Print per-fixer summary
335
- for (const plan of capsuleResult.plans) {
336
- const icon = plan.actions.every(a => a.status === "applied") ? "✅"
337
- : plan.actions.some(a => a.status === "failed") ? "❌" : "📋";
338
- console.log(` ${icon} ${plan.nameHe}: ${plan.totalActions} actions (${plan.autoFixable} auto, ${plan.manualRequired} manual)`);
307
+ if (topFindings.length > 10) {
308
+ console.log(` ... and ${topFindings.length - 10} more. See full report.\n`);
339
309
  }
310
+ console.log(" ──────────────────────────────────────");
311
+ console.log(" ⚠ Capsule provides recommendations only.");
312
+ console.log(" Fixes require understanding of your system —");
313
+ console.log(" tables, relationships, and business logic.");
314
+ console.log(" Work with your team to apply changes safely.");
340
315
  console.log(" ══════════════════════════════════════\n");
341
- // Write fix plans to output dir
342
- if (capsuleResult.plans.length > 0) {
343
- const plansPath = (0, path_1.resolve)(outputDir, "nodata-fix-plan.json");
344
- (0, fs_1.writeFileSync)(plansPath, JSON.stringify(capsuleResult, null, 2), "utf-8");
345
- log(ciMode, `Fix plan saved: ${plansPath}`);
346
- // Write SQL migrations to files
347
- for (const plan of capsuleResult.plans) {
348
- for (const action of plan.actions) {
349
- if (action.type === "file-create" && action.target.includes("migrations/")) {
350
- const migPath = (0, path_1.resolve)(outputDir, action.target);
351
- const migDir = (0, path_1.resolve)(outputDir, "migrations");
352
- if (!(0, fs_1.existsSync)(migDir)) {
353
- const { mkdirSync } = require("fs");
354
- mkdirSync(migDir, { recursive: true });
355
- }
356
- (0, fs_1.writeFileSync)(migPath, action.content, "utf-8");
357
- log(ciMode, `Migration: ${migPath}`);
358
- }
359
- }
360
- }
361
- }
362
- }
363
- // Send notifications if configured
364
- if (config.notify && fixMode === "apply") {
365
- const notifyPayload = {
366
- event: capsuleResult.applied > 0 ? "fix-applied" : "scan-complete",
367
- timestamp: new Date().toISOString(),
368
- projectName: full.project_name || "unknown",
369
- projectHash: full.proof_hash?.slice(0, 16) || "",
316
+ // Save recommendations to file
317
+ const recsPath = (0, path_1.resolve)(outputDir, "nodata-recommendations.json");
318
+ (0, fs_1.writeFileSync)(recsPath, JSON.stringify({
319
+ generated_at: new Date().toISOString(),
370
320
  score: full.overall_score,
371
- previousScore: serverResponse.previous_score ?? null,
372
- delta: serverResponse.previous_score != null ? full.overall_score - serverResponse.previous_score : 0,
373
- critical: full.summary.critical_issues,
374
- high: full.summary.high_issues,
375
- medium: full.summary.medium_issues,
376
- fixesApplied: capsuleResult.applied,
377
- fixesFailed: capsuleResult.failed,
378
- scanId: activation.scan_id,
379
- proofHash: capsuleResult.proofHash,
380
- };
381
- await (0, registry_1.sendNotifications)(config, notifyPayload.event, notifyPayload, (msg) => log(ciMode, msg));
321
+ total_findings: topFindings.length,
322
+ disclaimer: "These are recommendations only. Capsule does not modify your code. Fixes require understanding of your system architecture, database schema, and business logic. Work with your development team to implement changes safely.",
323
+ recommendations: topFindings,
324
+ }, null, 2), "utf-8");
325
+ log(ciMode, `Recommendations: ${recsPath}`);
382
326
  }
383
327
  }
384
328
  // ── CI mode: exit code ──
@@ -425,14 +369,16 @@ function loadOrCreateConfig(projectDir, overrides) {
425
369
  }
426
370
  function printHelp() {
427
371
  console.log(`
428
- NoData Guard v${VERSION} — Security Scanner + Auto-Remediation Capsule
372
+ NoData Guard v${VERSION} — Security Scanner + Recommendations
373
+
374
+ Scans your project locally for security issues and provides
375
+ actionable recommendations. Your code never leaves your machine.
376
+ Capsule does NOT modify your code — only you and your team can.
429
377
 
430
378
  Usage:
431
- npx nodata-guard --license-key NDC-XXXX # Scan only
432
- npx nodata-guard --license-key NDC-XXXX --fix-plan # Scan + show fix plan
433
- npx nodata-guard --license-key NDC-XXXX --fix # Scan + apply fixes
434
- npx nodata-guard --license-key NDC-XXXX --schedule weekly # Setup CI schedule
435
- npx nodata-guard --license-key NDC-XXXX --db $DATABASE_URL --fix # Full scan + fix
379
+ npx nodata-guard --license-key NDC-XXXX # Scan + recommend
380
+ npx nodata-guard --license-key NDC-XXXX --db $DATABASE_URL # Full scan (code + DB)
381
+ npx nodata-guard --license-key NDC-XXXX --schedule weekly # Setup CI schedule
436
382
 
437
383
  Scan Options:
438
384
  --license-key <key> NoData license key (or set NDC_LICENSE env var)
@@ -443,13 +389,6 @@ function printHelp() {
443
389
  --fail-on <level> Exit 1 if issues at: critical | high | medium
444
390
  --skip-send Don't send metadata to NoData
445
391
 
446
- Capsule Options:
447
- --fix-plan Generate fix plan (dry-run, no changes)
448
- --fix Apply all auto-fixable remediation
449
- --fix-only <fixers> Only run specific fixers (comma-separated)
450
- Fixers: pii-encrypt, rls, secrets, routes-auth,
451
- headers, csrf, rate-limit, gitignore
452
-
453
392
  Schedule Options:
454
393
  --schedule <preset> Install CI workflow: daily | weekly | monthly
455
394
  --ci-provider <name> CI provider: github-actions | gitlab-ci | bitbucket | auto
@@ -458,28 +397,36 @@ function printHelp() {
458
397
  Configure in .nodata-guard.json → notify: { email, webhook, slack, telegram }
459
398
 
460
399
  Output files:
461
- nodata-full-report.json Full report — STAYS LOCAL
462
- nodata-metadata-only.json Metadata only — sent to NoData
463
- nodata-fix-plan.json Fix plan with actions
464
- migrations/*.sql Generated SQL migrations
400
+ nodata-full-report.json Full report — STAYS LOCAL
401
+ nodata-metadata-only.json Metadata only — sent to dashboard
402
+ nodata-recommendations.json Prioritized recommendations
465
403
 
466
- What we NEVER receive:
467
- Data values, emails, phones, passwords, source code, connection strings.
404
+ What we provide:
405
+ Scan find weak points (PII, routes, secrets, encryption)
406
+ ✓ Recommend — prioritized actions with SOC control mapping
407
+ ✓ Prove — cryptographic proof chain of scan results
408
+ ✓ Monitor — track score over time via dashboard
409
+
410
+ What we NEVER do:
411
+ ✗ Modify your code, database, or configuration
412
+ ✗ Receive data values, source code, or credentials
413
+
414
+ Important:
415
+ Recommendations require understanding of YOUR system —
416
+ tables, relationships, business logic. Work with your team
417
+ to implement changes safely.
468
418
 
469
419
  Examples:
470
- # Quick scan
420
+ # Scan and get recommendations
471
421
  npx nodata-guard --license-key NDC-XXXX
472
422
 
473
- # Full scan + DB probe + fix
474
- npx nodata-guard --license-key NDC-XXXX --db $DATABASE_URL --fix
475
-
476
- # Only fix security headers and CSRF
477
- npx nodata-guard --license-key NDC-XXXX --fix --fix-only headers,csrf
423
+ # Full scan with DB probe
424
+ npx nodata-guard --license-key NDC-XXXX --db $DATABASE_URL
478
425
 
479
426
  # Setup weekly CI scan with GitHub Actions
480
427
  npx nodata-guard --license-key NDC-XXXX --schedule weekly
481
428
 
482
- # CI pipeline
429
+ # CI pipeline — fail on critical issues
483
430
  npx nodata-guard --ci --fail-on critical
484
431
 
485
432
  Documentation: https://nodatacapsule.com/guard
package/dist/reporter.js CHANGED
@@ -123,7 +123,7 @@ function generateReports(input) {
123
123
  critical: criticalSecrets,
124
124
  high: highSecrets + plaintextPII,
125
125
  medium: medSecrets,
126
- fixes_available: plaintextPII, // each plaintext field has a migration fix
126
+ recommendations_available: plaintextPII, // each plaintext field has a recommendation
127
127
  },
128
128
  // Fix suggestions — safe to send (just recommendation text, no code/values)
129
129
  findings: [
@@ -203,7 +203,7 @@ function generateReports(input) {
203
203
  critical_issues: criticalSecrets,
204
204
  high_issues: highSecrets + plaintextPII,
205
205
  medium_issues: medSecrets,
206
- fixes_available: plaintextPII,
206
+ recommendations_available: plaintextPII,
207
207
  },
208
208
  proof_hash: proofHash,
209
209
  metadata_preview: metadata,
package/dist/types.d.ts CHANGED
@@ -84,7 +84,7 @@ export interface FullReport {
84
84
  critical_issues: number;
85
85
  high_issues: number;
86
86
  medium_issues: number;
87
- fixes_available: number;
87
+ recommendations_available: number;
88
88
  };
89
89
  proof_hash: string;
90
90
  metadata_preview: MetadataReport;
@@ -140,7 +140,7 @@ export interface MetadataReport {
140
140
  critical: number;
141
141
  high: number;
142
142
  medium: number;
143
- fixes_available: number;
143
+ recommendations_available: number;
144
144
  };
145
145
  findings: Array<{
146
146
  severity: "critical" | "high" | "medium" | "low";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodatachat/guard",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "NoData Guard — continuous security scanner. Runs locally, reports only metadata. Your data never leaves your machine.",
5
5
  "main": "./dist/cli.js",
6
6
  "types": "./dist/cli.d.ts",