gitlab-auto-reviewers 2.0.0 → 2.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/LICENSE +1 -1
- package/README.md +20 -10
- package/dist/bin/cli.js +155 -85
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/index.d.ts +1 -8
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +26 -9
- package/dist/bin/index.js.map +1 -1
- package/dist/bin/mcp.js +0 -0
- package/dist/cli/cicd-integration.d.ts +127 -0
- package/dist/cli/cicd-integration.d.ts.map +1 -0
- package/dist/cli/cicd-integration.js +385 -0
- package/dist/cli/cicd-integration.js.map +1 -0
- package/dist/cli/commands.d.ts +21 -4
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +417 -71
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/config.d.ts +145 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +277 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consistency-validator.d.ts +175 -0
- package/dist/cli/consistency-validator.d.ts.map +1 -0
- package/dist/cli/consistency-validator.js +599 -0
- package/dist/cli/consistency-validator.js.map +1 -0
- package/dist/cli/data-source-consistency.d.ts +105 -0
- package/dist/cli/data-source-consistency.d.ts.map +1 -0
- package/dist/cli/data-source-consistency.js +271 -0
- package/dist/cli/data-source-consistency.js.map +1 -0
- package/dist/cli/data-source-selector.d.ts +103 -0
- package/dist/cli/data-source-selector.d.ts.map +1 -0
- package/dist/cli/data-source-selector.js +242 -0
- package/dist/cli/data-source-selector.js.map +1 -0
- package/dist/cli/enhanced-cli.d.ts +104 -0
- package/dist/cli/enhanced-cli.d.ts.map +1 -0
- package/dist/cli/enhanced-cli.js +321 -0
- package/dist/cli/enhanced-cli.js.map +1 -0
- package/dist/cli/enhanced-data-source-resolver.d.ts +67 -0
- package/dist/cli/enhanced-data-source-resolver.d.ts.map +1 -0
- package/dist/cli/enhanced-data-source-resolver.js +249 -0
- package/dist/cli/enhanced-data-source-resolver.js.map +1 -0
- package/dist/cli/enhanced-parameter-resolver.d.ts +111 -0
- package/dist/cli/enhanced-parameter-resolver.d.ts.map +1 -0
- package/dist/cli/enhanced-parameter-resolver.js +233 -0
- package/dist/cli/enhanced-parameter-resolver.js.map +1 -0
- package/dist/cli/errors.d.ts +105 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +577 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/output.d.ts +43 -3
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +157 -30
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/parameter-source-tracker.d.ts +169 -0
- package/dist/cli/parameter-source-tracker.d.ts.map +1 -0
- package/dist/cli/parameter-source-tracker.js +252 -0
- package/dist/cli/parameter-source-tracker.js.map +1 -0
- package/dist/cli/template-engine.d.ts +109 -0
- package/dist/cli/template-engine.d.ts.map +1 -0
- package/dist/cli/template-engine.js +220 -0
- package/dist/cli/template-engine.js.map +1 -0
- package/dist/config/config.service.d.ts +24 -2
- package/dist/config/config.service.d.ts.map +1 -1
- package/dist/config/config.service.js +39 -6
- package/dist/config/config.service.js.map +1 -1
- package/dist/datasources/local-git-data-source.d.ts +39 -0
- package/dist/datasources/local-git-data-source.d.ts.map +1 -1
- package/dist/datasources/local-git-data-source.js +121 -1
- package/dist/datasources/local-git-data-source.js.map +1 -1
- package/dist/enhanced-config.js +26 -0
- package/dist/index.js +0 -0
- package/dist/mcp/server.js +2 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/services/blacklist.service.d.ts +11 -5
- package/dist/services/blacklist.service.d.ts.map +1 -1
- package/dist/services/blacklist.service.js +28 -7
- package/dist/services/blacklist.service.js.map +1 -1
- package/dist/services/reviewer-service.d.ts +24 -0
- package/dist/services/reviewer-service.d.ts.map +1 -1
- package/dist/services/reviewer-service.js +177 -7
- package/dist/services/reviewer-service.js.map +1 -1
- package/dist/services/whitelist.service.js +1 -1
- package/dist/services/whitelist.service.js.map +1 -1
- package/dist/types/enhanced-config.d.ts +121 -0
- package/dist/types/enhanced-config.d.ts.map +1 -0
- package/dist/types/enhanced-config.js +27 -0
- package/dist/types/enhanced-config.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/bin/deprecated-mcp.d.ts +0 -12
- package/dist/bin/deprecated-mcp.d.ts.map +0 -1
- package/dist/bin/deprecated-mcp.js +0 -73
- package/dist/bin/deprecated-mcp.js.map +0 -1
- package/dist/tools.d.ts +0 -22
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -176
- package/dist/tools.js.map +0 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter Source Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks and logs the source of each configuration parameter for debugging.
|
|
5
|
+
* Implements Requirement 3.5: THE System SHALL log the source of each configuration value for debugging
|
|
6
|
+
*
|
|
7
|
+
* @module cli/parameter-source-tracker
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Parameter Source Tracker
|
|
11
|
+
*
|
|
12
|
+
* Tracks the source of each configuration parameter and provides
|
|
13
|
+
* comprehensive logging for debugging configuration issues.
|
|
14
|
+
*/
|
|
15
|
+
export class ParameterSourceTracker {
|
|
16
|
+
parameters = new Map();
|
|
17
|
+
logger;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new ParameterSourceTracker instance
|
|
20
|
+
*
|
|
21
|
+
* @param logger - Logger instance for outputting parameter source information
|
|
22
|
+
*/
|
|
23
|
+
constructor(logger) {
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Track a parameter with its value and source
|
|
28
|
+
*/
|
|
29
|
+
track(name, value, source, options) {
|
|
30
|
+
this.parameters.set(name, {
|
|
31
|
+
name,
|
|
32
|
+
value,
|
|
33
|
+
source,
|
|
34
|
+
sourceDetail: options?.sourceDetail,
|
|
35
|
+
masked: options?.masked,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a parameter value with source tracking
|
|
40
|
+
* Implements the precedence: CLI argument > environment variable > auto-detected > config file > default
|
|
41
|
+
*/
|
|
42
|
+
resolve(name, cliValue, envVarName, autoDetectFn, configValue, defaultValue, options) {
|
|
43
|
+
// Priority 1: CLI argument
|
|
44
|
+
if (cliValue !== undefined) {
|
|
45
|
+
this.track(name, cliValue, 'cli-argument', {
|
|
46
|
+
sourceDetail: `--${this.toKebabCase(name)}`,
|
|
47
|
+
masked: options?.masked,
|
|
48
|
+
});
|
|
49
|
+
return cliValue;
|
|
50
|
+
}
|
|
51
|
+
// Priority 2: Environment variable
|
|
52
|
+
if (envVarName) {
|
|
53
|
+
const envValue = process.env[envVarName];
|
|
54
|
+
if (envValue !== undefined && envValue !== '') {
|
|
55
|
+
const parsedValue = this.parseEnvValue(envValue);
|
|
56
|
+
this.track(name, parsedValue, 'environment', {
|
|
57
|
+
sourceDetail: envVarName,
|
|
58
|
+
masked: options?.masked,
|
|
59
|
+
});
|
|
60
|
+
return parsedValue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Priority 3: Auto-detection
|
|
64
|
+
if (autoDetectFn) {
|
|
65
|
+
const autoValue = autoDetectFn();
|
|
66
|
+
if (autoValue !== undefined) {
|
|
67
|
+
this.track(name, autoValue, 'auto-detected', {
|
|
68
|
+
masked: options?.masked,
|
|
69
|
+
});
|
|
70
|
+
return autoValue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Priority 4: Config file
|
|
74
|
+
if (configValue !== undefined) {
|
|
75
|
+
this.track(name, configValue, 'config-file', {
|
|
76
|
+
masked: options?.masked,
|
|
77
|
+
});
|
|
78
|
+
return configValue;
|
|
79
|
+
}
|
|
80
|
+
// Priority 5: Default value
|
|
81
|
+
if (defaultValue !== undefined) {
|
|
82
|
+
this.track(name, defaultValue, 'default', {
|
|
83
|
+
masked: options?.masked,
|
|
84
|
+
});
|
|
85
|
+
return defaultValue;
|
|
86
|
+
}
|
|
87
|
+
// Not set
|
|
88
|
+
this.track(name, undefined, 'not-set', {
|
|
89
|
+
masked: options?.masked,
|
|
90
|
+
});
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get all tracked parameters
|
|
95
|
+
*/
|
|
96
|
+
getAll() {
|
|
97
|
+
return new Map(this.parameters);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get a specific tracked parameter
|
|
101
|
+
*
|
|
102
|
+
* @param name - The name of the parameter to retrieve
|
|
103
|
+
* @returns The tracked parameter or undefined if not found
|
|
104
|
+
*/
|
|
105
|
+
get(name) {
|
|
106
|
+
return this.parameters.get(name);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Log all parameter sources
|
|
110
|
+
* This implements Requirement 3.5
|
|
111
|
+
*/
|
|
112
|
+
logParameterSources() {
|
|
113
|
+
this.logger.info('Configuration resolved - parameter sources:');
|
|
114
|
+
const sortedParams = Array.from(this.parameters.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
115
|
+
for (const [name, param] of sortedParams) {
|
|
116
|
+
const displayValue = this.formatValueForLog(param);
|
|
117
|
+
const sourceInfo = this.formatSourceForLog(param);
|
|
118
|
+
this.logger.info(` ${name}: ${displayValue} (${sourceInfo})`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Log parameter sources in a structured format (for JSON output)
|
|
123
|
+
*/
|
|
124
|
+
toStructuredLog() {
|
|
125
|
+
const result = {};
|
|
126
|
+
for (const [name, param] of this.parameters) {
|
|
127
|
+
result[name] = {
|
|
128
|
+
value: param.masked ? '***' : param.value,
|
|
129
|
+
source: param.source,
|
|
130
|
+
sourceDetail: param.sourceDetail,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Format value for logging (handles masking and undefined)
|
|
137
|
+
*/
|
|
138
|
+
formatValueForLog(param) {
|
|
139
|
+
if (param.value === undefined) {
|
|
140
|
+
return '<not set>';
|
|
141
|
+
}
|
|
142
|
+
if (param.masked) {
|
|
143
|
+
return '***';
|
|
144
|
+
}
|
|
145
|
+
if (typeof param.value === 'string') {
|
|
146
|
+
// Truncate long strings
|
|
147
|
+
if (param.value.length > 50) {
|
|
148
|
+
return `"${param.value.substring(0, 47)}..."`;
|
|
149
|
+
}
|
|
150
|
+
return `"${param.value}"`;
|
|
151
|
+
}
|
|
152
|
+
return String(param.value);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Format source information for logging
|
|
156
|
+
*/
|
|
157
|
+
formatSourceForLog(param) {
|
|
158
|
+
switch (param.source) {
|
|
159
|
+
case 'cli-argument':
|
|
160
|
+
return `CLI argument ${param.sourceDetail || ''}`.trim();
|
|
161
|
+
case 'environment':
|
|
162
|
+
return `environment variable ${param.sourceDetail || ''}`.trim();
|
|
163
|
+
case 'auto-detected':
|
|
164
|
+
return param.sourceDetail ? `auto-detected from ${param.sourceDetail}` : 'auto-detected';
|
|
165
|
+
case 'config-file':
|
|
166
|
+
return param.sourceDetail ? `config file ${param.sourceDetail}` : 'config file';
|
|
167
|
+
case 'default':
|
|
168
|
+
return 'default';
|
|
169
|
+
case 'not-set':
|
|
170
|
+
return 'not set';
|
|
171
|
+
default:
|
|
172
|
+
return param.source;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Convert camelCase to kebab-case
|
|
177
|
+
*/
|
|
178
|
+
toKebabCase(str) {
|
|
179
|
+
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Parse environment variable value to appropriate type
|
|
183
|
+
*/
|
|
184
|
+
parseEnvValue(value) {
|
|
185
|
+
// Try to parse as number
|
|
186
|
+
const num = Number(value);
|
|
187
|
+
if (!isNaN(num) && value.trim() !== '') {
|
|
188
|
+
return num;
|
|
189
|
+
}
|
|
190
|
+
// Try to parse as boolean
|
|
191
|
+
if (value.toLowerCase() === 'true') {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
if (value.toLowerCase() === 'false') {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
// Return as string
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Create a parameter source tracker and resolve all CLI parameters
|
|
203
|
+
*
|
|
204
|
+
* @param options - CLI options from argument parsing
|
|
205
|
+
* @param cicdEnv - CI/CD environment detection result
|
|
206
|
+
* @param logger - Logger instance
|
|
207
|
+
* @returns Resolved parameters with source tracking
|
|
208
|
+
*/
|
|
209
|
+
export function resolveParametersWithTracking(options, cicdEnv, logger) {
|
|
210
|
+
const tracker = new ParameterSourceTracker(logger);
|
|
211
|
+
// Resolve each parameter with source tracking
|
|
212
|
+
// NOTE: We need to resolve project FIRST to determine if we should auto-detect repoPath
|
|
213
|
+
// When both project ID and project directory are available in CI, prefer API mode (project ID)
|
|
214
|
+
// because it provides more reliable data access in CI environments
|
|
215
|
+
const project = tracker.resolve('project', options.project, 'CI_PROJECT_ID', // Also check CI_PROJECT_ID environment variable
|
|
216
|
+
() => cicdEnv.isCI ? cicdEnv.projectId : undefined, undefined, undefined);
|
|
217
|
+
// Only auto-detect repoPath from CI_PROJECT_DIR if project is NOT already set
|
|
218
|
+
// This prevents the "Cannot specify both --repo-path and --project" conflict
|
|
219
|
+
const repoPath = tracker.resolve('repoPath', options.repoPath, project ? undefined : 'CI_PROJECT_DIR', // Only use CI_PROJECT_DIR if project is not set
|
|
220
|
+
undefined, undefined, undefined);
|
|
221
|
+
// Resolve mergeRequestIid FIRST to determine if we should auto-detect branch
|
|
222
|
+
// When both MR IID and branch are available in CI, prefer MR IID because
|
|
223
|
+
// it provides more specific context for reviewer suggestions
|
|
224
|
+
const mergeRequestIid = tracker.resolve('mergeRequestIid', options.mergeRequestIid, 'CI_MERGE_REQUEST_IID', () => cicdEnv.isCI ? cicdEnv.mergeRequestIid : undefined, undefined, undefined);
|
|
225
|
+
// Only auto-detect branch from CI_COMMIT_REF_NAME if mergeRequestIid is NOT already set
|
|
226
|
+
// This prevents the "Cannot specify both merge request IID and branch name" conflict
|
|
227
|
+
const branch = tracker.resolve('branch', options.branch, mergeRequestIid ? undefined : 'CI_COMMIT_REF_NAME', // Only use CI_COMMIT_REF_NAME if MR IID is not set
|
|
228
|
+
() => (cicdEnv.isCI && !mergeRequestIid) ? cicdEnv.branch : undefined, undefined, undefined);
|
|
229
|
+
const gitlabUrl = tracker.resolve('gitlabUrl', options.gitlabUrl, 'GITLAB_URL', () => process.env.CI_SERVER_URL, // Auto-detect from GitLab CI environment
|
|
230
|
+
undefined, 'https://gitlab.com') || 'https://gitlab.com';
|
|
231
|
+
const gitlabToken = tracker.resolve('gitlabToken', options.gitlabToken, 'GITLAB_TOKEN', () => process.env.CI_JOB_TOKEN, undefined, undefined, { masked: true });
|
|
232
|
+
const format = tracker.resolve('format', options.format, undefined, () => cicdEnv.isCI ? 'json' : undefined, undefined, 'text') || 'text';
|
|
233
|
+
const verbose = tracker.resolve('verbose', options.verbose, undefined, undefined, undefined, false) || false;
|
|
234
|
+
const dryRun = tracker.resolve('dryRun', options.dryRun, undefined, undefined, undefined, false) || false;
|
|
235
|
+
const quiet = tracker.resolve('quiet', options.quiet, undefined, () => cicdEnv.isCI ? true : undefined, undefined, false) || false;
|
|
236
|
+
return {
|
|
237
|
+
tracker,
|
|
238
|
+
resolved: {
|
|
239
|
+
repoPath,
|
|
240
|
+
project,
|
|
241
|
+
mergeRequestIid,
|
|
242
|
+
branch,
|
|
243
|
+
gitlabUrl,
|
|
244
|
+
gitlabToken,
|
|
245
|
+
format,
|
|
246
|
+
verbose,
|
|
247
|
+
dryRun,
|
|
248
|
+
quiet,
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=parameter-source-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-source-tracker.js","sourceRoot":"","sources":["../../src/cli/parameter-source-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Engine for CLI Comment Generation
|
|
3
|
+
*
|
|
4
|
+
* This module provides template loading, compilation, and rendering
|
|
5
|
+
* for custom comment formats in the CLI.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/template-engine
|
|
8
|
+
*/
|
|
9
|
+
import type { AutoReviewerResult } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Compiled template interface
|
|
12
|
+
*/
|
|
13
|
+
export interface CompiledTemplate {
|
|
14
|
+
render(data: TemplateData): string;
|
|
15
|
+
validate(): boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Template data interface
|
|
19
|
+
*
|
|
20
|
+
* @property contributors - Array of contributor suggestions with scoring and reasoning
|
|
21
|
+
* @property teamMembers - Array of team member suggestions with workload information
|
|
22
|
+
* @property codeOwners - Array of code owner suggestions based on CODEOWNERS file
|
|
23
|
+
* @property summary - Summary statistics for the reviewer suggestions
|
|
24
|
+
* @property timestamp - ISO timestamp when the analysis was performed
|
|
25
|
+
* @property projectId - Optional GitLab project ID for context
|
|
26
|
+
* @property mergeRequestIid - Optional merge request internal ID for context
|
|
27
|
+
*/
|
|
28
|
+
export interface TemplateData {
|
|
29
|
+
contributors: Array<{
|
|
30
|
+
username: string;
|
|
31
|
+
reason: string;
|
|
32
|
+
workload: number;
|
|
33
|
+
fte?: number;
|
|
34
|
+
}>;
|
|
35
|
+
teamMembers: Array<{
|
|
36
|
+
username: string;
|
|
37
|
+
reason: string;
|
|
38
|
+
workload: number;
|
|
39
|
+
fte?: number;
|
|
40
|
+
}>;
|
|
41
|
+
codeOwners: Array<{
|
|
42
|
+
username: string;
|
|
43
|
+
reason: string;
|
|
44
|
+
workload: number;
|
|
45
|
+
fte?: number;
|
|
46
|
+
}>;
|
|
47
|
+
summary: {
|
|
48
|
+
totalSuggestions: number;
|
|
49
|
+
contributorCount: number;
|
|
50
|
+
teamMemberCount: number;
|
|
51
|
+
codeOwnerCount: number;
|
|
52
|
+
};
|
|
53
|
+
timestamp: string;
|
|
54
|
+
projectId?: string;
|
|
55
|
+
mergeRequestIid?: number;
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Template engine for custom comment formats
|
|
60
|
+
*/
|
|
61
|
+
export declare class TemplateEngine {
|
|
62
|
+
private templates;
|
|
63
|
+
/**
|
|
64
|
+
* Load and compile a template from file
|
|
65
|
+
*
|
|
66
|
+
* @param templatePath - Path to the template file
|
|
67
|
+
* @returns Compiled template
|
|
68
|
+
* @throws Error if template cannot be loaded or compiled
|
|
69
|
+
*/
|
|
70
|
+
loadTemplate(templatePath: string): Promise<CompiledTemplate>;
|
|
71
|
+
/**
|
|
72
|
+
* Compile a template from string content
|
|
73
|
+
*
|
|
74
|
+
* @param content - Template content
|
|
75
|
+
* @returns Compiled template
|
|
76
|
+
*/
|
|
77
|
+
compileTemplate(content: string): CompiledTemplate;
|
|
78
|
+
/**
|
|
79
|
+
* Get the default template content
|
|
80
|
+
*
|
|
81
|
+
* @returns Default template content matching MCP server format
|
|
82
|
+
*/
|
|
83
|
+
getDefaultTemplate(): string;
|
|
84
|
+
/**
|
|
85
|
+
* Render a comment using the default or custom template
|
|
86
|
+
*
|
|
87
|
+
* @param result - Reviewer analysis result
|
|
88
|
+
* @param templatePath - Optional custom template path
|
|
89
|
+
* @returns Rendered comment
|
|
90
|
+
*/
|
|
91
|
+
renderComment(result: AutoReviewerResult, templatePath?: string): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Validate a template file
|
|
94
|
+
*
|
|
95
|
+
* @param templatePath - Path to the template file
|
|
96
|
+
* @returns True if template is valid
|
|
97
|
+
* @throws Error if template is invalid
|
|
98
|
+
*/
|
|
99
|
+
validateTemplate(templatePath: string): Promise<boolean>;
|
|
100
|
+
/**
|
|
101
|
+
* Clear template cache
|
|
102
|
+
*/
|
|
103
|
+
clearCache(): void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Default template engine instance
|
|
107
|
+
*/
|
|
108
|
+
export declare const templateEngine: TemplateEngine;
|
|
109
|
+
//# sourceMappingURL=template-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../../src/cli/template-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC;IACnC,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,KAAK,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,UAAU,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAwED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAuC;IAExD;;;;;;OAMG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0BnE;;;;;OAKG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB;IAIlD;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;IAkC5B;;;;;;OAMG;IACG,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwCvF;;;;;;OAMG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK9D;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Engine for CLI Comment Generation
|
|
3
|
+
*
|
|
4
|
+
* This module provides template loading, compilation, and rendering
|
|
5
|
+
* for custom comment formats in the CLI.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/template-engine
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from 'fs';
|
|
10
|
+
import { resolve } from 'path';
|
|
11
|
+
/**
|
|
12
|
+
* Simple template implementation
|
|
13
|
+
*/
|
|
14
|
+
class SimpleTemplate {
|
|
15
|
+
content;
|
|
16
|
+
constructor(content) {
|
|
17
|
+
this.content = content;
|
|
18
|
+
}
|
|
19
|
+
render(data) {
|
|
20
|
+
let result = this.content;
|
|
21
|
+
// Replace template variables
|
|
22
|
+
result = result.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (match, path) => {
|
|
23
|
+
const value = this.getNestedValue(data, path);
|
|
24
|
+
return value !== undefined ? String(value) : match;
|
|
25
|
+
});
|
|
26
|
+
// Handle loops for contributors
|
|
27
|
+
result = result.replace(/\{\{#each contributors\}\}([\s\S]*?)\{\{\/each\}\}/g, (_match, template) => {
|
|
28
|
+
return data.contributors.map(contributor => {
|
|
29
|
+
return template.replace(/\{\{(\w+)\}\}/g, (innerMatch, prop) => {
|
|
30
|
+
const value = contributor[prop];
|
|
31
|
+
return value !== undefined ? String(value) : innerMatch;
|
|
32
|
+
});
|
|
33
|
+
}).join('');
|
|
34
|
+
});
|
|
35
|
+
// Handle loops for team members
|
|
36
|
+
result = result.replace(/\{\{#each teamMembers\}\}([\s\S]*?)\{\{\/each\}\}/g, (_match, template) => {
|
|
37
|
+
return data.teamMembers.map(member => {
|
|
38
|
+
return template.replace(/\{\{(\w+)\}\}/g, (innerMatch, prop) => {
|
|
39
|
+
const value = member[prop];
|
|
40
|
+
return value !== undefined ? String(value) : innerMatch;
|
|
41
|
+
});
|
|
42
|
+
}).join('');
|
|
43
|
+
});
|
|
44
|
+
// Handle loops for code owners
|
|
45
|
+
result = result.replace(/\{\{#each codeOwners\}\}([\s\S]*?)\{\{\/each\}\}/g, (_match, template) => {
|
|
46
|
+
return data.codeOwners.map(owner => {
|
|
47
|
+
return template.replace(/\{\{(\w+)\}\}/g, (innerMatch, prop) => {
|
|
48
|
+
const value = owner[prop];
|
|
49
|
+
return value !== undefined ? String(value) : innerMatch;
|
|
50
|
+
});
|
|
51
|
+
}).join('');
|
|
52
|
+
});
|
|
53
|
+
// Handle conditionals
|
|
54
|
+
result = result.replace(/\{\{#if (\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_match, path, content) => {
|
|
55
|
+
const value = this.getNestedValue(data, path);
|
|
56
|
+
return value ? content : '';
|
|
57
|
+
});
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
validate() {
|
|
61
|
+
// Basic validation - check for balanced template tags
|
|
62
|
+
const openTags = (this.content.match(/\{\{#/g) || []).length;
|
|
63
|
+
const closeTags = (this.content.match(/\{\{\//g) || []).length;
|
|
64
|
+
return openTags === closeTags;
|
|
65
|
+
}
|
|
66
|
+
getNestedValue(obj, path) {
|
|
67
|
+
return path.split('.').reduce((current, key) => {
|
|
68
|
+
return current && typeof current === 'object' && current !== null && key in current
|
|
69
|
+
? current[key]
|
|
70
|
+
: undefined;
|
|
71
|
+
}, obj);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Template engine for custom comment formats
|
|
76
|
+
*/
|
|
77
|
+
export class TemplateEngine {
|
|
78
|
+
templates = new Map();
|
|
79
|
+
/**
|
|
80
|
+
* Load and compile a template from file
|
|
81
|
+
*
|
|
82
|
+
* @param templatePath - Path to the template file
|
|
83
|
+
* @returns Compiled template
|
|
84
|
+
* @throws Error if template cannot be loaded or compiled
|
|
85
|
+
*/
|
|
86
|
+
async loadTemplate(templatePath) {
|
|
87
|
+
if (this.templates.has(templatePath)) {
|
|
88
|
+
return this.templates.get(templatePath);
|
|
89
|
+
}
|
|
90
|
+
const resolvedPath = resolve(templatePath);
|
|
91
|
+
if (!existsSync(resolvedPath)) {
|
|
92
|
+
throw new Error(`Template file not found: ${resolvedPath}`);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const content = readFileSync(resolvedPath, 'utf-8');
|
|
96
|
+
const compiled = this.compileTemplate(content);
|
|
97
|
+
if (!compiled.validate()) {
|
|
98
|
+
throw new Error(`Template validation failed: ${templatePath}`);
|
|
99
|
+
}
|
|
100
|
+
this.templates.set(templatePath, compiled);
|
|
101
|
+
return compiled;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
throw new Error(`Failed to load template ${templatePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Compile a template from string content
|
|
109
|
+
*
|
|
110
|
+
* @param content - Template content
|
|
111
|
+
* @returns Compiled template
|
|
112
|
+
*/
|
|
113
|
+
compileTemplate(content) {
|
|
114
|
+
return new SimpleTemplate(content);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get the default template content
|
|
118
|
+
*
|
|
119
|
+
* @returns Default template content matching MCP server format
|
|
120
|
+
*/
|
|
121
|
+
getDefaultTemplate() {
|
|
122
|
+
return `## 🔍 Suggested Reviewers
|
|
123
|
+
|
|
124
|
+
{{#if summary.totalSuggestions}}
|
|
125
|
+
Based on the analysis of changed files, here are the suggested reviewers:
|
|
126
|
+
|
|
127
|
+
{{#if contributors}}
|
|
128
|
+
### 📝 **Contributors** ({{contributors.length}})
|
|
129
|
+
{{#each contributors}}
|
|
130
|
+
- **@{{username}}** - {{reason}} (Current workload: {{workload}} MRs{{#if fte}}, FTE: {{fte}}{{/if}})
|
|
131
|
+
{{/each}}
|
|
132
|
+
|
|
133
|
+
{{/if}}
|
|
134
|
+
{{#if teamMembers}}
|
|
135
|
+
### 👥 **Team Members** ({{teamMembers.length}})
|
|
136
|
+
{{#each teamMembers}}
|
|
137
|
+
- **@{{username}}** - {{reason}} (Current workload: {{workload}} MRs{{#if fte}}, FTE: {{fte}}{{/if}})
|
|
138
|
+
{{/each}}
|
|
139
|
+
|
|
140
|
+
{{/if}}
|
|
141
|
+
{{#if codeOwners}}
|
|
142
|
+
### 🏠 **Code Owners** ({{codeOwners.length}})
|
|
143
|
+
{{#each codeOwners}}
|
|
144
|
+
- **@{{username}}** - {{reason}} (Current workload: {{workload}} MRs{{#if fte}}, FTE: {{fte}}{{/if}})
|
|
145
|
+
{{/each}}
|
|
146
|
+
|
|
147
|
+
{{/if}}
|
|
148
|
+
---
|
|
149
|
+
*Total suggestions: {{summary.totalSuggestions}} | Generated at {{timestamp}}*
|
|
150
|
+
{{else}}
|
|
151
|
+
No reviewer suggestions found based on the current analysis.
|
|
152
|
+
{{/if}}`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Render a comment using the default or custom template
|
|
156
|
+
*
|
|
157
|
+
* @param result - Reviewer analysis result
|
|
158
|
+
* @param templatePath - Optional custom template path
|
|
159
|
+
* @returns Rendered comment
|
|
160
|
+
*/
|
|
161
|
+
async renderComment(result, templatePath) {
|
|
162
|
+
let template;
|
|
163
|
+
if (templatePath) {
|
|
164
|
+
template = await this.loadTemplate(templatePath);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
template = this.compileTemplate(this.getDefaultTemplate());
|
|
168
|
+
}
|
|
169
|
+
const templateData = {
|
|
170
|
+
contributors: result.contributors.map(c => ({
|
|
171
|
+
username: c.username,
|
|
172
|
+
reason: c.reason,
|
|
173
|
+
workload: c.workload,
|
|
174
|
+
fte: c.fte,
|
|
175
|
+
})),
|
|
176
|
+
teamMembers: result.teamMembers.map(t => ({
|
|
177
|
+
username: t.username,
|
|
178
|
+
reason: t.reason,
|
|
179
|
+
workload: t.workload,
|
|
180
|
+
fte: t.fte,
|
|
181
|
+
})),
|
|
182
|
+
codeOwners: result.codeOwners.map(o => ({
|
|
183
|
+
username: o.username,
|
|
184
|
+
reason: o.reason,
|
|
185
|
+
workload: o.workload,
|
|
186
|
+
fte: o.fte,
|
|
187
|
+
})),
|
|
188
|
+
summary: {
|
|
189
|
+
totalSuggestions: result.contributors.length + result.teamMembers.length + result.codeOwners.length,
|
|
190
|
+
contributorCount: result.contributors.length,
|
|
191
|
+
teamMemberCount: result.teamMembers.length,
|
|
192
|
+
codeOwnerCount: result.codeOwners.length,
|
|
193
|
+
},
|
|
194
|
+
timestamp: new Date().toISOString(),
|
|
195
|
+
};
|
|
196
|
+
return template.render(templateData);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Validate a template file
|
|
200
|
+
*
|
|
201
|
+
* @param templatePath - Path to the template file
|
|
202
|
+
* @returns True if template is valid
|
|
203
|
+
* @throws Error if template is invalid
|
|
204
|
+
*/
|
|
205
|
+
async validateTemplate(templatePath) {
|
|
206
|
+
const template = await this.loadTemplate(templatePath);
|
|
207
|
+
return template.validate();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Clear template cache
|
|
211
|
+
*/
|
|
212
|
+
clearCache() {
|
|
213
|
+
this.templates.clear();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Default template engine instance
|
|
218
|
+
*/
|
|
219
|
+
export const templateEngine = new TemplateEngine();
|
|
220
|
+
//# sourceMappingURL=template-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-engine.js","sourceRoot":"","sources":["../../src/cli/template-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,17 +37,36 @@ export interface MCPServerConfig {
|
|
|
37
37
|
*
|
|
38
38
|
* Loads configuration from environment variables, applies defaults,
|
|
39
39
|
* validates settings, and provides type-safe access to configuration.
|
|
40
|
+
*
|
|
41
|
+
* Supports singleton pattern to avoid multiple instantiations and duplicate logging.
|
|
40
42
|
*/
|
|
41
43
|
export declare class ConfigService {
|
|
44
|
+
private static instance;
|
|
45
|
+
private static hasLoggedDefaults;
|
|
42
46
|
private config;
|
|
43
47
|
private appliedDefaults;
|
|
44
48
|
/**
|
|
45
49
|
* Create a new configuration service
|
|
46
50
|
*
|
|
47
51
|
* Automatically loads and validates configuration from environment variables.
|
|
48
|
-
* Logs any default values that were applied.
|
|
52
|
+
* Logs any default values that were applied (only once per process).
|
|
53
|
+
*
|
|
54
|
+
* @param skipLogging - If true, skip logging applied defaults (useful for testing)
|
|
49
55
|
*/
|
|
50
|
-
constructor();
|
|
56
|
+
constructor(skipLogging?: boolean);
|
|
57
|
+
/**
|
|
58
|
+
* Get the singleton instance of ConfigService
|
|
59
|
+
*
|
|
60
|
+
* This ensures configuration is only loaded and logged once per process,
|
|
61
|
+
* avoiding duplicate log messages when multiple components need config.
|
|
62
|
+
*
|
|
63
|
+
* @returns The shared ConfigService instance
|
|
64
|
+
*/
|
|
65
|
+
static getInstance(): ConfigService;
|
|
66
|
+
/**
|
|
67
|
+
* Reset the singleton instance (primarily for testing)
|
|
68
|
+
*/
|
|
69
|
+
static resetInstance(): void;
|
|
51
70
|
/**
|
|
52
71
|
* Get the current configuration (read-only)
|
|
53
72
|
*/
|
|
@@ -58,6 +77,8 @@ export declare class ConfigService {
|
|
|
58
77
|
getAppliedDefaults(): ReadonlyMap<string, unknown>;
|
|
59
78
|
/**
|
|
60
79
|
* Load configuration from environment variables and validate
|
|
80
|
+
*
|
|
81
|
+
* @param skipLogging - If true, skip logging applied defaults
|
|
61
82
|
*/
|
|
62
83
|
private loadAndValidate;
|
|
63
84
|
/**
|
|
@@ -83,6 +104,7 @@ export declare class ConfigService {
|
|
|
83
104
|
/**
|
|
84
105
|
* Log which default values were applied
|
|
85
106
|
* Uses console.error since MCP servers log to stderr
|
|
107
|
+
* Only logs once per process to avoid duplicate messages
|
|
86
108
|
*/
|
|
87
109
|
private logAppliedDefaults;
|
|
88
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.service.d.ts","sourceRoot":"","sources":["../../src/config/config.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAG5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IAGrB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"config.service.d.ts","sourceRoot":"","sources":["../../src/config/config.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAG5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IAGrB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAS;IAEzC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAmC;IAE1D;;;;;;;OAOG;gBACS,WAAW,UAAQ;IAI/B;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAK5B;;OAEG;IACH,GAAG,IAAI,QAAQ,CAAC,eAAe,CAAC;IAIhC;;OAEG;IACH,kBAAkB,IAAI,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC;IAKlD;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,OAAO,CAAC,cAAc;IA2CtB;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAa3B"}
|