@jishankai/solid-cli 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.
- package/LICENSE +21 -0
- package/README.md +276 -0
- package/config/default.json +79 -0
- package/package.json +60 -0
- package/src/Orchestrator.js +482 -0
- package/src/agents/BaseAgent.js +35 -0
- package/src/agents/BlockchainAgent.js +453 -0
- package/src/agents/DeFiSecurityAgent.js +257 -0
- package/src/agents/NetworkAgent.js +341 -0
- package/src/agents/PermissionAgent.js +192 -0
- package/src/agents/PersistenceAgent.js +361 -0
- package/src/agents/ProcessAgent.js +572 -0
- package/src/agents/ResourceAgent.js +217 -0
- package/src/agents/SystemAgent.js +173 -0
- package/src/config/ConfigManager.js +446 -0
- package/src/index.js +629 -0
- package/src/llm/LLMAnalyzer.js +705 -0
- package/src/logging/Logger.js +352 -0
- package/src/report/ReportManager.js +445 -0
- package/src/report/generators/MarkdownGenerator.js +173 -0
- package/src/report/generators/PDFGenerator.js +616 -0
- package/src/report/templates/report.hbs +465 -0
- package/src/report/utils/formatter.js +426 -0
- package/src/report/utils/sanitizer.js +275 -0
- package/src/utils/commander.js +42 -0
- package/src/utils/signature.js +121 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
import DailyRotateFile from 'winston-daily-rotate-file';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Structured Logging System
|
|
8
|
+
*/
|
|
9
|
+
export class Logger {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.options = {
|
|
12
|
+
logDir: './logs',
|
|
13
|
+
level: 'info',
|
|
14
|
+
consoleLevel: 'warn',
|
|
15
|
+
maxSize: '20m',
|
|
16
|
+
maxFiles: '14d',
|
|
17
|
+
enableConsole: true,
|
|
18
|
+
enableFiles: true,
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
this.logger = this.createLogger();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create Winston logger with proper configuration
|
|
27
|
+
*/
|
|
28
|
+
createLogger() {
|
|
29
|
+
const transports = [];
|
|
30
|
+
|
|
31
|
+
// Console transport for development
|
|
32
|
+
if (this.options.enableConsole) {
|
|
33
|
+
transports.push(
|
|
34
|
+
new winston.transports.Console({
|
|
35
|
+
level: this.options.consoleLevel,
|
|
36
|
+
format: winston.format.combine(
|
|
37
|
+
winston.format.colorize(),
|
|
38
|
+
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
|
39
|
+
winston.format.printf(({ level, message, timestamp, ...meta }) => {
|
|
40
|
+
const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
|
|
41
|
+
return `${timestamp} [${level}]: ${message}${metaStr}`;
|
|
42
|
+
})
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// File transport for production logs
|
|
49
|
+
if (this.options.enableFiles) {
|
|
50
|
+
// Ensure log directory exists
|
|
51
|
+
this.ensureLogDirectory();
|
|
52
|
+
|
|
53
|
+
// Application logs
|
|
54
|
+
transports.push(
|
|
55
|
+
new DailyRotateFile({
|
|
56
|
+
filename: join(this.options.logDir, 'app-%DATE%.log'),
|
|
57
|
+
datePattern: 'YYYY-MM-DD',
|
|
58
|
+
maxSize: this.options.maxSize,
|
|
59
|
+
maxFiles: this.options.maxFiles,
|
|
60
|
+
format: winston.format.combine(
|
|
61
|
+
winston.format.timestamp(),
|
|
62
|
+
winston.format.json()
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Error logs
|
|
68
|
+
transports.push(
|
|
69
|
+
new DailyRotateFile({
|
|
70
|
+
filename: join(this.options.logDir, 'error-%DATE%.log'),
|
|
71
|
+
datePattern: 'YYYY-MM-DD',
|
|
72
|
+
level: 'error',
|
|
73
|
+
maxSize: this.options.maxSize,
|
|
74
|
+
maxFiles: this.options.maxFiles,
|
|
75
|
+
format: winston.format.combine(
|
|
76
|
+
winston.format.timestamp(),
|
|
77
|
+
winston.format.json()
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Security event logs
|
|
83
|
+
transports.push(
|
|
84
|
+
new DailyRotateFile({
|
|
85
|
+
filename: join(this.options.logDir, 'security-%DATE%.log'),
|
|
86
|
+
datePattern: 'YYYY-MM-DD',
|
|
87
|
+
level: 'warn',
|
|
88
|
+
maxSize: this.options.maxSize,
|
|
89
|
+
maxFiles: '30d', // Keep security logs longer
|
|
90
|
+
format: winston.format.combine(
|
|
91
|
+
winston.format.timestamp(),
|
|
92
|
+
winston.format.json()
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return winston.createLogger({
|
|
99
|
+
level: this.options.level,
|
|
100
|
+
defaultMeta: {
|
|
101
|
+
service: 'security-solid-cli',
|
|
102
|
+
version: '2.0.0'
|
|
103
|
+
},
|
|
104
|
+
transports,
|
|
105
|
+
exitOnError: false
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Ensure log directory exists
|
|
111
|
+
*/
|
|
112
|
+
async ensureLogDirectory() {
|
|
113
|
+
try {
|
|
114
|
+
await fs.mkdir(this.options.logDir, { recursive: true });
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error(`Failed to create log directory: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Log analysis start
|
|
122
|
+
*/
|
|
123
|
+
logAnalysisStart(options = {}) {
|
|
124
|
+
this.logger.info('Analysis started', {
|
|
125
|
+
event: 'analysis_start',
|
|
126
|
+
mode: options.mode,
|
|
127
|
+
depth: options.depth,
|
|
128
|
+
geoLookup: options.geoLookup,
|
|
129
|
+
hostname: options.hostname
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Log analysis completion
|
|
135
|
+
*/
|
|
136
|
+
logAnalysisComplete(results, duration) {
|
|
137
|
+
this.logger.info('Analysis completed', {
|
|
138
|
+
event: 'analysis_complete',
|
|
139
|
+
duration,
|
|
140
|
+
findings: results.summary.totalFindings,
|
|
141
|
+
highRisk: results.summary.highRiskFindings,
|
|
142
|
+
mediumRisk: results.summary.mediumRiskFindings,
|
|
143
|
+
lowRisk: results.summary.lowRiskFindings,
|
|
144
|
+
overallRisk: results.overallRisk,
|
|
145
|
+
agentsRan: Object.keys(results.agents).length
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Log agent execution
|
|
151
|
+
*/
|
|
152
|
+
logAgentStart(agentName, options = {}) {
|
|
153
|
+
this.logger.debug(`Agent started: ${agentName}`, {
|
|
154
|
+
event: 'agent_start',
|
|
155
|
+
agent: agentName,
|
|
156
|
+
...options
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Log agent completion
|
|
162
|
+
*/
|
|
163
|
+
logAgentComplete(agentName, results, duration) {
|
|
164
|
+
this.logger.debug(`Agent completed: ${agentName}`, {
|
|
165
|
+
event: 'agent_complete',
|
|
166
|
+
agent: agentName,
|
|
167
|
+
duration,
|
|
168
|
+
findings: results.findings?.length || 0,
|
|
169
|
+
risk: results.overallRisk,
|
|
170
|
+
error: results.error ? true : false
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Log agent error
|
|
176
|
+
*/
|
|
177
|
+
logAgentError(agentName, error, duration) {
|
|
178
|
+
this.logger.error(`Agent failed: ${agentName}`, {
|
|
179
|
+
event: 'agent_error',
|
|
180
|
+
agent: agentName,
|
|
181
|
+
duration,
|
|
182
|
+
error: error.message,
|
|
183
|
+
stack: error.stack
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Log security event
|
|
189
|
+
*/
|
|
190
|
+
logSecurityEvent(event, details = {}) {
|
|
191
|
+
this.logger.warn('Security event detected', {
|
|
192
|
+
event: 'security_event',
|
|
193
|
+
securityEvent: event,
|
|
194
|
+
severity: details.severity || 'medium',
|
|
195
|
+
...details
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Log report generation
|
|
201
|
+
*/
|
|
202
|
+
logReportGeneration(formats, outputPaths, duration) {
|
|
203
|
+
this.logger.info('Reports generated', {
|
|
204
|
+
event: 'report_generation',
|
|
205
|
+
formats,
|
|
206
|
+
outputPaths,
|
|
207
|
+
duration
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Log LLM analysis
|
|
213
|
+
*/
|
|
214
|
+
logLLMAnalysis(provider, model, tokens, duration) {
|
|
215
|
+
this.logger.info('LLM analysis completed', {
|
|
216
|
+
event: 'llm_analysis',
|
|
217
|
+
provider,
|
|
218
|
+
model,
|
|
219
|
+
tokens,
|
|
220
|
+
duration
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Log blockchain detection
|
|
226
|
+
*/
|
|
227
|
+
logBlockchainDetection(indicators) {
|
|
228
|
+
this.logger.info('Blockchain activity detected', {
|
|
229
|
+
event: 'blockchain_detection',
|
|
230
|
+
indicators,
|
|
231
|
+
action: 'blockchain_agents_activated'
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Log performance metrics
|
|
237
|
+
*/
|
|
238
|
+
logPerformance(operation, duration, metadata = {}) {
|
|
239
|
+
this.logger.debug(`Performance: ${operation}`, {
|
|
240
|
+
event: 'performance',
|
|
241
|
+
operation,
|
|
242
|
+
duration,
|
|
243
|
+
...metadata
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Log user interaction
|
|
249
|
+
*/
|
|
250
|
+
logUserInteraction(action, details = {}) {
|
|
251
|
+
this.logger.debug('User interaction', {
|
|
252
|
+
event: 'user_interaction',
|
|
253
|
+
action,
|
|
254
|
+
...details
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Log configuration changes
|
|
260
|
+
*/
|
|
261
|
+
logConfigurationChange(setting, oldValue, newValue) {
|
|
262
|
+
this.logger.info('Configuration changed', {
|
|
263
|
+
event: 'config_change',
|
|
264
|
+
setting,
|
|
265
|
+
oldValue,
|
|
266
|
+
newValue
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get logger instance
|
|
272
|
+
*/
|
|
273
|
+
getLogger() {
|
|
274
|
+
return this.logger;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Set log level
|
|
279
|
+
*/
|
|
280
|
+
setLevel(level) {
|
|
281
|
+
this.logger.level = level;
|
|
282
|
+
this.options.level = level;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Add custom transport
|
|
287
|
+
*/
|
|
288
|
+
addTransport(transport) {
|
|
289
|
+
this.logger.add(transport);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Remove transport
|
|
294
|
+
*/
|
|
295
|
+
removeTransport(transport) {
|
|
296
|
+
this.logger.remove(transport);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Close logger
|
|
301
|
+
*/
|
|
302
|
+
async close() {
|
|
303
|
+
const transports = this.logger.transports;
|
|
304
|
+
await Promise.all(
|
|
305
|
+
transports.map(transport => {
|
|
306
|
+
if (typeof transport.close === 'function') {
|
|
307
|
+
return transport.close();
|
|
308
|
+
}
|
|
309
|
+
return Promise.resolve();
|
|
310
|
+
})
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Global logger instance
|
|
317
|
+
*/
|
|
318
|
+
let globalLogger = null;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Get or create global logger instance
|
|
322
|
+
*/
|
|
323
|
+
export function getLogger(options = {}) {
|
|
324
|
+
if (!globalLogger) {
|
|
325
|
+
globalLogger = new Logger(options);
|
|
326
|
+
}
|
|
327
|
+
return globalLogger;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Log convenience functions
|
|
332
|
+
*/
|
|
333
|
+
export const log = {
|
|
334
|
+
debug: (message, meta = {}) => getLogger().getLogger().debug(message, meta),
|
|
335
|
+
info: (message, meta = {}) => getLogger().getLogger().info(message, meta),
|
|
336
|
+
warn: (message, meta = {}) => getLogger().getLogger().warn(message, meta),
|
|
337
|
+
error: (message, meta = {}) => getLogger().getLogger().error(message, meta),
|
|
338
|
+
|
|
339
|
+
// Structured logging functions
|
|
340
|
+
analysisStart: (options) => getLogger().logAnalysisStart(options),
|
|
341
|
+
analysisComplete: (results, duration) => getLogger().logAnalysisComplete(results, duration),
|
|
342
|
+
agentStart: (agent, options) => getLogger().logAgentStart(agent, options),
|
|
343
|
+
agentComplete: (agent, results, duration) => getLogger().logAgentComplete(agent, results, duration),
|
|
344
|
+
agentError: (agent, error, duration) => getLogger().logAgentError(agent, error, duration),
|
|
345
|
+
securityEvent: (event, details) => getLogger().logSecurityEvent(event, details),
|
|
346
|
+
reportGeneration: (formats, paths, duration) => getLogger().logReportGeneration(formats, paths, duration),
|
|
347
|
+
llmAnalysis: (provider, model, tokens, duration) => getLogger().logLLMAnalysis(provider, model, tokens, duration),
|
|
348
|
+
blockchainDetection: (indicators) => getLogger().logBlockchainDetection(indicators),
|
|
349
|
+
performance: (operation, duration, meta) => getLogger().logPerformance(operation, duration, meta),
|
|
350
|
+
userInteraction: (action, details) => getLogger().logUserInteraction(action, details),
|
|
351
|
+
configChange: (setting, oldVal, newVal) => getLogger().logConfigurationChange(setting, oldVal, newVal)
|
|
352
|
+
};
|