gitlab-auto-reviewers 2.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 +1878 -0
- package/dist/api/gitlab-api.d.ts +136 -0
- package/dist/api/gitlab-api.d.ts.map +1 -0
- package/dist/api/gitlab-api.js +334 -0
- package/dist/api/gitlab-api.js.map +1 -0
- package/dist/bin/cli.d.ts +10 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +186 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bin/deprecated-mcp.d.ts +12 -0
- package/dist/bin/deprecated-mcp.d.ts.map +1 -0
- package/dist/bin/deprecated-mcp.js +73 -0
- package/dist/bin/deprecated-mcp.js.map +1 -0
- package/dist/bin/index.d.ts +18 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +78 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/bin/mcp.d.ts +11 -0
- package/dist/bin/mcp.d.ts.map +1 -0
- package/dist/bin/mcp.js +43 -0
- package/dist/bin/mcp.js.map +1 -0
- package/dist/cache/cache.service.d.ts +113 -0
- package/dist/cache/cache.service.d.ts.map +1 -0
- package/dist/cache/cache.service.js +213 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/cli/commands.d.ts +40 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +142 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/output.d.ts +24 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +143 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/config/config.service.d.ts +89 -0
- package/dist/config/config.service.d.ts.map +1 -0
- package/dist/config/config.service.js +169 -0
- package/dist/config/config.service.js.map +1 -0
- package/dist/datasources/git-data-source.interface.d.ts +140 -0
- package/dist/datasources/git-data-source.interface.d.ts.map +1 -0
- package/dist/datasources/git-data-source.interface.js +2 -0
- package/dist/datasources/git-data-source.interface.js.map +1 -0
- package/dist/datasources/gitlab-api-data-source.d.ts +127 -0
- package/dist/datasources/gitlab-api-data-source.d.ts.map +1 -0
- package/dist/datasources/gitlab-api-data-source.js +248 -0
- package/dist/datasources/gitlab-api-data-source.js.map +1 -0
- package/dist/datasources/local-git-data-source.d.ts +124 -0
- package/dist/datasources/local-git-data-source.d.ts.map +1 -0
- package/dist/datasources/local-git-data-source.js +580 -0
- package/dist/datasources/local-git-data-source.js.map +1 -0
- package/dist/errors/error-handler.d.ts +113 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +230 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/index.d.ts +139 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +139 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/example.d.ts +15 -0
- package/dist/logging/example.d.ts.map +1 -0
- package/dist/logging/example.js +79 -0
- package/dist/logging/example.js.map +1 -0
- package/dist/logging/index.d.ts +7 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +7 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.service.d.ts +98 -0
- package/dist/logging/logger.service.d.ts.map +1 -0
- package/dist/logging/logger.service.js +160 -0
- package/dist/logging/logger.service.js.map +1 -0
- package/dist/mcp/server.d.ts +67 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +213 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +176 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/services/blacklist.service.d.ts +32 -0
- package/dist/services/blacklist.service.d.ts.map +1 -0
- package/dist/services/blacklist.service.js +59 -0
- package/dist/services/blacklist.service.js.map +1 -0
- package/dist/services/codeowners.service.d.ts +45 -0
- package/dist/services/codeowners.service.d.ts.map +1 -0
- package/dist/services/codeowners.service.js +200 -0
- package/dist/services/codeowners.service.js.map +1 -0
- package/dist/services/comment-builder.service.d.ts +48 -0
- package/dist/services/comment-builder.service.d.ts.map +1 -0
- package/dist/services/comment-builder.service.js +61 -0
- package/dist/services/comment-builder.service.js.map +1 -0
- package/dist/services/contributors.service.d.ts +52 -0
- package/dist/services/contributors.service.d.ts.map +1 -0
- package/dist/services/contributors.service.js +144 -0
- package/dist/services/contributors.service.js.map +1 -0
- package/dist/services/reviewer-service.d.ts +125 -0
- package/dist/services/reviewer-service.d.ts.map +1 -0
- package/dist/services/reviewer-service.js +554 -0
- package/dist/services/reviewer-service.js.map +1 -0
- package/dist/services/team-members.service.d.ts +29 -0
- package/dist/services/team-members.service.d.ts.map +1 -0
- package/dist/services/team-members.service.js +45 -0
- package/dist/services/team-members.service.js.map +1 -0
- package/dist/services/whitelist.service.d.ts +31 -0
- package/dist/services/whitelist.service.d.ts.map +1 -0
- package/dist/services/whitelist.service.js +51 -0
- package/dist/services/whitelist.service.js.map +1 -0
- package/dist/tools.d.ts +22 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +176 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/index.d.ts +502 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +91 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Usage Examples
|
|
3
|
+
*
|
|
4
|
+
* This file demonstrates how to use the Logger service.
|
|
5
|
+
* It is not part of the production code.
|
|
6
|
+
*/
|
|
7
|
+
import { Logger, LogLevel } from './logger.service.js';
|
|
8
|
+
// Example 1: Basic logging
|
|
9
|
+
function basicLoggingExample() {
|
|
10
|
+
const logger = new Logger('MyService', LogLevel.DEBUG);
|
|
11
|
+
logger.debug('Starting service initialization');
|
|
12
|
+
logger.info('Service initialized successfully');
|
|
13
|
+
logger.warn('Configuration value missing, using default');
|
|
14
|
+
logger.error('Failed to connect to database', new Error('Connection timeout'));
|
|
15
|
+
}
|
|
16
|
+
// Example 2: Logging with context
|
|
17
|
+
function contextLoggingExample() {
|
|
18
|
+
const logger = new Logger('ReviewerService', LogLevel.INFO);
|
|
19
|
+
logger.info('Fetching merge request', {
|
|
20
|
+
project: 'my-project',
|
|
21
|
+
mr: 123,
|
|
22
|
+
operation: 'fetchMR',
|
|
23
|
+
});
|
|
24
|
+
logger.info('Suggesting reviewers', {
|
|
25
|
+
project: 'my-project',
|
|
26
|
+
mr: 123,
|
|
27
|
+
operation: 'suggestReviewers',
|
|
28
|
+
candidateCount: 5,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// Example 3: Performance timing
|
|
32
|
+
async function performanceTimingExample() {
|
|
33
|
+
const logger = new Logger('DataService', LogLevel.DEBUG);
|
|
34
|
+
const endTimer = logger.startTimer('fetchUserData');
|
|
35
|
+
// Simulate async operation
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
37
|
+
endTimer(); // Logs: "fetchUserData completed" with duration
|
|
38
|
+
}
|
|
39
|
+
// Example 4: Child loggers
|
|
40
|
+
function childLoggerExample() {
|
|
41
|
+
const parentLogger = new Logger('Application', LogLevel.INFO);
|
|
42
|
+
const serviceLogger = parentLogger.child('UserService');
|
|
43
|
+
const repoLogger = serviceLogger.child('Repository');
|
|
44
|
+
parentLogger.info('Application started'); // [Application]
|
|
45
|
+
serviceLogger.info('Service initialized'); // [Application:UserService]
|
|
46
|
+
repoLogger.info('Connected to database'); // [Application:UserService:Repository]
|
|
47
|
+
}
|
|
48
|
+
// Example 5: Error logging with context
|
|
49
|
+
function errorLoggingExample() {
|
|
50
|
+
const logger = new Logger('GitService', LogLevel.INFO);
|
|
51
|
+
try {
|
|
52
|
+
throw new Error('Git operation failed');
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
logger.error('Failed to fetch git data', error, {
|
|
56
|
+
operation: 'git-blame',
|
|
57
|
+
file: 'src/index.ts',
|
|
58
|
+
commit: 'abc123',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Example 6: Log level filtering
|
|
63
|
+
function logLevelFilteringExample() {
|
|
64
|
+
// Only log warnings and errors
|
|
65
|
+
const prodLogger = new Logger('Production', LogLevel.WARN);
|
|
66
|
+
prodLogger.debug('Debug message'); // Not logged
|
|
67
|
+
prodLogger.info('Info message'); // Not logged
|
|
68
|
+
prodLogger.warn('Warning message'); // Logged
|
|
69
|
+
prodLogger.error('Error message'); // Logged
|
|
70
|
+
}
|
|
71
|
+
// Example 7: Parsing log level from environment
|
|
72
|
+
function parseLogLevelExample() {
|
|
73
|
+
const logLevelStr = process.env.LOG_LEVEL || 'info';
|
|
74
|
+
const logLevel = Logger.parseLogLevel(logLevelStr);
|
|
75
|
+
const logger = new Logger('ConfigurableService', logLevel);
|
|
76
|
+
logger.info('Logger configured with level:', { level: logLevelStr });
|
|
77
|
+
}
|
|
78
|
+
export { basicLoggingExample, contextLoggingExample, performanceTimingExample, childLoggerExample, errorLoggingExample, logLevelFilteringExample, parseLogLevelExample, };
|
|
79
|
+
//# sourceMappingURL=example.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.js","sourceRoot":"","sources":["../../src/logging/example.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAmB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Service
|
|
3
|
+
*
|
|
4
|
+
* Structured logging with appropriate log levels and context.
|
|
5
|
+
* Provides performance timing utilities and debug mode support.
|
|
6
|
+
*/
|
|
7
|
+
export declare enum LogLevel {
|
|
8
|
+
DEBUG = 0,
|
|
9
|
+
INFO = 1,
|
|
10
|
+
WARN = 2,
|
|
11
|
+
ERROR = 3
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Context information for log messages
|
|
15
|
+
*
|
|
16
|
+
* @property operation - Name of the operation being performed (optional)
|
|
17
|
+
* @property project - Project identifier (optional)
|
|
18
|
+
* @property mr - Merge request number (optional)
|
|
19
|
+
* @property duration - Operation duration in milliseconds (optional)
|
|
20
|
+
*/
|
|
21
|
+
export interface LogContext {
|
|
22
|
+
operation?: string;
|
|
23
|
+
project?: string;
|
|
24
|
+
mr?: number;
|
|
25
|
+
duration?: number;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Logger service for structured logging with context
|
|
30
|
+
*
|
|
31
|
+
* Provides methods for logging at different levels (debug, info, warn, error)
|
|
32
|
+
* with contextual information and performance timing utilities.
|
|
33
|
+
*/
|
|
34
|
+
export declare class Logger {
|
|
35
|
+
private readonly context;
|
|
36
|
+
private readonly minLevel;
|
|
37
|
+
/**
|
|
38
|
+
* Create a new logger instance
|
|
39
|
+
*
|
|
40
|
+
* @param context - Context name for this logger (e.g., 'GitLabAPI', 'ReviewerService')
|
|
41
|
+
* @param minLevel - Minimum log level to output (default: INFO)
|
|
42
|
+
*/
|
|
43
|
+
constructor(context: string, minLevel?: LogLevel);
|
|
44
|
+
/**
|
|
45
|
+
* Log a debug message (for detailed diagnostic information)
|
|
46
|
+
*
|
|
47
|
+
* @param message - The log message
|
|
48
|
+
* @param context - Optional contextual information
|
|
49
|
+
*/
|
|
50
|
+
debug(message: string, context?: LogContext): void;
|
|
51
|
+
/**
|
|
52
|
+
* Log an info message (for normal operations)
|
|
53
|
+
*
|
|
54
|
+
* @param message - The log message
|
|
55
|
+
* @param context - Optional contextual information
|
|
56
|
+
*/
|
|
57
|
+
info(message: string, context?: LogContext): void;
|
|
58
|
+
/**
|
|
59
|
+
* Log a warning message (for recoverable issues)
|
|
60
|
+
*
|
|
61
|
+
* @param message - The log message
|
|
62
|
+
* @param context - Optional contextual information
|
|
63
|
+
*/
|
|
64
|
+
warn(message: string, context?: LogContext): void;
|
|
65
|
+
/**
|
|
66
|
+
* Log an error message (for failures)
|
|
67
|
+
*
|
|
68
|
+
* @param message - The log message
|
|
69
|
+
* @param error - Optional error object with stack trace
|
|
70
|
+
* @param context - Optional contextual information
|
|
71
|
+
*/
|
|
72
|
+
error(message: string, error?: Error, context?: LogContext): void;
|
|
73
|
+
/**
|
|
74
|
+
* Start a performance timer for an operation
|
|
75
|
+
* Returns a function that when called, logs the duration
|
|
76
|
+
*/
|
|
77
|
+
startTimer(operation: string): () => void;
|
|
78
|
+
/**
|
|
79
|
+
* Internal logging method
|
|
80
|
+
*/
|
|
81
|
+
private log;
|
|
82
|
+
/**
|
|
83
|
+
* Format log message for human readability
|
|
84
|
+
*/
|
|
85
|
+
private formatMessage;
|
|
86
|
+
/**
|
|
87
|
+
* Create a child logger with additional context
|
|
88
|
+
*
|
|
89
|
+
* @param childContext - Additional context to append to parent context
|
|
90
|
+
* @returns New logger instance with combined context
|
|
91
|
+
*/
|
|
92
|
+
child(childContext: string): Logger;
|
|
93
|
+
/**
|
|
94
|
+
* Parse log level from string
|
|
95
|
+
*/
|
|
96
|
+
static parseLogLevel(level: string): LogLevel;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=logger.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.service.d.ts","sourceRoot":"","sources":["../../src/logging/logger.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC;;;;;OAKG;gBACS,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAwB;IAK/D;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAYjE;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,IAAI;IASzC;;OAEG;IACH,OAAO,CAAC,GAAG;IAiCX;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;;;;OAKG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;CAgB9C"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Service
|
|
3
|
+
*
|
|
4
|
+
* Structured logging with appropriate log levels and context.
|
|
5
|
+
* Provides performance timing utilities and debug mode support.
|
|
6
|
+
*/
|
|
7
|
+
export var LogLevel;
|
|
8
|
+
(function (LogLevel) {
|
|
9
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
10
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
11
|
+
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
12
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
13
|
+
})(LogLevel || (LogLevel = {}));
|
|
14
|
+
/**
|
|
15
|
+
* Logger service for structured logging with context
|
|
16
|
+
*
|
|
17
|
+
* Provides methods for logging at different levels (debug, info, warn, error)
|
|
18
|
+
* with contextual information and performance timing utilities.
|
|
19
|
+
*/
|
|
20
|
+
export class Logger {
|
|
21
|
+
context;
|
|
22
|
+
minLevel;
|
|
23
|
+
/**
|
|
24
|
+
* Create a new logger instance
|
|
25
|
+
*
|
|
26
|
+
* @param context - Context name for this logger (e.g., 'GitLabAPI', 'ReviewerService')
|
|
27
|
+
* @param minLevel - Minimum log level to output (default: INFO)
|
|
28
|
+
*/
|
|
29
|
+
constructor(context, minLevel = LogLevel.INFO) {
|
|
30
|
+
this.context = context;
|
|
31
|
+
this.minLevel = minLevel;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Log a debug message (for detailed diagnostic information)
|
|
35
|
+
*
|
|
36
|
+
* @param message - The log message
|
|
37
|
+
* @param context - Optional contextual information
|
|
38
|
+
*/
|
|
39
|
+
debug(message, context) {
|
|
40
|
+
this.log(LogLevel.DEBUG, message, context);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Log an info message (for normal operations)
|
|
44
|
+
*
|
|
45
|
+
* @param message - The log message
|
|
46
|
+
* @param context - Optional contextual information
|
|
47
|
+
*/
|
|
48
|
+
info(message, context) {
|
|
49
|
+
this.log(LogLevel.INFO, message, context);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Log a warning message (for recoverable issues)
|
|
53
|
+
*
|
|
54
|
+
* @param message - The log message
|
|
55
|
+
* @param context - Optional contextual information
|
|
56
|
+
*/
|
|
57
|
+
warn(message, context) {
|
|
58
|
+
this.log(LogLevel.WARN, message, context);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Log an error message (for failures)
|
|
62
|
+
*
|
|
63
|
+
* @param message - The log message
|
|
64
|
+
* @param error - Optional error object with stack trace
|
|
65
|
+
* @param context - Optional contextual information
|
|
66
|
+
*/
|
|
67
|
+
error(message, error, context) {
|
|
68
|
+
// Include error message in the main message if error is provided
|
|
69
|
+
const fullMessage = error ? `${message}: ${error.message}` : message;
|
|
70
|
+
const errorContext = {
|
|
71
|
+
...context,
|
|
72
|
+
error: error?.message,
|
|
73
|
+
stack: error?.stack,
|
|
74
|
+
};
|
|
75
|
+
this.log(LogLevel.ERROR, fullMessage, errorContext);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Start a performance timer for an operation
|
|
79
|
+
* Returns a function that when called, logs the duration
|
|
80
|
+
*/
|
|
81
|
+
startTimer(operation) {
|
|
82
|
+
const startTime = Date.now();
|
|
83
|
+
return () => {
|
|
84
|
+
const duration = Date.now() - startTime;
|
|
85
|
+
this.debug(`${operation} completed`, { operation, duration });
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Internal logging method
|
|
90
|
+
*/
|
|
91
|
+
log(level, message, context) {
|
|
92
|
+
if (level < this.minLevel) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const timestamp = new Date().toISOString();
|
|
96
|
+
const levelName = LogLevel[level];
|
|
97
|
+
const contextStr = this.context;
|
|
98
|
+
// Format for console output
|
|
99
|
+
const formattedMessage = this.formatMessage(timestamp, levelName, contextStr, message, context);
|
|
100
|
+
// Output to stderr (MCP servers use stderr for logging)
|
|
101
|
+
if (level === LogLevel.ERROR) {
|
|
102
|
+
console.error(formattedMessage);
|
|
103
|
+
if (context?.stack) {
|
|
104
|
+
console.error(context.stack);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (level === LogLevel.WARN) {
|
|
108
|
+
console.error(`WARN: ${formattedMessage}`);
|
|
109
|
+
}
|
|
110
|
+
else if (level === LogLevel.DEBUG) {
|
|
111
|
+
console.error(`DEBUG: ${formattedMessage}`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.error(formattedMessage);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Format log message for human readability
|
|
119
|
+
*/
|
|
120
|
+
formatMessage(timestamp, level, context, message, data) {
|
|
121
|
+
const parts = [`[${timestamp}]`, `[${level}]`, `[${context}]`, message];
|
|
122
|
+
if (data && Object.keys(data).length > 0) {
|
|
123
|
+
// Filter out stack traces from inline display
|
|
124
|
+
const { stack, error, ...displayData } = data;
|
|
125
|
+
if (Object.keys(displayData).length > 0) {
|
|
126
|
+
parts.push(JSON.stringify(displayData));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return parts.join(' ');
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Create a child logger with additional context
|
|
133
|
+
*
|
|
134
|
+
* @param childContext - Additional context to append to parent context
|
|
135
|
+
* @returns New logger instance with combined context
|
|
136
|
+
*/
|
|
137
|
+
child(childContext) {
|
|
138
|
+
return new Logger(`${this.context}:${childContext}`, this.minLevel);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Parse log level from string
|
|
142
|
+
*/
|
|
143
|
+
static parseLogLevel(level) {
|
|
144
|
+
const normalized = level.toLowerCase();
|
|
145
|
+
switch (normalized) {
|
|
146
|
+
case 'debug':
|
|
147
|
+
return LogLevel.DEBUG;
|
|
148
|
+
case 'info':
|
|
149
|
+
return LogLevel.INFO;
|
|
150
|
+
case 'warn':
|
|
151
|
+
case 'warning':
|
|
152
|
+
return LogLevel.WARN;
|
|
153
|
+
case 'error':
|
|
154
|
+
return LogLevel.ERROR;
|
|
155
|
+
default:
|
|
156
|
+
return LogLevel.INFO;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=logger.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.service.js","sourceRoot":"","sources":["../../src/logging/logger.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto Reviewers MCP Server
|
|
3
|
+
*
|
|
4
|
+
* A Model Context Protocol (MCP) server that provides intelligent GitLab merge request
|
|
5
|
+
* reviewer suggestions through AI assistants. The server analyzes git blame data,
|
|
6
|
+
* team member availability with FTE-aware load balancing, CODEOWNERS rules, and
|
|
7
|
+
* current reviewer workload to suggest the most appropriate reviewers.
|
|
8
|
+
*
|
|
9
|
+
* @module mcp/server
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Main MCP Server class that handles tool requests and manages services
|
|
13
|
+
*/
|
|
14
|
+
export declare class AutoReviewerMCPServer {
|
|
15
|
+
private server;
|
|
16
|
+
private reviewerServices;
|
|
17
|
+
private config;
|
|
18
|
+
private logger;
|
|
19
|
+
private cache;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the MCP server with all required services
|
|
22
|
+
*/
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Get or create a ReviewerService instance for the given configuration
|
|
26
|
+
* Services are cached per unique combination of GitLab URL, token, and repo path
|
|
27
|
+
*
|
|
28
|
+
* @param gitlabUrl - GitLab instance URL
|
|
29
|
+
* @param token - GitLab API token
|
|
30
|
+
* @param repoPath - Optional local repository path
|
|
31
|
+
* @returns ReviewerService instance
|
|
32
|
+
*/
|
|
33
|
+
private getReviewerService;
|
|
34
|
+
/**
|
|
35
|
+
* Set up MCP protocol request handlers
|
|
36
|
+
* Handles ListTools and CallTool requests
|
|
37
|
+
*/
|
|
38
|
+
private setupHandlers;
|
|
39
|
+
/**
|
|
40
|
+
* Handle a tool call request
|
|
41
|
+
* Routes the request to the appropriate ReviewerService method
|
|
42
|
+
*
|
|
43
|
+
* @param name - Tool name
|
|
44
|
+
* @param args - Tool arguments
|
|
45
|
+
* @returns Tool result
|
|
46
|
+
* @throws MCPError if tool is unknown or parameters are invalid
|
|
47
|
+
*/
|
|
48
|
+
private handleToolCall;
|
|
49
|
+
/**
|
|
50
|
+
* Detect the local git repository path
|
|
51
|
+
* Attempts to find the git root directory from the current working directory
|
|
52
|
+
*
|
|
53
|
+
* @returns Git repository root path, or undefined if not in a git repository
|
|
54
|
+
*/
|
|
55
|
+
private detectRepoPath;
|
|
56
|
+
/**
|
|
57
|
+
* Start the MCP server
|
|
58
|
+
* Connects to stdio transport and begins listening for requests
|
|
59
|
+
*/
|
|
60
|
+
run(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Gracefully shutdown the MCP server
|
|
63
|
+
* Logs cache statistics, clears cache, and closes the server connection
|
|
64
|
+
*/
|
|
65
|
+
shutdown(): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsBH;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAe;IAE5B;;OAEG;;IAuCH;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;;OAGG;IACH,OAAO,CAAC,aAAa;IA0CrB;;;;;;;;OAQG;YACW,cAAc;IAoD5B;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAW1B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAoBhC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto Reviewers MCP Server
|
|
3
|
+
*
|
|
4
|
+
* A Model Context Protocol (MCP) server that provides intelligent GitLab merge request
|
|
5
|
+
* reviewer suggestions through AI assistants. The server analyzes git blame data,
|
|
6
|
+
* team member availability with FTE-aware load balancing, CODEOWNERS rules, and
|
|
7
|
+
* current reviewer workload to suggest the most appropriate reviewers.
|
|
8
|
+
*
|
|
9
|
+
* @module mcp/server
|
|
10
|
+
*/
|
|
11
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
12
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
14
|
+
import { TOOLS } from "./tools.js";
|
|
15
|
+
import { ReviewerService } from "../services/reviewer-service.js";
|
|
16
|
+
import { ConfigService } from "../config/config.service.js";
|
|
17
|
+
import { Logger } from "../logging/logger.service.js";
|
|
18
|
+
import { ErrorHandler } from "../errors/error-handler.js";
|
|
19
|
+
import { CacheService } from "../cache/cache.service.js";
|
|
20
|
+
/**
|
|
21
|
+
* Main MCP Server class that handles tool requests and manages services
|
|
22
|
+
*/
|
|
23
|
+
export class AutoReviewerMCPServer {
|
|
24
|
+
server;
|
|
25
|
+
reviewerServices;
|
|
26
|
+
config;
|
|
27
|
+
logger;
|
|
28
|
+
cache;
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the MCP server with all required services
|
|
31
|
+
*/
|
|
32
|
+
constructor() {
|
|
33
|
+
// Initialize configuration
|
|
34
|
+
this.config = new ConfigService();
|
|
35
|
+
// Initialize logger with configured log level
|
|
36
|
+
const logLevel = Logger.parseLogLevel(this.config.get().logLevel);
|
|
37
|
+
this.logger = new Logger('MCPServer', logLevel);
|
|
38
|
+
// Log applied defaults
|
|
39
|
+
const defaults = this.config.getAppliedDefaults();
|
|
40
|
+
if (defaults.size > 0) {
|
|
41
|
+
this.logger.info('Using default configuration values', {
|
|
42
|
+
defaults: Array.from(defaults.entries()).map((entry) => ({ key: entry[0], value: entry[1] }))
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// Initialize cache with configured TTL
|
|
46
|
+
this.cache = new CacheService({ ttlMs: this.config.get().cacheTTL * 1000 }, this.logger.child('Cache'));
|
|
47
|
+
// Initialize MCP server
|
|
48
|
+
this.server = new Server({ name: "auto-reviewers-server", version: "1.0.0" }, { capabilities: { tools: {} } });
|
|
49
|
+
this.reviewerServices = new Map();
|
|
50
|
+
this.logger.info('MCP Server initialized', {
|
|
51
|
+
version: '1.0.0',
|
|
52
|
+
cacheTTL: this.config.get().cacheTTL,
|
|
53
|
+
logLevel: this.config.get().logLevel,
|
|
54
|
+
});
|
|
55
|
+
this.setupHandlers();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get or create a ReviewerService instance for the given configuration
|
|
59
|
+
* Services are cached per unique combination of GitLab URL, token, and repo path
|
|
60
|
+
*
|
|
61
|
+
* @param gitlabUrl - GitLab instance URL
|
|
62
|
+
* @param token - GitLab API token
|
|
63
|
+
* @param repoPath - Optional local repository path
|
|
64
|
+
* @returns ReviewerService instance
|
|
65
|
+
*/
|
|
66
|
+
getReviewerService(gitlabUrl, token, repoPath) {
|
|
67
|
+
const key = `${gitlabUrl}:${token}:${repoPath || "api"}`;
|
|
68
|
+
if (!this.reviewerServices.has(key)) {
|
|
69
|
+
const cacheEnabled = this.config.get().cacheEnabled;
|
|
70
|
+
this.reviewerServices.set(key, new ReviewerService(gitlabUrl, token, repoPath, this.logger.child('ReviewerService'), cacheEnabled ? this.cache : undefined));
|
|
71
|
+
this.logger.debug('Created new ReviewerService', {
|
|
72
|
+
gitlabUrl,
|
|
73
|
+
repoPath: repoPath || 'api-mode',
|
|
74
|
+
cacheEnabled
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return this.reviewerServices.get(key);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Set up MCP protocol request handlers
|
|
81
|
+
* Handles ListTools and CallTool requests
|
|
82
|
+
*/
|
|
83
|
+
setupHandlers() {
|
|
84
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
85
|
+
this.logger.debug('ListTools request received');
|
|
86
|
+
return { tools: TOOLS };
|
|
87
|
+
});
|
|
88
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
89
|
+
const { name, arguments: args } = request.params;
|
|
90
|
+
this.logger.info(`Tool call: ${name}`, { tool: name, args });
|
|
91
|
+
const endTimer = this.logger.startTimer(`Tool: ${name}`);
|
|
92
|
+
try {
|
|
93
|
+
const result = await ErrorHandler.wrap(() => this.handleToolCall(name, args), 'TOOL_CALL_FAILED', `Tool call ${name} failed`, { tool: name });
|
|
94
|
+
endTimer();
|
|
95
|
+
this.logger.info(`Tool call completed`, { tool: name });
|
|
96
|
+
return {
|
|
97
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
endTimer();
|
|
102
|
+
this.logger.error(`Tool call failed`, error instanceof Error ? error : new Error(String(error)));
|
|
103
|
+
const errorMessage = ErrorHandler.formatError(error instanceof Error ? error : new Error(String(error)));
|
|
104
|
+
return {
|
|
105
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
106
|
+
isError: true,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Handle a tool call request
|
|
113
|
+
* Routes the request to the appropriate ReviewerService method
|
|
114
|
+
*
|
|
115
|
+
* @param name - Tool name
|
|
116
|
+
* @param args - Tool arguments
|
|
117
|
+
* @returns Tool result
|
|
118
|
+
* @throws MCPError if tool is unknown or parameters are invalid
|
|
119
|
+
*/
|
|
120
|
+
async handleToolCall(name, args) {
|
|
121
|
+
const params = args;
|
|
122
|
+
// Get configuration with fallbacks
|
|
123
|
+
const config = this.config.get();
|
|
124
|
+
const gitlabUrl = (typeof params.gitlabUrl === 'string' ? params.gitlabUrl : undefined) ||
|
|
125
|
+
process.env.GITLAB_URL ||
|
|
126
|
+
config.gitlabUrl;
|
|
127
|
+
const token = (typeof params.gitlabToken === 'string' ? params.gitlabToken : undefined) ||
|
|
128
|
+
process.env.GITLAB_TOKEN;
|
|
129
|
+
const repoPath = (typeof params.repoPath === 'string' ? params.repoPath : undefined) ||
|
|
130
|
+
process.env.REPO_PATH ||
|
|
131
|
+
this.detectRepoPath();
|
|
132
|
+
if (!token) {
|
|
133
|
+
throw ErrorHandler.configurationError("GitLab token is required. Provide gitlabToken parameter or set GITLAB_TOKEN environment variable.", { gitlabUrl, hasRepoPath: !!repoPath });
|
|
134
|
+
}
|
|
135
|
+
this.logger.debug('Getting reviewer service', {
|
|
136
|
+
gitlabUrl,
|
|
137
|
+
hasToken: !!token,
|
|
138
|
+
repoPath: repoPath || 'api-mode'
|
|
139
|
+
});
|
|
140
|
+
const reviewerService = this.getReviewerService(gitlabUrl, token, repoPath);
|
|
141
|
+
switch (name) {
|
|
142
|
+
case "suggest_reviewers":
|
|
143
|
+
return reviewerService.suggestReviewers(params);
|
|
144
|
+
case "get_contributor_analysis":
|
|
145
|
+
return reviewerService.getContributorAnalysis(params);
|
|
146
|
+
case "get_reviewer_workload":
|
|
147
|
+
return reviewerService.getReviewerWorkload(params);
|
|
148
|
+
case "post_comment":
|
|
149
|
+
return reviewerService.postComment(params);
|
|
150
|
+
case "invite_reviewers":
|
|
151
|
+
return reviewerService.inviteReviewers(params);
|
|
152
|
+
default:
|
|
153
|
+
throw ErrorHandler.validationError(`Unknown tool: ${name}`, { tool: name });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Detect the local git repository path
|
|
158
|
+
* Attempts to find the git root directory from the current working directory
|
|
159
|
+
*
|
|
160
|
+
* @returns Git repository root path, or undefined if not in a git repository
|
|
161
|
+
*/
|
|
162
|
+
detectRepoPath() {
|
|
163
|
+
try {
|
|
164
|
+
const { execSync } = require("child_process");
|
|
165
|
+
const gitRoot = execSync("git rev-parse --show-toplevel", {
|
|
166
|
+
encoding: "utf-8",
|
|
167
|
+
cwd: process.cwd(),
|
|
168
|
+
}).trim();
|
|
169
|
+
this.logger.info('Detected git repository', { gitRoot });
|
|
170
|
+
return gitRoot;
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
this.logger.debug('No git repository detected, using API mode', {
|
|
174
|
+
cwd: process.cwd(),
|
|
175
|
+
});
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Start the MCP server
|
|
181
|
+
* Connects to stdio transport and begins listening for requests
|
|
182
|
+
*/
|
|
183
|
+
async run() {
|
|
184
|
+
const transport = new StdioServerTransport();
|
|
185
|
+
await this.server.connect(transport);
|
|
186
|
+
const stats = this.cache.getStats();
|
|
187
|
+
this.logger.info('Auto Reviewers MCP Server started successfully', {
|
|
188
|
+
cacheSize: stats.size,
|
|
189
|
+
cacheTTL: this.config.get().cacheTTL,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Gracefully shutdown the MCP server
|
|
194
|
+
* Logs cache statistics, clears cache, and closes the server connection
|
|
195
|
+
*/
|
|
196
|
+
async shutdown() {
|
|
197
|
+
this.logger.info('Shutting down MCP server...');
|
|
198
|
+
// Log cache statistics before shutdown
|
|
199
|
+
const stats = this.cache.getStats();
|
|
200
|
+
this.logger.info('Cache statistics', {
|
|
201
|
+
hits: stats.hits,
|
|
202
|
+
misses: stats.misses,
|
|
203
|
+
size: stats.size,
|
|
204
|
+
hitRate: stats.hitRate,
|
|
205
|
+
});
|
|
206
|
+
// Clear cache
|
|
207
|
+
this.cache.clear();
|
|
208
|
+
// Close server
|
|
209
|
+
await this.server.close();
|
|
210
|
+
this.logger.info('MCP server shut down successfully');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=server.js.map
|