ship-safe 6.1.1 → 6.3.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.
Files changed (49) hide show
  1. package/README.md +748 -641
  2. package/cli/agents/api-fuzzer.js +345 -345
  3. package/cli/agents/auth-bypass-agent.js +348 -348
  4. package/cli/agents/base-agent.js +272 -272
  5. package/cli/agents/cicd-scanner.js +236 -201
  6. package/cli/agents/config-auditor.js +521 -521
  7. package/cli/agents/deep-analyzer.js +6 -2
  8. package/cli/agents/git-history-scanner.js +170 -170
  9. package/cli/agents/html-reporter.js +568 -568
  10. package/cli/agents/index.js +85 -84
  11. package/cli/agents/injection-tester.js +500 -500
  12. package/cli/agents/legal-risk-agent.js +302 -0
  13. package/cli/agents/llm-redteam.js +251 -251
  14. package/cli/agents/mobile-scanner.js +231 -231
  15. package/cli/agents/orchestrator.js +322 -322
  16. package/cli/agents/pii-compliance-agent.js +301 -301
  17. package/cli/agents/scoring-engine.js +248 -248
  18. package/cli/agents/supabase-rls-agent.js +154 -154
  19. package/cli/agents/supply-chain-agent.js +650 -507
  20. package/cli/bin/ship-safe.js +464 -426
  21. package/cli/commands/agent.js +608 -608
  22. package/cli/commands/audit.js +1006 -980
  23. package/cli/commands/baseline.js +193 -193
  24. package/cli/commands/ci.js +342 -342
  25. package/cli/commands/deps.js +516 -516
  26. package/cli/commands/doctor.js +159 -159
  27. package/cli/commands/fix.js +218 -218
  28. package/cli/commands/hooks.js +268 -0
  29. package/cli/commands/init.js +407 -407
  30. package/cli/commands/legal.js +158 -0
  31. package/cli/commands/mcp.js +304 -304
  32. package/cli/commands/red-team.js +7 -1
  33. package/cli/commands/remediate.js +798 -798
  34. package/cli/commands/rotate.js +571 -571
  35. package/cli/commands/scan.js +569 -569
  36. package/cli/commands/score.js +449 -449
  37. package/cli/commands/watch.js +281 -281
  38. package/cli/hooks/patterns.js +313 -0
  39. package/cli/hooks/post-tool-use.js +140 -0
  40. package/cli/hooks/pre-tool-use.js +186 -0
  41. package/cli/index.js +73 -69
  42. package/cli/providers/llm-provider.js +397 -287
  43. package/cli/utils/autofix-rules.js +74 -74
  44. package/cli/utils/cache-manager.js +311 -311
  45. package/cli/utils/output.js +230 -230
  46. package/cli/utils/patterns.js +1121 -1121
  47. package/cli/utils/pdf-generator.js +94 -94
  48. package/package.json +69 -69
  49. package/configs/supabase/rls-templates.sql +0 -242
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Legal Command
3
+ * =============
4
+ *
5
+ * Scans dependency manifests for packages that carry legal risk:
6
+ * active DMCA takedowns, leaked-source derivatives, IP disputes,
7
+ * and license violations.
8
+ *
9
+ * USAGE:
10
+ * ship-safe legal [path] Scan for legally risky dependencies
11
+ * ship-safe legal . --json JSON output
12
+ *
13
+ * EXIT CODES:
14
+ * 0 Clean — no legally risky packages found
15
+ * 1 Findings — one or more legally risky packages detected
16
+ */
17
+
18
+ import fs from 'fs';
19
+ import path from 'path';
20
+ import chalk from 'chalk';
21
+ import ora from 'ora';
22
+ import { LegalRiskAgent } from '../agents/legal-risk-agent.js';
23
+ import * as output from '../utils/output.js';
24
+
25
+ // =============================================================================
26
+ // RISK LABELS & COLORS
27
+ // =============================================================================
28
+
29
+ const RISK_COLORS = {
30
+ dmca: chalk.red.bold,
31
+ 'ip-dispute': chalk.red,
32
+ 'leaked-source': chalk.yellow.bold,
33
+ 'license-violation': chalk.yellow,
34
+ };
35
+
36
+ const RISK_LABELS = {
37
+ dmca: 'DMCA Takedown',
38
+ 'ip-dispute': 'IP Dispute',
39
+ 'leaked-source': 'Leaked Source',
40
+ 'license-violation': 'License Violation',
41
+ };
42
+
43
+ const SEVERITY_COLORS = {
44
+ critical: chalk.bgRed.white.bold,
45
+ high: chalk.red.bold,
46
+ medium: chalk.yellow,
47
+ low: chalk.blue,
48
+ };
49
+
50
+ // =============================================================================
51
+ // MAIN COMMAND
52
+ // =============================================================================
53
+
54
+ export async function legalCommand(targetPath = '.', options = {}) {
55
+ const absolutePath = path.resolve(targetPath);
56
+
57
+ if (!fs.existsSync(absolutePath)) {
58
+ output.error(`Path does not exist: ${absolutePath}`);
59
+ process.exit(1);
60
+ }
61
+
62
+ if (!options.json) {
63
+ console.log();
64
+ output.header('Legal Risk Audit');
65
+ console.log(chalk.gray(' Scanning for DMCA notices, leaked-source derivatives, and IP disputes'));
66
+ console.log();
67
+ }
68
+
69
+ // ── Run the agent ──────────────────────────────────────────────────────────
70
+ const spinner = options.json
71
+ ? null
72
+ : ora({ text: 'Scanning dependency manifests…', color: 'cyan' }).start();
73
+
74
+ const agent = new LegalRiskAgent();
75
+ let findings = [];
76
+
77
+ try {
78
+ findings = await agent.analyze({ rootPath: absolutePath, files: [] });
79
+ if (spinner) spinner.stop();
80
+ } catch (err) {
81
+ if (spinner) spinner.stop();
82
+ output.error(`Legal scan failed: ${err.message}`);
83
+ process.exit(1);
84
+ }
85
+
86
+ // ── JSON output ────────────────────────────────────────────────────────────
87
+ if (options.json) {
88
+ console.log(JSON.stringify({ findings, total: findings.length }, null, 2));
89
+ process.exit(findings.length > 0 ? 1 : 0);
90
+ }
91
+
92
+ // ── Human-readable output ──────────────────────────────────────────────────
93
+ if (findings.length === 0) {
94
+ output.success('No legally risky packages found.');
95
+ console.log();
96
+ console.log(chalk.gray(' Scanned: package.json, requirements.txt, Cargo.toml, go.mod'));
97
+ console.log();
98
+ return;
99
+ }
100
+
101
+ // Group by severity
102
+ const bySeverity = { critical: [], high: [], medium: [], low: [] };
103
+ for (const f of findings) {
104
+ (bySeverity[f.severity] || bySeverity.medium).push(f);
105
+ }
106
+
107
+ const total = findings.length;
108
+ const critCount = bySeverity.critical.length;
109
+ const highCount = bySeverity.high.length;
110
+
111
+ // Summary line
112
+ console.log(
113
+ chalk.red.bold(` ${total} legal risk finding${total === 1 ? '' : 's'}`),
114
+ chalk.gray('—'),
115
+ critCount > 0 ? chalk.red.bold(`${critCount} critical`) + chalk.gray(', ') : '',
116
+ highCount > 0 ? chalk.red(`${highCount} high`) : '',
117
+ );
118
+ console.log();
119
+
120
+ // Print findings
121
+ for (const severity of ['critical', 'high', 'medium', 'low']) {
122
+ const group = bySeverity[severity];
123
+ if (group.length === 0) continue;
124
+
125
+ for (const f of group) {
126
+ const sevBadge = SEVERITY_COLORS[severity]
127
+ ? SEVERITY_COLORS[severity](` ${severity.toUpperCase()} `)
128
+ : chalk.gray(` ${severity.toUpperCase()} `);
129
+
130
+ // Extract risk type from rule: LEGAL_RISK_DMCA → dmca
131
+ const riskKey = f.rule
132
+ .replace('LEGAL_RISK_', '')
133
+ .toLowerCase()
134
+ .replace(/_/g, '-');
135
+ const riskColor = RISK_COLORS[riskKey] || chalk.white;
136
+ const riskLabel = RISK_LABELS[riskKey] || riskKey;
137
+
138
+ console.log(` ${sevBadge} ${chalk.white.bold(f.title)}`);
139
+ console.log(` ${riskColor(`[${riskLabel}]`)} ${chalk.gray(path.relative(absolutePath, f.file) || f.file)}`);
140
+ console.log();
141
+ console.log(` ${chalk.gray(f.description)}`);
142
+ console.log();
143
+ if (f.fix) {
144
+ console.log(` ${chalk.cyan('Fix:')} ${chalk.gray(f.fix)}`);
145
+ }
146
+ console.log();
147
+ console.log(chalk.gray(' ' + '─'.repeat(56)));
148
+ console.log();
149
+ }
150
+ }
151
+
152
+ // Footer
153
+ console.log(chalk.yellow.bold(' ⚠ Shipping legally risky packages can expose your project to IP liability.'));
154
+ console.log(chalk.gray(' Review each finding and remove the affected dependency before releasing.'));
155
+ console.log();
156
+
157
+ process.exit(1);
158
+ }