@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.
- package/README.md +167 -0
- package/dist/bin/shipsafe.d.ts +3 -0
- package/dist/bin/shipsafe.d.ts.map +1 -0
- package/dist/bin/shipsafe.js +33 -0
- package/dist/bin/shipsafe.js.map +1 -0
- package/dist/src/autofix/pr-generator.d.ts +48 -0
- package/dist/src/autofix/pr-generator.d.ts.map +1 -0
- package/dist/src/autofix/pr-generator.js +359 -0
- package/dist/src/autofix/pr-generator.js.map +1 -0
- package/dist/src/autofix/scaffolding.d.ts +26 -0
- package/dist/src/autofix/scaffolding.d.ts.map +1 -0
- package/dist/src/autofix/scaffolding.js +249 -0
- package/dist/src/autofix/scaffolding.js.map +1 -0
- package/dist/src/autofix/secret-fixer.d.ts +27 -0
- package/dist/src/autofix/secret-fixer.d.ts.map +1 -0
- package/dist/src/autofix/secret-fixer.js +138 -0
- package/dist/src/autofix/secret-fixer.js.map +1 -0
- package/dist/src/claude-md/manager.d.ts +17 -0
- package/dist/src/claude-md/manager.d.ts.map +1 -0
- package/dist/src/claude-md/manager.js +143 -0
- package/dist/src/claude-md/manager.js.map +1 -0
- package/dist/src/cli/activate.d.ts +4 -0
- package/dist/src/cli/activate.d.ts.map +1 -0
- package/dist/src/cli/activate.js +53 -0
- package/dist/src/cli/activate.js.map +1 -0
- package/dist/src/cli/config.d.ts +21 -0
- package/dist/src/cli/config.d.ts.map +1 -0
- package/dist/src/cli/config.js +128 -0
- package/dist/src/cli/config.js.map +1 -0
- package/dist/src/cli/connect.d.ts +36 -0
- package/dist/src/cli/connect.d.ts.map +1 -0
- package/dist/src/cli/connect.js +107 -0
- package/dist/src/cli/connect.js.map +1 -0
- package/dist/src/cli/init.d.ts +12 -0
- package/dist/src/cli/init.d.ts.map +1 -0
- package/dist/src/cli/init.js +45 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/license-check.d.ts +7 -0
- package/dist/src/cli/license-check.d.ts.map +1 -0
- package/dist/src/cli/license-check.js +69 -0
- package/dist/src/cli/license-check.js.map +1 -0
- package/dist/src/cli/license-gate.d.ts +9 -0
- package/dist/src/cli/license-gate.d.ts.map +1 -0
- package/dist/src/cli/license-gate.js +25 -0
- package/dist/src/cli/license-gate.js.map +1 -0
- package/dist/src/cli/scan.d.ts +9 -0
- package/dist/src/cli/scan.d.ts.map +1 -0
- package/dist/src/cli/scan.js +75 -0
- package/dist/src/cli/scan.js.map +1 -0
- package/dist/src/cli/setup.d.ts +27 -0
- package/dist/src/cli/setup.d.ts.map +1 -0
- package/dist/src/cli/setup.js +134 -0
- package/dist/src/cli/setup.js.map +1 -0
- package/dist/src/cli/status.d.ts +4 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +52 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/upload-sourcemaps.d.ts +13 -0
- package/dist/src/cli/upload-sourcemaps.d.ts.map +1 -0
- package/dist/src/cli/upload-sourcemaps.js +157 -0
- package/dist/src/cli/upload-sourcemaps.js.map +1 -0
- package/dist/src/config/manager.d.ts +37 -0
- package/dist/src/config/manager.d.ts.map +1 -0
- package/dist/src/config/manager.js +131 -0
- package/dist/src/config/manager.js.map +1 -0
- package/dist/src/constants.d.ts +28 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +34 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/engines/graph/data-flow.d.ts +36 -0
- package/dist/src/engines/graph/data-flow.d.ts.map +1 -0
- package/dist/src/engines/graph/data-flow.js +189 -0
- package/dist/src/engines/graph/data-flow.js.map +1 -0
- package/dist/src/engines/graph/index.d.ts +20 -0
- package/dist/src/engines/graph/index.d.ts.map +1 -0
- package/dist/src/engines/graph/index.js +100 -0
- package/dist/src/engines/graph/index.js.map +1 -0
- package/dist/src/engines/graph/parser.d.ts +13 -0
- package/dist/src/engines/graph/parser.d.ts.map +1 -0
- package/dist/src/engines/graph/parser.js +620 -0
- package/dist/src/engines/graph/parser.js.map +1 -0
- package/dist/src/engines/graph/queries.d.ts +11 -0
- package/dist/src/engines/graph/queries.d.ts.map +1 -0
- package/dist/src/engines/graph/queries.js +196 -0
- package/dist/src/engines/graph/queries.js.map +1 -0
- package/dist/src/engines/graph/store.d.ts +35 -0
- package/dist/src/engines/graph/store.d.ts.map +1 -0
- package/dist/src/engines/graph/store.js +284 -0
- package/dist/src/engines/graph/store.js.map +1 -0
- package/dist/src/engines/pattern/gitleaks.d.ts +4 -0
- package/dist/src/engines/pattern/gitleaks.d.ts.map +1 -0
- package/dist/src/engines/pattern/gitleaks.js +78 -0
- package/dist/src/engines/pattern/gitleaks.js.map +1 -0
- package/dist/src/engines/pattern/index.d.ts +11 -0
- package/dist/src/engines/pattern/index.d.ts.map +1 -0
- package/dist/src/engines/pattern/index.js +111 -0
- package/dist/src/engines/pattern/index.js.map +1 -0
- package/dist/src/engines/pattern/semgrep.d.ts +4 -0
- package/dist/src/engines/pattern/semgrep.d.ts.map +1 -0
- package/dist/src/engines/pattern/semgrep.js +83 -0
- package/dist/src/engines/pattern/semgrep.js.map +1 -0
- package/dist/src/engines/pattern/trivy.d.ts +4 -0
- package/dist/src/engines/pattern/trivy.d.ts.map +1 -0
- package/dist/src/engines/pattern/trivy.js +90 -0
- package/dist/src/engines/pattern/trivy.js.map +1 -0
- package/dist/src/github/api.d.ts +19 -0
- package/dist/src/github/api.d.ts.map +1 -0
- package/dist/src/github/api.js +75 -0
- package/dist/src/github/api.js.map +1 -0
- package/dist/src/github/app-manifest.d.ts +28 -0
- package/dist/src/github/app-manifest.d.ts.map +1 -0
- package/dist/src/github/app-manifest.js +27 -0
- package/dist/src/github/app-manifest.js.map +1 -0
- package/dist/src/github/checks.d.ts +36 -0
- package/dist/src/github/checks.d.ts.map +1 -0
- package/dist/src/github/checks.js +90 -0
- package/dist/src/github/checks.js.map +1 -0
- package/dist/src/github/scanner.d.ts +20 -0
- package/dist/src/github/scanner.d.ts.map +1 -0
- package/dist/src/github/scanner.js +78 -0
- package/dist/src/github/scanner.js.map +1 -0
- package/dist/src/github/webhook.d.ts +39 -0
- package/dist/src/github/webhook.d.ts.map +1 -0
- package/dist/src/github/webhook.js +80 -0
- package/dist/src/github/webhook.js.map +1 -0
- package/dist/src/hooks/installer.d.ts +4 -0
- package/dist/src/hooks/installer.d.ts.map +1 -0
- package/dist/src/hooks/installer.js +146 -0
- package/dist/src/hooks/installer.js.map +1 -0
- package/dist/src/mcp/server.d.ts +2 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +96 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/check-package.d.ts +30 -0
- package/dist/src/mcp/tools/check-package.d.ts.map +1 -0
- package/dist/src/mcp/tools/check-package.js +196 -0
- package/dist/src/mcp/tools/check-package.js.map +1 -0
- package/dist/src/mcp/tools/fix.d.ts +41 -0
- package/dist/src/mcp/tools/fix.d.ts.map +1 -0
- package/dist/src/mcp/tools/fix.js +98 -0
- package/dist/src/mcp/tools/fix.js.map +1 -0
- package/dist/src/mcp/tools/graph-query.d.ts +7 -0
- package/dist/src/mcp/tools/graph-query.d.ts.map +1 -0
- package/dist/src/mcp/tools/graph-query.js +139 -0
- package/dist/src/mcp/tools/graph-query.js.map +1 -0
- package/dist/src/mcp/tools/production-errors.d.ts +23 -0
- package/dist/src/mcp/tools/production-errors.d.ts.map +1 -0
- package/dist/src/mcp/tools/production-errors.js +46 -0
- package/dist/src/mcp/tools/production-errors.js.map +1 -0
- package/dist/src/mcp/tools/scan.d.ts +7 -0
- package/dist/src/mcp/tools/scan.d.ts.map +1 -0
- package/dist/src/mcp/tools/scan.js +9 -0
- package/dist/src/mcp/tools/scan.js.map +1 -0
- package/dist/src/mcp/tools/status.d.ts +9 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -0
- package/dist/src/mcp/tools/status.js +18 -0
- package/dist/src/mcp/tools/status.js.map +1 -0
- package/dist/src/mcp/tools/verify-resolution.d.ts +12 -0
- package/dist/src/mcp/tools/verify-resolution.d.ts.map +1 -0
- package/dist/src/mcp/tools/verify-resolution.js +45 -0
- package/dist/src/mcp/tools/verify-resolution.js.map +1 -0
- package/dist/src/types.d.ts +136 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { runPatternEngine } from '../engines/pattern/index.js';
|
|
3
|
+
import { fixHardcodedSecret } from '../autofix/secret-fixer.js';
|
|
4
|
+
import { gateFeature } from './license-gate.js';
|
|
5
|
+
const SEVERITY_COLORS = {
|
|
6
|
+
critical: chalk.red,
|
|
7
|
+
high: chalk.red,
|
|
8
|
+
medium: chalk.yellow,
|
|
9
|
+
low: chalk.blue,
|
|
10
|
+
info: chalk.gray,
|
|
11
|
+
};
|
|
12
|
+
function formatDuration(ms) {
|
|
13
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
14
|
+
}
|
|
15
|
+
function formatResults(result) {
|
|
16
|
+
console.log(chalk.bold('\nShipSafe Scan Results'));
|
|
17
|
+
console.log(chalk.bold('─'.repeat(40)));
|
|
18
|
+
const duration = formatDuration(result.scan_duration_ms);
|
|
19
|
+
const scoreLine = `Score: ${result.score} | ${result.findings.length} findings | ${duration}`;
|
|
20
|
+
console.log(scoreLine);
|
|
21
|
+
if (result.findings.length > 0) {
|
|
22
|
+
console.log('');
|
|
23
|
+
for (const finding of result.findings) {
|
|
24
|
+
const colorFn = SEVERITY_COLORS[finding.severity];
|
|
25
|
+
const severityLabel = colorFn(finding.severity.toUpperCase());
|
|
26
|
+
console.log(`${severityLabel} ${finding.file}:${finding.line}`);
|
|
27
|
+
console.log(` ${finding.description}`);
|
|
28
|
+
console.log(` Fix: ${finding.fix_suggestion}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
console.log('');
|
|
32
|
+
}
|
|
33
|
+
export async function handleScanAction(options) {
|
|
34
|
+
const scope = options.scope;
|
|
35
|
+
const result = await runPatternEngine({
|
|
36
|
+
targetPath: process.cwd(),
|
|
37
|
+
scope,
|
|
38
|
+
});
|
|
39
|
+
if (options.fix) {
|
|
40
|
+
const gate = await gateFeature('autofix');
|
|
41
|
+
if (!gate.allowed) {
|
|
42
|
+
console.log(chalk.yellow(`\n${gate.reason}`));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
for (const finding of result.findings) {
|
|
46
|
+
if (finding.type === 'hardcoded_secret' && finding.auto_fixable) {
|
|
47
|
+
const fix = await fixHardcodedSecret(finding);
|
|
48
|
+
console.log(chalk.green(`Fixed: moved ${fix.envVarName} to .env in ${finding.file}:${finding.line}`));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (options.json) {
|
|
54
|
+
console.log(JSON.stringify(result, null, 2));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
formatResults(result);
|
|
58
|
+
}
|
|
59
|
+
const hasCriticalOrHigh = result.findings.some((f) => f.severity === 'critical' || f.severity === 'high');
|
|
60
|
+
if (hasCriticalOrHigh) {
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function registerScanCommand(program) {
|
|
65
|
+
program
|
|
66
|
+
.command('scan')
|
|
67
|
+
.description('Scan project for security vulnerabilities')
|
|
68
|
+
.option('--scope <scope>', 'Scan scope: staged, all, or file:<path>', 'staged')
|
|
69
|
+
.option('--fix', 'Attempt to auto-fix findings', false)
|
|
70
|
+
.option('--json', 'Output results as JSON', false)
|
|
71
|
+
.action(async (options) => {
|
|
72
|
+
await handleScanAction(options);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface SetupOptions {
|
|
3
|
+
skipHooks?: boolean;
|
|
4
|
+
skipMcp?: boolean;
|
|
5
|
+
skipClaudeMd?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Registers the ShipSafe MCP server in Claude Code's global config.
|
|
9
|
+
* Merges into existing config if present; creates new config otherwise.
|
|
10
|
+
*/
|
|
11
|
+
export declare function registerMcpClaudeCode(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Registers the ShipSafe MCP server in Cursor's project-level config.
|
|
14
|
+
* Merges into existing config if present; creates new config otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerMcpCursor(projectDir: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Registers the ShipSafe MCP server in all known editor configs.
|
|
19
|
+
*/
|
|
20
|
+
export declare function registerMcpServers(projectDir: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Main setup action — orchestrates hooks, MCP, and CLAUDE.md.
|
|
23
|
+
* Each step is independent; failures are warned but don't block other steps.
|
|
24
|
+
*/
|
|
25
|
+
export declare function handleSetupAction(options: SetupOptions): Promise<void>;
|
|
26
|
+
export declare function registerSetupCommand(program: Command): void;
|
|
27
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AA2BD;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAe3D;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAezE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC5E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc3D"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { installHooks } from '../hooks/installer.js';
|
|
6
|
+
import { injectClaudeMd } from '../claude-md/manager.js';
|
|
7
|
+
const MCP_SERVER_ENTRY = {
|
|
8
|
+
command: 'npx',
|
|
9
|
+
args: ['-y', 'shipsafe', 'mcp-server'],
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Reads a JSON file, returning null if it doesn't exist or is invalid.
|
|
13
|
+
*/
|
|
14
|
+
async function readJsonFile(filePath) {
|
|
15
|
+
try {
|
|
16
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Writes a JSON file, creating parent directories as needed.
|
|
25
|
+
*/
|
|
26
|
+
async function writeJsonFile(filePath, data) {
|
|
27
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
28
|
+
await fs.writeFile(filePath, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Registers the ShipSafe MCP server in Claude Code's global config.
|
|
32
|
+
* Merges into existing config if present; creates new config otherwise.
|
|
33
|
+
*/
|
|
34
|
+
export async function registerMcpClaudeCode() {
|
|
35
|
+
const configPath = path.join(homedir(), '.claude', 'claude_desktop_config.json');
|
|
36
|
+
const existing = await readJsonFile(configPath);
|
|
37
|
+
if (existing) {
|
|
38
|
+
existing.mcpServers = existing.mcpServers ?? {};
|
|
39
|
+
existing.mcpServers.shipsafe = MCP_SERVER_ENTRY;
|
|
40
|
+
await writeJsonFile(configPath, existing);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
await writeJsonFile(configPath, {
|
|
44
|
+
mcpServers: {
|
|
45
|
+
shipsafe: MCP_SERVER_ENTRY,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Registers the ShipSafe MCP server in Cursor's project-level config.
|
|
52
|
+
* Merges into existing config if present; creates new config otherwise.
|
|
53
|
+
*/
|
|
54
|
+
export async function registerMcpCursor(projectDir) {
|
|
55
|
+
const configPath = path.join(projectDir, '.cursor', 'mcp.json');
|
|
56
|
+
const existing = await readJsonFile(configPath);
|
|
57
|
+
if (existing) {
|
|
58
|
+
existing.mcpServers = existing.mcpServers ?? {};
|
|
59
|
+
existing.mcpServers.shipsafe = MCP_SERVER_ENTRY;
|
|
60
|
+
await writeJsonFile(configPath, existing);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
await writeJsonFile(configPath, {
|
|
64
|
+
mcpServers: {
|
|
65
|
+
shipsafe: MCP_SERVER_ENTRY,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Registers the ShipSafe MCP server in all known editor configs.
|
|
72
|
+
*/
|
|
73
|
+
export async function registerMcpServers(projectDir) {
|
|
74
|
+
await registerMcpClaudeCode();
|
|
75
|
+
await registerMcpCursor(projectDir);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Main setup action — orchestrates hooks, MCP, and CLAUDE.md.
|
|
79
|
+
* Each step is independent; failures are warned but don't block other steps.
|
|
80
|
+
*/
|
|
81
|
+
export async function handleSetupAction(options) {
|
|
82
|
+
const projectDir = process.cwd();
|
|
83
|
+
console.log('Setting up ShipSafe...');
|
|
84
|
+
// Step 1: Install git hooks
|
|
85
|
+
if (!options.skipHooks) {
|
|
86
|
+
try {
|
|
87
|
+
await installHooks(projectDir);
|
|
88
|
+
console.log(chalk.green('✓') + ' Git hooks installed');
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
92
|
+
console.warn(chalk.yellow('⚠') + ` Git hooks: ${msg}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Step 2: Register MCP servers
|
|
96
|
+
if (!options.skipMcp) {
|
|
97
|
+
try {
|
|
98
|
+
await registerMcpServers(projectDir);
|
|
99
|
+
console.log(chalk.green('✓') + ' MCP server registered');
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
103
|
+
console.warn(chalk.yellow('⚠') + ` MCP registration: ${msg}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Step 3: Inject CLAUDE.md
|
|
107
|
+
if (!options.skipClaudeMd) {
|
|
108
|
+
try {
|
|
109
|
+
await injectClaudeMd(projectDir);
|
|
110
|
+
console.log(chalk.green('✓') + ' CLAUDE.md updated');
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
114
|
+
console.warn(chalk.yellow('⚠') + ` CLAUDE.md: ${msg}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
console.log(`\nShipSafe is ready! Run 'shipsafe scan' to run your first scan.`);
|
|
118
|
+
}
|
|
119
|
+
export function registerSetupCommand(program) {
|
|
120
|
+
program
|
|
121
|
+
.command('setup')
|
|
122
|
+
.description('Set up ShipSafe for current project (hooks, MCP, CLAUDE.md)')
|
|
123
|
+
.option('--skip-hooks', 'Skip git hook installation')
|
|
124
|
+
.option('--skip-mcp', 'Skip MCP server registration')
|
|
125
|
+
.option('--skip-claude-md', 'Skip CLAUDE.md injection')
|
|
126
|
+
.action(async (options) => {
|
|
127
|
+
await handleSetupAction({
|
|
128
|
+
skipHooks: options.skipHooks,
|
|
129
|
+
skipMcp: options.skipMcp,
|
|
130
|
+
skipClaudeMd: options.skipClaudeMd,
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/cli/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBxD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAO5D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { loadConfig, getProjectName } from '../config/manager.js';
|
|
5
|
+
import { getAvailableScanners } from '../engines/pattern/index.js';
|
|
6
|
+
import { HOOK_MARKER } from '../constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* Checks whether the ShipSafe pre-commit hook is installed in the
|
|
9
|
+
* current project's .git/hooks directory.
|
|
10
|
+
*/
|
|
11
|
+
function checkHooksInstalled(projectDir) {
|
|
12
|
+
const hookPath = path.join(projectDir, '.git', 'hooks', 'pre-commit');
|
|
13
|
+
try {
|
|
14
|
+
if (!existsSync(hookPath))
|
|
15
|
+
return false;
|
|
16
|
+
const contents = readFileSync(hookPath, 'utf-8');
|
|
17
|
+
return contents.includes(HOOK_MARKER);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function handleStatusAction() {
|
|
24
|
+
const projectDir = process.cwd();
|
|
25
|
+
const config = await loadConfig(projectDir);
|
|
26
|
+
const projectName = getProjectName(projectDir);
|
|
27
|
+
const hooksInstalled = checkHooksInstalled(projectDir);
|
|
28
|
+
const scanners = await getAvailableScanners();
|
|
29
|
+
const check = chalk.green('\u2713');
|
|
30
|
+
const cross = chalk.red('\u2717');
|
|
31
|
+
const semgrepLabel = `semgrep ${scanners.semgrep ? check : cross}`;
|
|
32
|
+
const gitleaksLabel = `gitleaks ${scanners.gitleaks ? check : cross}`;
|
|
33
|
+
const trivyLabel = `trivy ${scanners.trivy ? check : cross}`;
|
|
34
|
+
const license = config.licenseKey ? 'Pro' : 'Free tier';
|
|
35
|
+
console.log(chalk.bold('\nShipSafe Status'));
|
|
36
|
+
console.log(chalk.bold('\u2500'.repeat(40)));
|
|
37
|
+
console.log(`Project: ${projectName}`);
|
|
38
|
+
console.log(`Security Score: ${chalk.dim("\u2014 (run 'shipsafe scan' first)")}`);
|
|
39
|
+
console.log(`Hooks Installed: ${hooksInstalled ? chalk.green('Yes') : chalk.red('No')}`);
|
|
40
|
+
console.log(`Scanners: ${semgrepLabel} ${gitleaksLabel} ${trivyLabel}`);
|
|
41
|
+
console.log(`License: ${license}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
}
|
|
44
|
+
export function registerStatusCommand(program) {
|
|
45
|
+
program
|
|
46
|
+
.command('status')
|
|
47
|
+
.description('Show ShipSafe status for current project')
|
|
48
|
+
.action(async () => {
|
|
49
|
+
await handleStatusAction();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Upload source maps action — finds .map files and uploads them to the ShipSafe API.
|
|
4
|
+
*/
|
|
5
|
+
export declare function handleUploadSourcemaps(options: {
|
|
6
|
+
dir: string;
|
|
7
|
+
release?: string;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Register the 'upload-sourcemaps' command with the CLI program.
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerUploadSourcemapsCommand(program: Command): void;
|
|
13
|
+
//# sourceMappingURL=upload-sourcemaps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-sourcemaps.d.ts","sourceRoot":"","sources":["../../../src/cli/upload-sourcemaps.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwDpC;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGhB;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAWtE"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { loadConfig, getApiEndpoint } from '../config/manager.js';
|
|
6
|
+
import { gateFeature } from './license-gate.js';
|
|
7
|
+
/**
|
|
8
|
+
* Recursively find all .map files in a directory.
|
|
9
|
+
*/
|
|
10
|
+
async function findSourceMaps(dir) {
|
|
11
|
+
const results = [];
|
|
12
|
+
let names;
|
|
13
|
+
try {
|
|
14
|
+
names = await fs.readdir(dir);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return results;
|
|
18
|
+
}
|
|
19
|
+
for (const name of names) {
|
|
20
|
+
const fullPath = path.join(dir, name);
|
|
21
|
+
try {
|
|
22
|
+
const stat = await fs.stat(fullPath);
|
|
23
|
+
if (stat.isDirectory()) {
|
|
24
|
+
// Skip node_modules
|
|
25
|
+
if (name === 'node_modules')
|
|
26
|
+
continue;
|
|
27
|
+
const nested = await findSourceMaps(fullPath);
|
|
28
|
+
results.push(...nested);
|
|
29
|
+
}
|
|
30
|
+
else if (name.endsWith('.map')) {
|
|
31
|
+
results.push(fullPath);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Skip files we can't stat
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reads the version field from package.json in the current working directory.
|
|
42
|
+
* Returns undefined if package.json is absent or has no version field.
|
|
43
|
+
*/
|
|
44
|
+
function readVersionFromPackageJson() {
|
|
45
|
+
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
46
|
+
try {
|
|
47
|
+
if (existsSync(pkgPath)) {
|
|
48
|
+
const raw = readFileSync(pkgPath, 'utf-8');
|
|
49
|
+
const pkg = JSON.parse(raw);
|
|
50
|
+
return pkg.version ?? undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// ignore
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Upload source maps action — finds .map files and uploads them to the ShipSafe API.
|
|
60
|
+
*/
|
|
61
|
+
export async function handleUploadSourcemaps(options) {
|
|
62
|
+
const gate = await gateFeature('upload_sourcemaps');
|
|
63
|
+
if (!gate.allowed) {
|
|
64
|
+
console.log(chalk.yellow(`\n${gate.reason}`));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const targetDir = path.resolve(process.cwd(), options.dir);
|
|
68
|
+
// Verify directory exists
|
|
69
|
+
try {
|
|
70
|
+
const stat = await fs.stat(targetDir);
|
|
71
|
+
if (!stat.isDirectory()) {
|
|
72
|
+
console.error(chalk.red(`Error: ${options.dir} is not a directory`));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
console.error(chalk.red(`Error: Directory ${options.dir} does not exist`));
|
|
78
|
+
console.log(`Run your build first, then try again.`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
console.log(chalk.bold(`Scanning ${options.dir} for source maps...\n`));
|
|
82
|
+
const mapFiles = await findSourceMaps(targetDir);
|
|
83
|
+
if (mapFiles.length === 0) {
|
|
84
|
+
console.log(chalk.yellow('No source map files (.map) found.'));
|
|
85
|
+
console.log(`Ensure your build is configured to emit source maps.`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// List found files
|
|
89
|
+
for (const file of mapFiles) {
|
|
90
|
+
const relative = path.relative(process.cwd(), file);
|
|
91
|
+
console.log(` ${chalk.cyan(relative)}`);
|
|
92
|
+
}
|
|
93
|
+
console.log('');
|
|
94
|
+
// Load config
|
|
95
|
+
const config = await loadConfig();
|
|
96
|
+
if (!config.projectId) {
|
|
97
|
+
console.log(chalk.yellow('Warning: No project ID configured. Run `shipsafe setup` to connect.'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const apiEndpoint = getApiEndpoint(config);
|
|
101
|
+
// Determine release version
|
|
102
|
+
const release = options.release ?? readVersionFromPackageJson() ?? 'unknown';
|
|
103
|
+
// Read all .map file contents
|
|
104
|
+
const sourceMaps = [];
|
|
105
|
+
for (const file of mapFiles) {
|
|
106
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
107
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
108
|
+
sourceMaps.push({ file_path: relativePath, source_map: content });
|
|
109
|
+
}
|
|
110
|
+
// Build request headers
|
|
111
|
+
const headers = {
|
|
112
|
+
'Content-Type': 'application/json',
|
|
113
|
+
};
|
|
114
|
+
if (config.licenseKey) {
|
|
115
|
+
headers['Authorization'] = `Bearer ${config.licenseKey}`;
|
|
116
|
+
}
|
|
117
|
+
// POST to API
|
|
118
|
+
const url = `${apiEndpoint}/v1/sourcemaps/batch`;
|
|
119
|
+
let response;
|
|
120
|
+
try {
|
|
121
|
+
response = await fetch(url, {
|
|
122
|
+
method: 'POST',
|
|
123
|
+
headers,
|
|
124
|
+
body: JSON.stringify({
|
|
125
|
+
project_id: config.projectId,
|
|
126
|
+
release,
|
|
127
|
+
source_maps: sourceMaps,
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
console.error(chalk.red(`Upload failed: ${err.message}`));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
const text = await response.text();
|
|
137
|
+
console.error(chalk.red(`Upload failed (${response.status}): ${text}`));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
console.log(chalk.green(`Found ${mapFiles.length} source map${mapFiles.length === 1 ? '' : 's'}, uploaded to ShipSafe.`));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Register the 'upload-sourcemaps' command with the CLI program.
|
|
144
|
+
*/
|
|
145
|
+
export function registerUploadSourcemapsCommand(program) {
|
|
146
|
+
program
|
|
147
|
+
.command('upload-sourcemaps')
|
|
148
|
+
.description('Upload source maps for production stack trace resolution')
|
|
149
|
+
.option('--dir <dir>', 'Directory containing source maps', './dist')
|
|
150
|
+
.option('--release <version>', 'Release version tag for the source maps')
|
|
151
|
+
.action(async (options) => {
|
|
152
|
+
// Default release to package.json version if not specified
|
|
153
|
+
const release = options.release ?? readVersionFromPackageJson() ?? 'unknown';
|
|
154
|
+
await handleUploadSourcemaps({ dir: options.dir, release });
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=upload-sourcemaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-sourcemaps.js","sourceRoot":"","sources":["../../../src/cli/upload-sourcemaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ShipSafeConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the path to the global ShipSafe config directory (~/.shipsafe).
|
|
4
|
+
*/
|
|
5
|
+
export declare function getGlobalConfigDir(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Reads the global config from ~/.shipsafe/config.json.
|
|
8
|
+
* Returns defaults if the file is missing.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadGlobalConfig(): Promise<ShipSafeConfig>;
|
|
11
|
+
/**
|
|
12
|
+
* Reads the project config from <projectDir>/shipsafe.config.json.
|
|
13
|
+
* Returns defaults if the file is missing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadProjectConfig(projectDir?: string): Promise<ShipSafeConfig>;
|
|
16
|
+
/**
|
|
17
|
+
* Merges global and project configs. Project config overrides global config.
|
|
18
|
+
* Merge order: defaults < global < project.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadConfig(projectDir?: string): Promise<ShipSafeConfig>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the API endpoint. Priority: SHIPSAFE_API_URL env var > config value > default.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getApiEndpoint(config?: Pick<ShipSafeConfig, 'apiEndpoint'>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Writes config to ~/.shipsafe/config.json, creating the directory if needed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function saveGlobalConfig(config: Partial<ShipSafeConfig>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Writes config to <projectDir>/shipsafe.config.json.
|
|
31
|
+
*/
|
|
32
|
+
export declare function saveProjectConfig(config: Partial<ShipSafeConfig>, projectDir?: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Derives project name from package.json name field or falls back to directory name.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getProjectName(projectDir?: string): string;
|
|
37
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/config/manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuClD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAeD;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,cAAc,CAAC,CAOhE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAQpF;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAiB7E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,MAAM,CAKnF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAiB1D"}
|