@shipsafe/cli 0.1.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 (166) hide show
  1. package/README.md +167 -0
  2. package/dist/bin/shipsafe.d.ts +3 -0
  3. package/dist/bin/shipsafe.d.ts.map +1 -0
  4. package/dist/bin/shipsafe.js +33 -0
  5. package/dist/bin/shipsafe.js.map +1 -0
  6. package/dist/src/autofix/pr-generator.d.ts +48 -0
  7. package/dist/src/autofix/pr-generator.d.ts.map +1 -0
  8. package/dist/src/autofix/pr-generator.js +359 -0
  9. package/dist/src/autofix/pr-generator.js.map +1 -0
  10. package/dist/src/autofix/scaffolding.d.ts +26 -0
  11. package/dist/src/autofix/scaffolding.d.ts.map +1 -0
  12. package/dist/src/autofix/scaffolding.js +249 -0
  13. package/dist/src/autofix/scaffolding.js.map +1 -0
  14. package/dist/src/autofix/secret-fixer.d.ts +27 -0
  15. package/dist/src/autofix/secret-fixer.d.ts.map +1 -0
  16. package/dist/src/autofix/secret-fixer.js +138 -0
  17. package/dist/src/autofix/secret-fixer.js.map +1 -0
  18. package/dist/src/claude-md/manager.d.ts +17 -0
  19. package/dist/src/claude-md/manager.d.ts.map +1 -0
  20. package/dist/src/claude-md/manager.js +143 -0
  21. package/dist/src/claude-md/manager.js.map +1 -0
  22. package/dist/src/cli/activate.d.ts +4 -0
  23. package/dist/src/cli/activate.d.ts.map +1 -0
  24. package/dist/src/cli/activate.js +53 -0
  25. package/dist/src/cli/activate.js.map +1 -0
  26. package/dist/src/cli/config.d.ts +21 -0
  27. package/dist/src/cli/config.d.ts.map +1 -0
  28. package/dist/src/cli/config.js +128 -0
  29. package/dist/src/cli/config.js.map +1 -0
  30. package/dist/src/cli/connect.d.ts +36 -0
  31. package/dist/src/cli/connect.d.ts.map +1 -0
  32. package/dist/src/cli/connect.js +107 -0
  33. package/dist/src/cli/connect.js.map +1 -0
  34. package/dist/src/cli/init.d.ts +12 -0
  35. package/dist/src/cli/init.d.ts.map +1 -0
  36. package/dist/src/cli/init.js +45 -0
  37. package/dist/src/cli/init.js.map +1 -0
  38. package/dist/src/cli/license-check.d.ts +7 -0
  39. package/dist/src/cli/license-check.d.ts.map +1 -0
  40. package/dist/src/cli/license-check.js +69 -0
  41. package/dist/src/cli/license-check.js.map +1 -0
  42. package/dist/src/cli/license-gate.d.ts +9 -0
  43. package/dist/src/cli/license-gate.d.ts.map +1 -0
  44. package/dist/src/cli/license-gate.js +25 -0
  45. package/dist/src/cli/license-gate.js.map +1 -0
  46. package/dist/src/cli/scan.d.ts +9 -0
  47. package/dist/src/cli/scan.d.ts.map +1 -0
  48. package/dist/src/cli/scan.js +75 -0
  49. package/dist/src/cli/scan.js.map +1 -0
  50. package/dist/src/cli/setup.d.ts +27 -0
  51. package/dist/src/cli/setup.d.ts.map +1 -0
  52. package/dist/src/cli/setup.js +134 -0
  53. package/dist/src/cli/setup.js.map +1 -0
  54. package/dist/src/cli/status.d.ts +4 -0
  55. package/dist/src/cli/status.d.ts.map +1 -0
  56. package/dist/src/cli/status.js +52 -0
  57. package/dist/src/cli/status.js.map +1 -0
  58. package/dist/src/cli/upload-sourcemaps.d.ts +13 -0
  59. package/dist/src/cli/upload-sourcemaps.d.ts.map +1 -0
  60. package/dist/src/cli/upload-sourcemaps.js +157 -0
  61. package/dist/src/cli/upload-sourcemaps.js.map +1 -0
  62. package/dist/src/config/manager.d.ts +37 -0
  63. package/dist/src/config/manager.d.ts.map +1 -0
  64. package/dist/src/config/manager.js +131 -0
  65. package/dist/src/config/manager.js.map +1 -0
  66. package/dist/src/constants.d.ts +28 -0
  67. package/dist/src/constants.d.ts.map +1 -0
  68. package/dist/src/constants.js +34 -0
  69. package/dist/src/constants.js.map +1 -0
  70. package/dist/src/engines/graph/data-flow.d.ts +36 -0
  71. package/dist/src/engines/graph/data-flow.d.ts.map +1 -0
  72. package/dist/src/engines/graph/data-flow.js +189 -0
  73. package/dist/src/engines/graph/data-flow.js.map +1 -0
  74. package/dist/src/engines/graph/index.d.ts +20 -0
  75. package/dist/src/engines/graph/index.d.ts.map +1 -0
  76. package/dist/src/engines/graph/index.js +100 -0
  77. package/dist/src/engines/graph/index.js.map +1 -0
  78. package/dist/src/engines/graph/parser.d.ts +13 -0
  79. package/dist/src/engines/graph/parser.d.ts.map +1 -0
  80. package/dist/src/engines/graph/parser.js +620 -0
  81. package/dist/src/engines/graph/parser.js.map +1 -0
  82. package/dist/src/engines/graph/queries.d.ts +11 -0
  83. package/dist/src/engines/graph/queries.d.ts.map +1 -0
  84. package/dist/src/engines/graph/queries.js +196 -0
  85. package/dist/src/engines/graph/queries.js.map +1 -0
  86. package/dist/src/engines/graph/store.d.ts +35 -0
  87. package/dist/src/engines/graph/store.d.ts.map +1 -0
  88. package/dist/src/engines/graph/store.js +284 -0
  89. package/dist/src/engines/graph/store.js.map +1 -0
  90. package/dist/src/engines/pattern/gitleaks.d.ts +4 -0
  91. package/dist/src/engines/pattern/gitleaks.d.ts.map +1 -0
  92. package/dist/src/engines/pattern/gitleaks.js +78 -0
  93. package/dist/src/engines/pattern/gitleaks.js.map +1 -0
  94. package/dist/src/engines/pattern/index.d.ts +11 -0
  95. package/dist/src/engines/pattern/index.d.ts.map +1 -0
  96. package/dist/src/engines/pattern/index.js +111 -0
  97. package/dist/src/engines/pattern/index.js.map +1 -0
  98. package/dist/src/engines/pattern/semgrep.d.ts +4 -0
  99. package/dist/src/engines/pattern/semgrep.d.ts.map +1 -0
  100. package/dist/src/engines/pattern/semgrep.js +83 -0
  101. package/dist/src/engines/pattern/semgrep.js.map +1 -0
  102. package/dist/src/engines/pattern/trivy.d.ts +4 -0
  103. package/dist/src/engines/pattern/trivy.d.ts.map +1 -0
  104. package/dist/src/engines/pattern/trivy.js +90 -0
  105. package/dist/src/engines/pattern/trivy.js.map +1 -0
  106. package/dist/src/github/api.d.ts +19 -0
  107. package/dist/src/github/api.d.ts.map +1 -0
  108. package/dist/src/github/api.js +75 -0
  109. package/dist/src/github/api.js.map +1 -0
  110. package/dist/src/github/app-manifest.d.ts +28 -0
  111. package/dist/src/github/app-manifest.d.ts.map +1 -0
  112. package/dist/src/github/app-manifest.js +27 -0
  113. package/dist/src/github/app-manifest.js.map +1 -0
  114. package/dist/src/github/checks.d.ts +36 -0
  115. package/dist/src/github/checks.d.ts.map +1 -0
  116. package/dist/src/github/checks.js +90 -0
  117. package/dist/src/github/checks.js.map +1 -0
  118. package/dist/src/github/scanner.d.ts +20 -0
  119. package/dist/src/github/scanner.d.ts.map +1 -0
  120. package/dist/src/github/scanner.js +78 -0
  121. package/dist/src/github/scanner.js.map +1 -0
  122. package/dist/src/github/webhook.d.ts +39 -0
  123. package/dist/src/github/webhook.d.ts.map +1 -0
  124. package/dist/src/github/webhook.js +80 -0
  125. package/dist/src/github/webhook.js.map +1 -0
  126. package/dist/src/hooks/installer.d.ts +4 -0
  127. package/dist/src/hooks/installer.d.ts.map +1 -0
  128. package/dist/src/hooks/installer.js +146 -0
  129. package/dist/src/hooks/installer.js.map +1 -0
  130. package/dist/src/mcp/server.d.ts +2 -0
  131. package/dist/src/mcp/server.d.ts.map +1 -0
  132. package/dist/src/mcp/server.js +96 -0
  133. package/dist/src/mcp/server.js.map +1 -0
  134. package/dist/src/mcp/tools/check-package.d.ts +30 -0
  135. package/dist/src/mcp/tools/check-package.d.ts.map +1 -0
  136. package/dist/src/mcp/tools/check-package.js +196 -0
  137. package/dist/src/mcp/tools/check-package.js.map +1 -0
  138. package/dist/src/mcp/tools/fix.d.ts +41 -0
  139. package/dist/src/mcp/tools/fix.d.ts.map +1 -0
  140. package/dist/src/mcp/tools/fix.js +98 -0
  141. package/dist/src/mcp/tools/fix.js.map +1 -0
  142. package/dist/src/mcp/tools/graph-query.d.ts +7 -0
  143. package/dist/src/mcp/tools/graph-query.d.ts.map +1 -0
  144. package/dist/src/mcp/tools/graph-query.js +139 -0
  145. package/dist/src/mcp/tools/graph-query.js.map +1 -0
  146. package/dist/src/mcp/tools/production-errors.d.ts +23 -0
  147. package/dist/src/mcp/tools/production-errors.d.ts.map +1 -0
  148. package/dist/src/mcp/tools/production-errors.js +46 -0
  149. package/dist/src/mcp/tools/production-errors.js.map +1 -0
  150. package/dist/src/mcp/tools/scan.d.ts +7 -0
  151. package/dist/src/mcp/tools/scan.d.ts.map +1 -0
  152. package/dist/src/mcp/tools/scan.js +9 -0
  153. package/dist/src/mcp/tools/scan.js.map +1 -0
  154. package/dist/src/mcp/tools/status.d.ts +9 -0
  155. package/dist/src/mcp/tools/status.d.ts.map +1 -0
  156. package/dist/src/mcp/tools/status.js +18 -0
  157. package/dist/src/mcp/tools/status.js.map +1 -0
  158. package/dist/src/mcp/tools/verify-resolution.d.ts +12 -0
  159. package/dist/src/mcp/tools/verify-resolution.d.ts.map +1 -0
  160. package/dist/src/mcp/tools/verify-resolution.js +45 -0
  161. package/dist/src/mcp/tools/verify-resolution.js.map +1 -0
  162. package/dist/src/types.d.ts +136 -0
  163. package/dist/src/types.d.ts.map +1 -0
  164. package/dist/src/types.js +2 -0
  165. package/dist/src/types.js.map +1 -0
  166. package/package.json +53 -0
@@ -0,0 +1,196 @@
1
+ // Popular packages to check for typosquatting
2
+ const POPULAR_PACKAGES = [
3
+ 'react',
4
+ 'express',
5
+ 'lodash',
6
+ 'axios',
7
+ 'moment',
8
+ 'chalk',
9
+ 'commander',
10
+ 'next',
11
+ 'vue',
12
+ 'angular',
13
+ 'webpack',
14
+ 'typescript',
15
+ 'zod',
16
+ 'prisma',
17
+ 'drizzle',
18
+ 'hono',
19
+ 'fastify',
20
+ ];
21
+ // Licenses generally considered compatible with most projects
22
+ const COMPATIBLE_LICENSES = [
23
+ 'MIT',
24
+ 'ISC',
25
+ 'BSD-2-Clause',
26
+ 'BSD-3-Clause',
27
+ 'Apache-2.0',
28
+ '0BSD',
29
+ 'Unlicense',
30
+ 'CC0-1.0',
31
+ 'BlueOak-1.0.0',
32
+ ];
33
+ /**
34
+ * Compute Levenshtein edit distance between two strings.
35
+ */
36
+ export function editDistance(a, b) {
37
+ const m = a.length;
38
+ const n = b.length;
39
+ // Create a 2D array for dynamic programming
40
+ const dp = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0));
41
+ for (let i = 0; i <= m; i++)
42
+ dp[i][0] = i;
43
+ for (let j = 0; j <= n; j++)
44
+ dp[0][j] = j;
45
+ for (let i = 1; i <= m; i++) {
46
+ for (let j = 1; j <= n; j++) {
47
+ if (a[i - 1] === b[j - 1]) {
48
+ dp[i][j] = dp[i - 1][j - 1];
49
+ }
50
+ else {
51
+ dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
52
+ }
53
+ }
54
+ }
55
+ return dp[m][n];
56
+ }
57
+ /**
58
+ * Check if a package name looks like a typosquat of a popular package.
59
+ */
60
+ export function checkTyposquat(name) {
61
+ for (const popular of POPULAR_PACKAGES) {
62
+ if (name === popular) {
63
+ // Exact match — not a typosquat
64
+ continue;
65
+ }
66
+ const distance = editDistance(name.toLowerCase(), popular.toLowerCase());
67
+ if (distance <= 2) {
68
+ return { isTyposquat: true, similarTo: popular };
69
+ }
70
+ }
71
+ return { isTyposquat: false };
72
+ }
73
+ export async function handleCheckPackage(params) {
74
+ const { name, version, registry = 'npm' } = params;
75
+ // Currently only npm is supported
76
+ if (registry !== 'npm') {
77
+ return {
78
+ name,
79
+ version: version ?? 'latest',
80
+ safe: false,
81
+ cves: [],
82
+ license: 'unknown',
83
+ license_compatible: false,
84
+ maintained: false,
85
+ last_publish: 'unknown',
86
+ typosquat_warning: false,
87
+ recommendation: `Registry "${registry}" is not yet supported. Only npm is currently available.`,
88
+ };
89
+ }
90
+ // Check typosquatting first (doesn't need network)
91
+ const typosquatCheck = checkTyposquat(name);
92
+ // Fetch package info from npm registry
93
+ let npmData;
94
+ try {
95
+ const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(name)}`;
96
+ const response = await fetch(registryUrl);
97
+ if (!response.ok) {
98
+ if (response.status === 404) {
99
+ return {
100
+ name,
101
+ version: version ?? 'latest',
102
+ safe: false,
103
+ cves: [],
104
+ license: 'unknown',
105
+ license_compatible: false,
106
+ maintained: false,
107
+ last_publish: 'unknown',
108
+ typosquat_warning: typosquatCheck.isTyposquat,
109
+ recommendation: `Package "${name}" not found on npm registry.${typosquatCheck.isTyposquat
110
+ ? ` WARNING: This name is similar to "${typosquatCheck.similarTo}" — possible typosquat.`
111
+ : ''}`,
112
+ };
113
+ }
114
+ return {
115
+ name,
116
+ version: version ?? 'latest',
117
+ safe: false,
118
+ cves: [],
119
+ license: 'unknown',
120
+ license_compatible: false,
121
+ maintained: false,
122
+ last_publish: 'unknown',
123
+ typosquat_warning: typosquatCheck.isTyposquat,
124
+ recommendation: `Failed to fetch package info: HTTP ${response.status}`,
125
+ };
126
+ }
127
+ npmData = (await response.json());
128
+ }
129
+ catch (err) {
130
+ const message = err instanceof Error ? err.message : String(err);
131
+ return {
132
+ name,
133
+ version: version ?? 'latest',
134
+ safe: false,
135
+ cves: [],
136
+ license: 'unknown',
137
+ license_compatible: false,
138
+ maintained: false,
139
+ last_publish: 'unknown',
140
+ typosquat_warning: typosquatCheck.isTyposquat,
141
+ recommendation: `Failed to fetch package info: ${message}`,
142
+ };
143
+ }
144
+ // Determine version
145
+ const resolvedVersion = version ?? npmData['dist-tags']?.latest ?? 'unknown';
146
+ // Check license
147
+ const license = npmData.license ?? 'unknown';
148
+ const licenseCompatible = COMPATIBLE_LICENSES.includes(license);
149
+ // Check maintenance — last publish date
150
+ const timeEntries = npmData.time ?? {};
151
+ const modified = timeEntries.modified ?? timeEntries[resolvedVersion];
152
+ const lastPublish = modified ?? 'unknown';
153
+ let maintained = true;
154
+ if (lastPublish !== 'unknown') {
155
+ const lastPublishDate = new Date(lastPublish);
156
+ const twoYearsAgo = new Date();
157
+ twoYearsAgo.setFullYear(twoYearsAgo.getFullYear() - 2);
158
+ maintained = lastPublishDate > twoYearsAgo;
159
+ }
160
+ // Check if the resolved version is deprecated
161
+ const isDeprecated = !!(npmData.versions?.[resolvedVersion]?.deprecated);
162
+ // Build recommendation
163
+ const warnings = [];
164
+ if (typosquatCheck.isTyposquat) {
165
+ warnings.push(`TYPOSQUAT WARNING: "${name}" is similar to "${typosquatCheck.similarTo}". Verify this is the intended package.`);
166
+ }
167
+ if (!maintained) {
168
+ warnings.push('Package has not been updated in over 2 years.');
169
+ }
170
+ if (!licenseCompatible) {
171
+ warnings.push(`License "${license}" may not be compatible with your project.`);
172
+ }
173
+ if (isDeprecated) {
174
+ warnings.push('This version is deprecated.');
175
+ }
176
+ const safe = !typosquatCheck.isTyposquat &&
177
+ maintained &&
178
+ licenseCompatible &&
179
+ !isDeprecated;
180
+ const recommendation = warnings.length === 0
181
+ ? `Package "${name}@${resolvedVersion}" appears safe to install.`
182
+ : warnings.join(' ');
183
+ return {
184
+ name,
185
+ version: resolvedVersion,
186
+ safe,
187
+ cves: [], // CVE checking will be expanded in future phases
188
+ license,
189
+ license_compatible: licenseCompatible,
190
+ maintained,
191
+ last_publish: lastPublish,
192
+ typosquat_warning: typosquatCheck.isTyposquat,
193
+ recommendation,
194
+ };
195
+ }
196
+ //# sourceMappingURL=check-package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-package.js","sourceRoot":"","sources":["../../../../src/mcp/tools/check-package.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface FixParams {
2
+ finding_id: string;
3
+ strategy?: 'suggested' | 'custom';
4
+ }
5
+ export interface FixResult {
6
+ status: 'fixed' | 'suggestion_only';
7
+ files_modified: string[];
8
+ description: string;
9
+ }
10
+ declare let lastScanFindings: Array<{
11
+ id: string;
12
+ type: string;
13
+ file: string;
14
+ line: number;
15
+ description: string;
16
+ fix_suggestion: string;
17
+ auto_fixable: boolean;
18
+ }>;
19
+ /**
20
+ * Store findings from the most recent scan for lookup by the fix tool.
21
+ */
22
+ export declare function cacheFindings(findings: Array<{
23
+ id: string;
24
+ type: string;
25
+ file: string;
26
+ line: number;
27
+ description: string;
28
+ fix_suggestion: string;
29
+ auto_fixable: boolean;
30
+ }>): void;
31
+ /**
32
+ * Clear the findings cache (useful for tests).
33
+ */
34
+ export declare function clearFindingsCache(): void;
35
+ /**
36
+ * Get cached findings (useful for tests).
37
+ */
38
+ export declare function getCachedFindings(): typeof lastScanFindings;
39
+ export declare function handleFix(params: FixParams): Promise<FixResult>;
40
+ export {};
41
+ //# sourceMappingURL=fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/fix.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACpC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,QAAA,IAAI,gBAAgB,EAAE,KAAK,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAM,CAAC;AAER;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,KAAK,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,GACD,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,gBAAgB,CAE3D;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CA4ErE"}
@@ -0,0 +1,98 @@
1
+ import { fixHardcodedSecret } from '../../autofix/secret-fixer.js';
2
+ import { generateFix } from '../../autofix/pr-generator.js';
3
+ import * as fs from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ // In-memory cache of findings from the last scan
6
+ let lastScanFindings = [];
7
+ /**
8
+ * Store findings from the most recent scan for lookup by the fix tool.
9
+ */
10
+ export function cacheFindings(findings) {
11
+ lastScanFindings = [...findings];
12
+ }
13
+ /**
14
+ * Clear the findings cache (useful for tests).
15
+ */
16
+ export function clearFindingsCache() {
17
+ lastScanFindings = [];
18
+ }
19
+ /**
20
+ * Get cached findings (useful for tests).
21
+ */
22
+ export function getCachedFindings() {
23
+ return lastScanFindings;
24
+ }
25
+ export async function handleFix(params) {
26
+ const { finding_id, strategy = 'suggested' } = params;
27
+ // Look up the finding
28
+ const finding = lastScanFindings.find((f) => f.id === finding_id);
29
+ if (!finding) {
30
+ return {
31
+ status: 'suggestion_only',
32
+ files_modified: [],
33
+ description: `Finding ${finding_id} not found in last scan results. Run shipsafe_scan first.`,
34
+ };
35
+ }
36
+ // For hardcoded secrets with suggested strategy, use the autofix secret-fixer
37
+ if (strategy === 'suggested' && finding.type === 'hardcoded-secret') {
38
+ try {
39
+ const result = await fixHardcodedSecret({
40
+ id: finding.id,
41
+ engine: 'pattern',
42
+ severity: 'high',
43
+ type: finding.type,
44
+ file: finding.file,
45
+ line: finding.line,
46
+ description: finding.description,
47
+ fix_suggestion: finding.fix_suggestion,
48
+ auto_fixable: finding.auto_fixable,
49
+ });
50
+ return {
51
+ status: 'fixed',
52
+ files_modified: result.filesModified,
53
+ description: `Moved hardcoded secret to .env as ${result.envVarName} and replaced with process.env.${result.envVarName}`,
54
+ };
55
+ }
56
+ catch (err) {
57
+ const message = err instanceof Error ? err.message : String(err);
58
+ return {
59
+ status: 'suggestion_only',
60
+ files_modified: [],
61
+ description: `Auto-fix failed: ${message}. Apply fix manually: move secret to .env and use process.env reference.`,
62
+ };
63
+ }
64
+ }
65
+ // For other auto-fixable findings, try the generateFix engine
66
+ if (strategy === 'suggested' && finding.auto_fixable) {
67
+ try {
68
+ const filePath = path.resolve(process.cwd(), finding.file);
69
+ const content = await fs.readFile(filePath, 'utf-8');
70
+ const error = {
71
+ id: finding.id,
72
+ message: finding.description,
73
+ severity: 'high',
74
+ file: finding.file,
75
+ line: finding.line,
76
+ };
77
+ const patch = generateFix(error, content);
78
+ if (patch) {
79
+ await fs.writeFile(filePath, patch.fixed, 'utf-8');
80
+ return {
81
+ status: 'fixed',
82
+ files_modified: [finding.file],
83
+ description: patch.description,
84
+ };
85
+ }
86
+ }
87
+ catch {
88
+ // Fall through to suggestion_only
89
+ }
90
+ }
91
+ // For all other findings, return the suggestion for manual implementation
92
+ return {
93
+ status: 'suggestion_only',
94
+ files_modified: [],
95
+ description: finding.fix_suggestion,
96
+ };
97
+ }
98
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../../../src/mcp/tools/fix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface GraphQueryParams {
2
+ query_type: 'callers' | 'callees' | 'data_flow' | 'attack_paths' | 'blast_radius' | 'auth_chain';
3
+ target?: string;
4
+ depth?: number;
5
+ }
6
+ export declare function handleGraphQuery(params: GraphQueryParams): Promise<object>;
7
+ //# sourceMappingURL=graph-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-query.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/graph-query.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;IACjG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0IhF"}
@@ -0,0 +1,139 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import { rm, mkdir } from 'node:fs/promises';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { initParser, parseProject } from '../../engines/graph/parser.js';
6
+ import { createGraphStore } from '../../engines/graph/store.js';
7
+ import { findAttackPaths, findBlastRadius, findMissingAuth, } from '../../engines/graph/queries.js';
8
+ // ── Handler ──
9
+ export async function handleGraphQuery(params) {
10
+ const { query_type, target, depth } = params;
11
+ const projectDir = process.cwd();
12
+ // Initialize parser
13
+ await initParser();
14
+ // Parse the project
15
+ const parsedFiles = await parseProject(projectDir);
16
+ // Create a temporary graph store
17
+ const tmpDir = path.join(os.tmpdir(), `shipsafe-graph-query-${randomUUID()}`);
18
+ await mkdir(tmpDir, { recursive: true });
19
+ const store = await createGraphStore(tmpDir);
20
+ try {
21
+ // Build the graph
22
+ await store.buildGraph(parsedFiles);
23
+ switch (query_type) {
24
+ case 'callers': {
25
+ if (!target) {
26
+ return { error: 'target is required for callers query' };
27
+ }
28
+ const callers = await store.getCallers(target, depth ?? 3);
29
+ return {
30
+ query_type,
31
+ target,
32
+ depth: depth ?? 3,
33
+ results: callers.map((fn) => ({
34
+ name: fn.name,
35
+ filePath: fn.filePath,
36
+ startLine: fn.startLine,
37
+ endLine: fn.endLine,
38
+ isAsync: fn.isAsync,
39
+ isExported: fn.isExported,
40
+ className: fn.className || undefined,
41
+ })),
42
+ };
43
+ }
44
+ case 'callees': {
45
+ if (!target) {
46
+ return { error: 'target is required for callees query' };
47
+ }
48
+ const callees = await store.getCallees(target, depth ?? 3);
49
+ return {
50
+ query_type,
51
+ target,
52
+ depth: depth ?? 3,
53
+ results: callees.map((fn) => ({
54
+ name: fn.name,
55
+ filePath: fn.filePath,
56
+ startLine: fn.startLine,
57
+ endLine: fn.endLine,
58
+ isAsync: fn.isAsync,
59
+ isExported: fn.isExported,
60
+ className: fn.className || undefined,
61
+ })),
62
+ };
63
+ }
64
+ case 'data_flow': {
65
+ if (!target) {
66
+ return { error: 'target is required for data_flow query' };
67
+ }
68
+ // data_flow combines callers + callees for a complete picture
69
+ const dfCallers = await store.getCallers(target, depth ?? 5);
70
+ const dfCallees = await store.getCallees(target, depth ?? 5);
71
+ return {
72
+ query_type,
73
+ target,
74
+ depth: depth ?? 5,
75
+ callers: dfCallers.map((fn) => ({
76
+ name: fn.name,
77
+ filePath: fn.filePath,
78
+ startLine: fn.startLine,
79
+ })),
80
+ callees: dfCallees.map((fn) => ({
81
+ name: fn.name,
82
+ filePath: fn.filePath,
83
+ startLine: fn.startLine,
84
+ })),
85
+ };
86
+ }
87
+ case 'attack_paths': {
88
+ const attackPaths = await findAttackPaths(store);
89
+ return {
90
+ query_type,
91
+ results: attackPaths.map((ap) => ({
92
+ entryPoint: ap.entryPoint,
93
+ sink: ap.sink,
94
+ path: ap.path,
95
+ hasValidation: ap.hasValidation,
96
+ })),
97
+ total: attackPaths.length,
98
+ };
99
+ }
100
+ case 'blast_radius': {
101
+ if (!target) {
102
+ return { error: 'target is required for blast_radius query' };
103
+ }
104
+ const br = await findBlastRadius(store, target);
105
+ return {
106
+ query_type,
107
+ target,
108
+ affectedFunctions: br.affectedFunctions,
109
+ affectedEndpoints: br.affectedEndpoints,
110
+ totalAffected: br.totalAffected,
111
+ };
112
+ }
113
+ case 'auth_chain': {
114
+ const missingAuth = await findMissingAuth(store);
115
+ return {
116
+ query_type,
117
+ results: missingAuth.map((ma) => ({
118
+ endpoint: ma.endpoint,
119
+ reason: ma.reason,
120
+ })),
121
+ total: missingAuth.length,
122
+ };
123
+ }
124
+ default:
125
+ return { error: `Unknown query_type: ${query_type}` };
126
+ }
127
+ }
128
+ finally {
129
+ // Clean up
130
+ await store.close();
131
+ try {
132
+ await rm(tmpDir, { recursive: true, force: true });
133
+ }
134
+ catch {
135
+ // Best-effort cleanup
136
+ }
137
+ }
138
+ }
139
+ //# sourceMappingURL=graph-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-query.js","sourceRoot":"","sources":["../../../../src/mcp/tools/graph-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface ProductionErrorsParams {
2
+ severity?: 'all' | 'critical' | 'high' | 'medium' | 'low';
3
+ status?: 'open' | 'resolved' | 'all';
4
+ }
5
+ export interface ProductionError {
6
+ id: string;
7
+ message: string;
8
+ severity: string;
9
+ status: string;
10
+ stack_trace?: string;
11
+ root_cause?: string;
12
+ suggested_fix?: string;
13
+ first_seen: string;
14
+ last_seen: string;
15
+ count: number;
16
+ }
17
+ export interface ProductionErrorsResult {
18
+ errors: ProductionError[];
19
+ total: number;
20
+ warning?: string;
21
+ }
22
+ export declare function handleProductionErrors(params: ProductionErrorsParams): Promise<ProductionErrorsResult>;
23
+ //# sourceMappingURL=production-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"production-errors.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/production-errors.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAiDjC"}
@@ -0,0 +1,46 @@
1
+ import { loadConfig, getApiEndpoint } from '../../config/manager.js';
2
+ export async function handleProductionErrors(params) {
3
+ const projectDir = process.cwd();
4
+ const config = await loadConfig(projectDir);
5
+ if (!config.projectId) {
6
+ return {
7
+ errors: [],
8
+ total: 0,
9
+ warning: 'No project ID configured. Run `shipsafe setup` to connect this project.',
10
+ };
11
+ }
12
+ const apiEndpoint = getApiEndpoint(config);
13
+ const severity = params.severity ?? 'all';
14
+ const status = params.status ?? 'open';
15
+ const url = new URL(`/v1/errors/${config.projectId}`, apiEndpoint);
16
+ url.searchParams.set('severity', severity);
17
+ url.searchParams.set('status', status);
18
+ try {
19
+ const response = await fetch(url.toString(), {
20
+ headers: {
21
+ ...(config.licenseKey ? { Authorization: `Bearer ${config.licenseKey}` } : {}),
22
+ },
23
+ });
24
+ if (!response.ok) {
25
+ return {
26
+ errors: [],
27
+ total: 0,
28
+ warning: `API returned ${response.status}: ${response.statusText}`,
29
+ };
30
+ }
31
+ const data = (await response.json());
32
+ return {
33
+ errors: data.errors,
34
+ total: data.count,
35
+ };
36
+ }
37
+ catch (err) {
38
+ const message = err instanceof Error ? err.message : String(err);
39
+ return {
40
+ errors: [],
41
+ total: 0,
42
+ warning: `Failed to fetch production errors: ${message}`,
43
+ };
44
+ }
45
+ }
46
+ //# sourceMappingURL=production-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"production-errors.js","sourceRoot":"","sources":["../../../../src/mcp/tools/production-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AA0BrE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA8B;IAE9B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAE5C,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO;YACL,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,yEAAyE;SACnF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IAEvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,cAAc,MAAM,CAAC,SAAS,EAAE,EAAE,WAAW,CAAC,CAAC;IACnE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,OAAO,EAAE;gBACP,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/E;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO;gBACL,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,gBAAgB,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE;aACnE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiD,CAAC;QAErF,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO;YACL,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,sCAAsC,OAAO,EAAE;SACzD,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ScanResult } from '../../types.js';
2
+ export interface ScanParams {
3
+ scope?: string;
4
+ fix?: boolean;
5
+ }
6
+ export declare function handleScan(params: ScanParams): Promise<ScanResult>;
7
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/scan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,gBAAgB,CAAC;AAG5D,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAQxE"}
@@ -0,0 +1,9 @@
1
+ import { runPatternEngine } from '../../engines/pattern/index.js';
2
+ export async function handleScan(params) {
3
+ const scope = params.scope ?? 'staged';
4
+ const targetPath = process.cwd();
5
+ // fix is a Phase 1 stub — accepted but not acted upon
6
+ const result = await runPatternEngine({ targetPath, scope });
7
+ return result;
8
+ }
9
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../../src/mcp/tools/scan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAOlE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB;IACjD,MAAM,KAAK,GAAe,MAAM,CAAC,KAAmB,IAAI,QAAQ,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAEjC,sDAAsD;IACtD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7D,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ScannerAvailability } from '../../types.js';
2
+ export interface McpProjectStatus {
3
+ project: string;
4
+ hooks_installed: boolean;
5
+ scanners: ScannerAvailability;
6
+ license: string;
7
+ }
8
+ export declare function handleStatus(): Promise<McpProjectStatus>;
9
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAK1D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAe9D"}