safe-pkg 1.0.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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -0
  3. package/dist/.DS_Store +0 -0
  4. package/dist/cli/index.d.ts +5 -0
  5. package/dist/cli/index.js +135 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/cli/parser.d.ts +5 -0
  8. package/dist/cli/parser.js +61 -0
  9. package/dist/cli/parser.js.map +1 -0
  10. package/dist/config/index.d.ts +1 -0
  11. package/dist/config/index.js +3 -0
  12. package/dist/config/index.js.map +1 -0
  13. package/dist/config/loadConfig.d.ts +5 -0
  14. package/dist/config/loadConfig.js +49 -0
  15. package/dist/config/loadConfig.js.map +1 -0
  16. package/dist/detector/detectPackageManager.d.ts +14 -0
  17. package/dist/detector/detectPackageManager.js +68 -0
  18. package/dist/detector/detectPackageManager.js.map +1 -0
  19. package/dist/detector/index.d.ts +1 -0
  20. package/dist/detector/index.js +3 -0
  21. package/dist/detector/index.js.map +1 -0
  22. package/dist/executor/index.d.ts +1 -0
  23. package/dist/executor/index.js +3 -0
  24. package/dist/executor/index.js.map +1 -0
  25. package/dist/executor/runCommand.d.ts +9 -0
  26. package/dist/executor/runCommand.js +61 -0
  27. package/dist/executor/runCommand.js.map +1 -0
  28. package/dist/index.d.ts +8 -0
  29. package/dist/index.js +11 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/scanner/aiAnalyzer.d.ts +6 -0
  32. package/dist/scanner/aiAnalyzer.js +92 -0
  33. package/dist/scanner/aiAnalyzer.js.map +1 -0
  34. package/dist/scanner/analyzePackage.d.ts +5 -0
  35. package/dist/scanner/analyzePackage.js +155 -0
  36. package/dist/scanner/analyzePackage.js.map +1 -0
  37. package/dist/scanner/auditAnalyzer.d.ts +11 -0
  38. package/dist/scanner/auditAnalyzer.js +113 -0
  39. package/dist/scanner/auditAnalyzer.js.map +1 -0
  40. package/dist/scanner/heuristicAnalyzer.d.ts +5 -0
  41. package/dist/scanner/heuristicAnalyzer.js +228 -0
  42. package/dist/scanner/heuristicAnalyzer.js.map +1 -0
  43. package/dist/scanner/index.d.ts +6 -0
  44. package/dist/scanner/index.js +8 -0
  45. package/dist/scanner/index.js.map +1 -0
  46. package/dist/scanner/metadataAnalyzer.d.ts +5 -0
  47. package/dist/scanner/metadataAnalyzer.js +136 -0
  48. package/dist/scanner/metadataAnalyzer.js.map +1 -0
  49. package/dist/scanner/scriptAnalyzer.d.ts +5 -0
  50. package/dist/scanner/scriptAnalyzer.js +187 -0
  51. package/dist/scanner/scriptAnalyzer.js.map +1 -0
  52. package/dist/scanner-project/batchAnalyze.d.ts +1 -0
  53. package/dist/scanner-project/batchAnalyze.js +4 -0
  54. package/dist/scanner-project/batchAnalyze.js.map +1 -0
  55. package/dist/scanner-project/index.d.ts +4 -0
  56. package/dist/scanner-project/index.js +6 -0
  57. package/dist/scanner-project/index.js.map +1 -0
  58. package/dist/scanner-project/readDependencies.d.ts +5 -0
  59. package/dist/scanner-project/readDependencies.js +28 -0
  60. package/dist/scanner-project/readDependencies.js.map +1 -0
  61. package/dist/scanner-project/scanNodeModules.d.ts +1 -0
  62. package/dist/scanner-project/scanNodeModules.js +4 -0
  63. package/dist/scanner-project/scanNodeModules.js.map +1 -0
  64. package/dist/scanner-project/scanProject.d.ts +5 -0
  65. package/dist/scanner-project/scanProject.js +69 -0
  66. package/dist/scanner-project/scanProject.js.map +1 -0
  67. package/dist/test.d.ts +6 -0
  68. package/dist/test.js +153 -0
  69. package/dist/test.js.map +1 -0
  70. package/dist/types.d.ts +133 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/dist/ui/index.d.ts +4 -0
  74. package/dist/ui/index.js +6 -0
  75. package/dist/ui/index.js.map +1 -0
  76. package/dist/ui/logger.d.ts +24 -0
  77. package/dist/ui/logger.js +39 -0
  78. package/dist/ui/logger.js.map +1 -0
  79. package/dist/ui/promptUser.d.ts +12 -0
  80. package/dist/ui/promptUser.js +50 -0
  81. package/dist/ui/promptUser.js.map +1 -0
  82. package/dist/ui/riskReporter.d.ts +5 -0
  83. package/dist/ui/riskReporter.js +157 -0
  84. package/dist/ui/riskReporter.js.map +1 -0
  85. package/dist/ui/scanReporter.d.ts +1 -0
  86. package/dist/ui/scanReporter.js +4 -0
  87. package/dist/ui/scanReporter.js.map +1 -0
  88. package/package.json +61 -0
@@ -0,0 +1,28 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Read dependencies from package.json in the project
5
+ */
6
+ export function readDependencies(cwd) {
7
+ const packageJsonPath = join(cwd, "package.json");
8
+ try {
9
+ const content = readFileSync(packageJsonPath, "utf-8");
10
+ const packageJson = JSON.parse(content);
11
+ const deps = packageJson.dependencies || {};
12
+ const devDeps = packageJson.devDependencies || {};
13
+ return {
14
+ dependencies: deps,
15
+ devDependencies: devDeps,
16
+ total: Object.keys(deps).length + Object.keys(devDeps).length,
17
+ };
18
+ }
19
+ catch (error) {
20
+ // If package.json doesn't exist or can't be read, return empty
21
+ return {
22
+ dependencies: {},
23
+ devDependencies: {},
24
+ total: 0,
25
+ };
26
+ }
27
+ }
28
+ //# sourceMappingURL=readDependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readDependencies.js","sourceRoot":"","sources":["../../src/scanner-project/readDependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAElD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAGrC,CAAC;QAEF,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,eAAe,IAAI,EAAE,CAAC;QAElD,OAAO;YACN,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,OAAO;YACxB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;SAC7D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,+DAA+D;QAC/D,OAAO;YACN,YAAY,EAAE,EAAE;YAChB,eAAe,EAAE,EAAE;YACnB,KAAK,EAAE,CAAC;SACR,CAAC;IACH,CAAC;AACF,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export {};
2
+ // Scan node_modules directory
3
+ // Will be implemented in Phase 5
4
+ //# sourceMappingURL=scanNodeModules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanNodeModules.js","sourceRoot":"","sources":["../../src/scanner-project/scanNodeModules.ts"],"names":[],"mappings":";AAAA,8BAA8B;AAC9B,iCAAiC"}
@@ -0,0 +1,5 @@
1
+ import type { Config, ProjectScanResult } from "../types.js";
2
+ /**
3
+ * Scan all dependencies in the current project
4
+ */
5
+ export declare function scanProject(cwd: string, config: Config, includeDevDeps?: boolean): Promise<ProjectScanResult>;
@@ -0,0 +1,69 @@
1
+ import chalk from "chalk";
2
+ import { analyzePackage } from "../scanner/analyzePackage.js";
3
+ import { logError, logStep, logSuccess, logWarning } from "../ui/logger.js";
4
+ import { readDependencies } from "./readDependencies.js";
5
+ /**
6
+ * Scan all dependencies in the current project
7
+ */
8
+ export async function scanProject(cwd, config, includeDevDeps = false) {
9
+ logStep("Reading project dependencies...");
10
+ const deps = readDependencies(cwd);
11
+ const allDeps = {
12
+ ...deps.dependencies,
13
+ ...(includeDevDeps ? deps.devDependencies : {}),
14
+ };
15
+ const packageNames = Object.keys(allDeps);
16
+ if (packageNames.length === 0) {
17
+ logWarning("No dependencies found in package.json");
18
+ return {
19
+ totalPackages: 0,
20
+ scannedPackages: 0,
21
+ highRiskCount: 0,
22
+ criticalVulnerabilities: 0,
23
+ reports: [],
24
+ summary: {
25
+ safe: 0,
26
+ caution: 0,
27
+ dangerous: 0,
28
+ },
29
+ scannedAt: new Date(),
30
+ };
31
+ }
32
+ logStep(`Analyzing ${packageNames.length} packages...\n`);
33
+ const reports = [];
34
+ let analyzed = 0;
35
+ // Analyze packages sequentially to avoid rate limits
36
+ for (const packageName of packageNames) {
37
+ try {
38
+ analyzed++;
39
+ process.stdout.write(chalk.gray(` [${analyzed}/${packageNames.length}] Analyzing ${packageName}...\r`));
40
+ const report = await analyzePackage(packageName, config);
41
+ reports.push(report);
42
+ }
43
+ catch (error) {
44
+ // Log error but continue with other packages
45
+ logError(`Failed to analyze ${packageName}: ${error instanceof Error ? error.message : String(error)}`);
46
+ }
47
+ }
48
+ // Clear progress line
49
+ process.stdout.write(`${" ".repeat(80)}\r`);
50
+ // Count by risk level
51
+ const safePackages = reports.filter((r) => r.riskLevel === "safe").length;
52
+ const cautionPackages = reports.filter((r) => r.riskLevel === "caution").length;
53
+ const dangerousPackages = reports.filter((r) => r.riskLevel === "dangerous").length;
54
+ logSuccess(`Analyzed ${reports.length}/${packageNames.length} packages`);
55
+ return {
56
+ totalPackages: packageNames.length,
57
+ scannedPackages: reports.length,
58
+ highRiskCount: cautionPackages + dangerousPackages,
59
+ criticalVulnerabilities: dangerousPackages,
60
+ reports,
61
+ summary: {
62
+ safe: safePackages,
63
+ caution: cautionPackages,
64
+ dangerous: dangerousPackages,
65
+ },
66
+ scannedAt: new Date(),
67
+ };
68
+ }
69
+ //# sourceMappingURL=scanProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanProject.js","sourceRoot":"","sources":["../../src/scanner-project/scanProject.ts"],"names":[],"mappings":"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"}
package/dist/test.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Test script for safe-pkg analysis engine
3
+ * Run with: node --loader ts-node/esm src/test.ts
4
+ * Or compile first: pnpm run build && node dist/test.js
5
+ */
6
+ export {};
package/dist/test.js ADDED
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Test script for safe-pkg analysis engine
3
+ * Run with: node --loader ts-node/esm src/test.ts
4
+ * Or compile first: pnpm run build && node dist/test.js
5
+ */
6
+ import { analyzePackage } from "./scanner/analyzePackage.js";
7
+ // ============================================
8
+ // HARDCODE YOUR ANTHROPIC API KEY HERE FOR TESTING
9
+ // ============================================
10
+ const ANTHROPIC_API_KEY = ""; // Add your key here: "sk-ant-..."
11
+ // Test configuration
12
+ const config = {
13
+ anthropicApiKey: ANTHROPIC_API_KEY || undefined,
14
+ riskThreshold: 7,
15
+ autoConfirm: false,
16
+ };
17
+ // Packages to test (mix of safe, risky, and unknown)
18
+ const TEST_PACKAGES = [
19
+ // Popular, well-maintained packages (should be safe)
20
+ "react",
21
+ "express",
22
+ "chalk",
23
+ // Less popular packages (might have warnings)
24
+ "tiny-package-that-doesnt-exist-12345",
25
+ // Package with potential security concerns (if any)
26
+ // Add any specific packages you want to test here
27
+ ];
28
+ /**
29
+ * Format and display risk report
30
+ */
31
+ function displayReport(packageName, report) {
32
+ console.log(`\n${"=".repeat(80)}`);
33
+ console.log(`📦 Package: ${packageName}`);
34
+ console.log("=".repeat(80));
35
+ console.log(`\n🎯 Risk Score: ${report.riskScore}/10`);
36
+ console.log(`📊 Risk Level: ${report.riskLevel.toUpperCase()}`);
37
+ console.log(`✅ Version: ${report.version}`);
38
+ console.log(`🕐 Analyzed: ${report.analyzedAt.toISOString()}`);
39
+ // Display recommendation
40
+ console.log(`\n💡 Recommendation:\n ${report.recommendation}`);
41
+ // Display warnings
42
+ if (report.warnings.length > 0) {
43
+ console.log(`\n⚠️ Warnings (${report.warnings.length}):`);
44
+ for (const warning of report.warnings) {
45
+ const icon = warning.severity === "critical"
46
+ ? "🔴"
47
+ : warning.severity === "high"
48
+ ? "🟠"
49
+ : warning.severity === "medium"
50
+ ? "🟡"
51
+ : "🔵";
52
+ console.log(` ${icon} [${warning.severity.toUpperCase()}] ${warning.message}`);
53
+ console.log(` Source: ${warning.source}`);
54
+ }
55
+ }
56
+ // Display analyzer details
57
+ console.log("\n📋 Analyzer Results:");
58
+ if (report.analyzers.audit) {
59
+ const audit = report.analyzers.audit;
60
+ console.log(` • Audit: ${audit.vulnerabilityCount} vulnerabilities (score: ${audit.riskScore}/10)`);
61
+ if (audit.criticalCount > 0 || audit.highCount > 0) {
62
+ console.log(` - ${audit.criticalCount} critical, ${audit.highCount} high`);
63
+ }
64
+ }
65
+ else {
66
+ console.log(" • Audit: N/A (failed or skipped)");
67
+ }
68
+ if (report.analyzers.metadata) {
69
+ const meta = report.analyzers.metadata;
70
+ console.log(` • Metadata: ${meta.downloads.toLocaleString()} weekly downloads (score: ${meta.riskScore}/10)`);
71
+ console.log(` - Age: ${meta.packageAge} days, Maintainers: ${meta.maintainerCount}, License: ${meta.hasLicense ? "Yes" : "No"}`);
72
+ }
73
+ else {
74
+ console.log(" • Metadata: N/A (failed or skipped)");
75
+ }
76
+ if (report.analyzers.script) {
77
+ const script = report.analyzers.script;
78
+ console.log(` • Scripts: ${script.hasSuspiciousScripts ? "⚠️ Suspicious" : "✓ Clean"} (score: ${script.riskScore}/10)`);
79
+ if (script.suspiciousScripts.length > 0) {
80
+ console.log(` - Found: ${script.suspiciousScripts.join(", ")}`);
81
+ }
82
+ }
83
+ else {
84
+ console.log(" • Scripts: N/A (failed or skipped)");
85
+ }
86
+ if (report.analyzers.heuristic) {
87
+ const heuristic = report.analyzers.heuristic;
88
+ console.log(` • Heuristics: ${heuristic.isPotentialTyposquat ? "⚠️ Typosquat risk" : "✓ Clean"} (score: ${heuristic.riskScore}/10)`);
89
+ if (heuristic.suspiciousPatterns.length > 0) {
90
+ console.log(` - Patterns: ${heuristic.suspiciousPatterns.join(", ")}`);
91
+ }
92
+ }
93
+ else {
94
+ console.log(" • Heuristics: N/A");
95
+ }
96
+ // Display AI insights if available
97
+ if (report.analyzers.aiInsights) {
98
+ console.log("\n🤖 AI Insights:");
99
+ console.log(` ${report.analyzers.aiInsights.replace(/\n/g, "\n ")}`);
100
+ }
101
+ else if (ANTHROPIC_API_KEY) {
102
+ console.log("\n🤖 AI Insights: N/A (enhancement failed)");
103
+ }
104
+ else {
105
+ console.log("\n🤖 AI Insights: Disabled (set ANTHROPIC_API_KEY to enable)");
106
+ }
107
+ }
108
+ /**
109
+ * Run tests on all packages
110
+ */
111
+ async function runTests() {
112
+ console.log("🚀 Starting safe-pkg Analysis Engine Tests");
113
+ console.log(`🔑 Anthropic API: ${ANTHROPIC_API_KEY ? "✓ Enabled" : "✗ Disabled"}`);
114
+ console.log(`📦 Testing ${TEST_PACKAGES.length} packages...\n`);
115
+ const results = [];
116
+ for (const packageName of TEST_PACKAGES) {
117
+ try {
118
+ console.log(`\n⏳ Analyzing ${packageName}...`);
119
+ const report = await analyzePackage(packageName, config);
120
+ displayReport(packageName, report);
121
+ results.push({ package: packageName, success: true });
122
+ }
123
+ catch (error) {
124
+ console.error(`\n❌ Error analyzing ${packageName}:`, error);
125
+ results.push({
126
+ package: packageName,
127
+ success: false,
128
+ error: error instanceof Error ? error.message : String(error),
129
+ });
130
+ }
131
+ }
132
+ // Summary
133
+ console.log(`\n${"=".repeat(80)}`);
134
+ console.log("📊 TEST SUMMARY");
135
+ console.log("=".repeat(80));
136
+ const successful = results.filter((r) => r.success).length;
137
+ const failed = results.filter((r) => !r.success).length;
138
+ console.log(`✅ Successful: ${successful}/${TEST_PACKAGES.length}`);
139
+ console.log(`❌ Failed: ${failed}/${TEST_PACKAGES.length}`);
140
+ if (failed > 0) {
141
+ console.log("\nFailed packages:");
142
+ for (const result of results.filter((r) => !r.success)) {
143
+ console.log(` • ${result.package}: ${result.error}`);
144
+ }
145
+ }
146
+ console.log("\n✨ Tests completed!\n");
147
+ }
148
+ // Run tests
149
+ runTests().catch((error) => {
150
+ console.error("Fatal error running tests:", error);
151
+ process.exit(1);
152
+ });
153
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Supported package managers
3
+ */
4
+ export type PackageManager = "npm" | "yarn" | "pnpm";
5
+ /**
6
+ * Risk levels for package analysis
7
+ */
8
+ export type RiskLevel = "safe" | "caution" | "dangerous";
9
+ /**
10
+ * Analyzer type that performed the analysis
11
+ */
12
+ export type AnalyzerType = "audit" | "metadata" | "script" | "heuristic" | "ai";
13
+ /**
14
+ * Individual warning from an analyzer
15
+ */
16
+ export interface Warning {
17
+ message: string;
18
+ severity: "low" | "medium" | "high" | "critical";
19
+ source: AnalyzerType;
20
+ }
21
+ /**
22
+ * Result from npm audit analysis
23
+ */
24
+ export interface AuditResult {
25
+ vulnerabilityCount: number;
26
+ criticalCount: number;
27
+ highCount: number;
28
+ moderateCount: number;
29
+ lowCount: number;
30
+ vulnerabilities: Array<{
31
+ name: string;
32
+ severity: "low" | "moderate" | "high" | "critical";
33
+ via: string;
34
+ }>;
35
+ riskScore: number;
36
+ }
37
+ /**
38
+ * Result from package metadata analysis
39
+ */
40
+ export interface MetadataScore {
41
+ version: string;
42
+ downloads: number;
43
+ lastPublishDate: Date;
44
+ maintainerCount: number;
45
+ hasLicense: boolean;
46
+ packageAge: number;
47
+ riskScore: number;
48
+ }
49
+ /**
50
+ * Result from script detection analysis
51
+ */
52
+ export interface ScriptRisk {
53
+ hasSuspiciousScripts: boolean;
54
+ suspiciousScripts: string[];
55
+ dangerousCommands: string[];
56
+ riskScore: number;
57
+ }
58
+ /**
59
+ * Result from heuristic analysis
60
+ */
61
+ export interface HeuristicScore {
62
+ suspiciousPatterns: string[];
63
+ isPotentialTyposquat: boolean;
64
+ riskScore: number;
65
+ }
66
+ /**
67
+ * Complete risk report for a package
68
+ */
69
+ export interface RiskReport {
70
+ packageName: string;
71
+ version: string;
72
+ riskScore: number;
73
+ riskLevel: RiskLevel;
74
+ warnings: Warning[];
75
+ recommendation: string;
76
+ analyzers: {
77
+ audit?: AuditResult;
78
+ metadata?: MetadataScore;
79
+ script?: ScriptRisk;
80
+ heuristic?: HeuristicScore;
81
+ aiInsights?: string;
82
+ };
83
+ analyzedAt: Date;
84
+ }
85
+ /**
86
+ * Analysis result (can include errors)
87
+ */
88
+ export interface AnalysisResult {
89
+ success: boolean;
90
+ report?: RiskReport;
91
+ error?: string;
92
+ }
93
+ /**
94
+ * Parsed command configuration
95
+ */
96
+ export interface CommandConfig {
97
+ action: "install" | "scan" | "check" | "help";
98
+ packages: string[];
99
+ options: Record<string, unknown>;
100
+ packageManager?: PackageManager;
101
+ }
102
+ /**
103
+ * List of dependencies from package.json
104
+ */
105
+ export interface DependencyList {
106
+ dependencies: Record<string, string>;
107
+ devDependencies: Record<string, string>;
108
+ total: number;
109
+ }
110
+ /**
111
+ * Result from project scan
112
+ */
113
+ export interface ProjectScanResult {
114
+ totalPackages: number;
115
+ scannedPackages: number;
116
+ highRiskCount: number;
117
+ criticalVulnerabilities: number;
118
+ reports: RiskReport[];
119
+ summary: {
120
+ safe: number;
121
+ caution: number;
122
+ dangerous: number;
123
+ };
124
+ scannedAt: Date;
125
+ }
126
+ /**
127
+ * Configuration loaded from env or file
128
+ */
129
+ export interface Config {
130
+ anthropicApiKey?: string;
131
+ riskThreshold: number;
132
+ autoConfirm: boolean;
133
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export * from "./logger.js";
2
+ export * from "./riskReporter.js";
3
+ export * from "./promptUser.js";
4
+ export * from "./scanReporter.js";
@@ -0,0 +1,6 @@
1
+ // UI barrel exports
2
+ export * from "./logger.js";
3
+ export * from "./riskReporter.js";
4
+ export * from "./promptUser.js";
5
+ export * from "./scanReporter.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Log a step/info message
3
+ */
4
+ export declare function logStep(message: string): void;
5
+ /**
6
+ * Log a success message
7
+ */
8
+ export declare function logSuccess(message: string): void;
9
+ /**
10
+ * Log a warning message
11
+ */
12
+ export declare function logWarning(message: string): void;
13
+ /**
14
+ * Log an error message
15
+ */
16
+ export declare function logError(message: string): void;
17
+ /**
18
+ * Log a section header
19
+ */
20
+ export declare function logHeader(message: string): void;
21
+ /**
22
+ * Log blank line for spacing
23
+ */
24
+ export declare function logNewline(): void;
@@ -0,0 +1,39 @@
1
+ import chalk from "chalk";
2
+ /**
3
+ * Log a step/info message
4
+ */
5
+ export function logStep(message) {
6
+ console.log(chalk.blue("ℹ"), message);
7
+ }
8
+ /**
9
+ * Log a success message
10
+ */
11
+ export function logSuccess(message) {
12
+ console.log(chalk.green("✔"), message);
13
+ }
14
+ /**
15
+ * Log a warning message
16
+ */
17
+ export function logWarning(message) {
18
+ console.log(chalk.yellow("⚠"), message);
19
+ }
20
+ /**
21
+ * Log an error message
22
+ */
23
+ export function logError(message) {
24
+ console.log(chalk.red("✖"), message);
25
+ }
26
+ /**
27
+ * Log a section header
28
+ */
29
+ export function logHeader(message) {
30
+ console.log(`\n${chalk.bold.cyan(message)}`);
31
+ console.log(chalk.gray("=".repeat(Math.min(message.length, 80))));
32
+ }
33
+ /**
34
+ * Log blank line for spacing
35
+ */
36
+ export function logNewline() {
37
+ console.log();
38
+ }
39
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/ui/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACzB,OAAO,CAAC,GAAG,EAAE,CAAC;AACf,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { RiskLevel } from "../types.js";
2
+ /**
3
+ * Ask user for confirmation before installing a package
4
+ */
5
+ export declare function askUserConfirmation(packageName: string, riskLevel: RiskLevel, riskScore: number): Promise<boolean>;
6
+ /**
7
+ * Ask user which packages to install from a list
8
+ */
9
+ export declare function selectPackagesToInstall(packages: Array<{
10
+ name: string;
11
+ safe: boolean;
12
+ }>): Promise<string[]>;
@@ -0,0 +1,50 @@
1
+ import chalk from "chalk";
2
+ import prompts from "prompts";
3
+ /**
4
+ * Ask user for confirmation before installing a package
5
+ */
6
+ export async function askUserConfirmation(packageName, riskLevel, riskScore) {
7
+ // Auto-deny for dangerous packages
8
+ if (riskLevel === "dangerous") {
9
+ const response = await prompts({
10
+ type: "confirm",
11
+ name: "proceed",
12
+ message: chalk.red.bold(`Package "${packageName}" is DANGEROUS (score: ${riskScore}/10). Install anyway?`),
13
+ initial: false,
14
+ });
15
+ return response.proceed ?? false;
16
+ }
17
+ // Warn for caution packages
18
+ if (riskLevel === "caution") {
19
+ const response = await prompts({
20
+ type: "confirm",
21
+ name: "proceed",
22
+ message: chalk.yellow(`Package "${packageName}" has warnings (score: ${riskScore}/10). Continue?`),
23
+ initial: false,
24
+ });
25
+ return response.proceed ?? false;
26
+ }
27
+ // Auto-proceed for safe packages (but can be overridden by config)
28
+ return true;
29
+ }
30
+ /**
31
+ * Ask user which packages to install from a list
32
+ */
33
+ export async function selectPackagesToInstall(packages) {
34
+ const choices = packages.map((pkg) => ({
35
+ title: pkg.safe
36
+ ? `${chalk.green("✓")} ${pkg.name}`
37
+ : `${chalk.red("✖")} ${pkg.name}`,
38
+ value: pkg.name,
39
+ selected: pkg.safe,
40
+ }));
41
+ const response = await prompts({
42
+ type: "multiselect",
43
+ name: "packages",
44
+ message: "Select packages to install:",
45
+ choices,
46
+ hint: "Space to select, Enter to confirm",
47
+ });
48
+ return response.packages ?? [];
49
+ }
50
+ //# sourceMappingURL=promptUser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptUser.js","sourceRoot":"","sources":["../../src/ui/promptUser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,WAAmB,EACnB,SAAoB,EACpB,SAAiB;IAEjB,mCAAmC;IACnC,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;YAC9B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CACtB,YAAY,WAAW,0BAA0B,SAAS,uBAAuB,CACjF;YACD,OAAO,EAAE,KAAK;SACd,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC;IAClC,CAAC;IAED,4BAA4B;IAC5B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;YAC9B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK,CAAC,MAAM,CACpB,YAAY,WAAW,0BAA0B,SAAS,iBAAiB,CAC3E;YACD,OAAO,EAAE,KAAK;SACd,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC;IAClC,CAAC;IAED,mEAAmE;IACnE,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,QAAgD;IAEhD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtC,KAAK,EAAE,GAAG,CAAC,IAAI;YACd,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE;YACnC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE;QAClC,KAAK,EAAE,GAAG,CAAC,IAAI;QACf,QAAQ,EAAE,GAAG,CAAC,IAAI;KAClB,CAAC,CAAC,CAAC;IAEJ,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC9B,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,6BAA6B;QACtC,OAAO;QACP,IAAI,EAAE,mCAAmC;KACzC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { RiskReport } from "../types.js";
2
+ /**
3
+ * Display a comprehensive risk report for a single package
4
+ */
5
+ export declare function displayRiskReport(report: RiskReport): void;