@juspay/yama 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/CHANGELOG.md +51 -0
- package/README.md +828 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.js +541 -0
- package/dist/core/ContextGatherer.d.ts +105 -0
- package/dist/core/ContextGatherer.js +454 -0
- package/dist/core/Guardian.d.ts +80 -0
- package/dist/core/Guardian.js +457 -0
- package/dist/core/providers/BitbucketProvider.d.ts +105 -0
- package/dist/core/providers/BitbucketProvider.js +444 -0
- package/dist/features/CodeReviewer.d.ts +105 -0
- package/dist/features/CodeReviewer.js +1041 -0
- package/dist/features/DescriptionEnhancer.d.ts +64 -0
- package/dist/features/DescriptionEnhancer.js +448 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +60 -0
- package/dist/types/index.d.ts +419 -0
- package/dist/types/index.js +44 -0
- package/dist/utils/Cache.d.ts +92 -0
- package/dist/utils/Cache.js +255 -0
- package/dist/utils/ConfigManager.d.ts +84 -0
- package/dist/utils/ConfigManager.js +590 -0
- package/dist/utils/Logger.d.ts +30 -0
- package/dist/utils/Logger.js +217 -0
- package/package.json +138 -0
- package/yama.config.example.yaml +143 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Enhanced Logger utility - Optimized from both pr-police.js and pr-describe.js
|
|
4
|
+
* Provides consistent logging across all Guardian operations
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.logger = exports.Logger = void 0;
|
|
11
|
+
exports.createLogger = createLogger;
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const YAMA_BADGE = `
|
|
14
|
+
⚔️ ═══════════════════════════════════════════════════════════ ⚔️
|
|
15
|
+
██╗ ██╗ █████╗ ███╗ ███╗ █████╗
|
|
16
|
+
╚██╗ ██╔╝██╔══██╗████╗ ████║██╔══██╗
|
|
17
|
+
╚████╔╝ ███████║██╔████╔██║███████║
|
|
18
|
+
╚██╔╝ ██╔══██║██║╚██╔╝██║██╔══██║
|
|
19
|
+
██║ ██║ ██║██║ ╚═╝ ██║██║ ██║
|
|
20
|
+
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
|
|
21
|
+
⚔️ ═══════════════════════════════════════════════════════════ ⚔️
|
|
22
|
+
AI-Powered PR Automation • Enterprise Security • Code Quality Yama
|
|
23
|
+
`;
|
|
24
|
+
class Logger {
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.options = {
|
|
27
|
+
level: "info",
|
|
28
|
+
verbose: false,
|
|
29
|
+
format: "simple",
|
|
30
|
+
colors: true,
|
|
31
|
+
...options,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
shouldLog(level) {
|
|
35
|
+
const levels = {
|
|
36
|
+
debug: 0,
|
|
37
|
+
info: 1,
|
|
38
|
+
warn: 2,
|
|
39
|
+
error: 3,
|
|
40
|
+
};
|
|
41
|
+
return levels[level] >= levels[this.options.level];
|
|
42
|
+
}
|
|
43
|
+
formatMessage(level, message, ...args) {
|
|
44
|
+
const timestamp = new Date().toISOString();
|
|
45
|
+
const formattedArgs = args.length > 0
|
|
46
|
+
? ` ${args
|
|
47
|
+
.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a))
|
|
48
|
+
.join(" ")}`
|
|
49
|
+
: "";
|
|
50
|
+
switch (this.options.format) {
|
|
51
|
+
case "json":
|
|
52
|
+
return JSON.stringify({
|
|
53
|
+
timestamp,
|
|
54
|
+
level: level.toUpperCase(),
|
|
55
|
+
message: message + formattedArgs,
|
|
56
|
+
args: args.length > 0 ? args : undefined,
|
|
57
|
+
});
|
|
58
|
+
case "detailed":
|
|
59
|
+
return `[${timestamp}] [${level.toUpperCase().padEnd(5)}] ${message}${formattedArgs}`;
|
|
60
|
+
default: // simple
|
|
61
|
+
return `${message}${formattedArgs}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
colorize(level, text) {
|
|
65
|
+
if (!this.options.colors) {
|
|
66
|
+
return text;
|
|
67
|
+
}
|
|
68
|
+
switch (level) {
|
|
69
|
+
case "debug":
|
|
70
|
+
return chalk_1.default.gray(text);
|
|
71
|
+
case "info":
|
|
72
|
+
return chalk_1.default.blue(text);
|
|
73
|
+
case "warn":
|
|
74
|
+
return chalk_1.default.yellow(text);
|
|
75
|
+
case "error":
|
|
76
|
+
return chalk_1.default.red(text);
|
|
77
|
+
default:
|
|
78
|
+
return text;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
debug(message, ...args) {
|
|
82
|
+
if (!this.shouldLog("debug") || !this.options.verbose) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const formatted = this.formatMessage("debug", `🔍 ${message}`, ...args);
|
|
86
|
+
console.log(this.colorize("debug", formatted));
|
|
87
|
+
}
|
|
88
|
+
info(message, ...args) {
|
|
89
|
+
if (!this.shouldLog("info")) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const formatted = this.formatMessage("info", `ℹ️ ${message}`, ...args);
|
|
93
|
+
console.log(this.colorize("info", formatted));
|
|
94
|
+
}
|
|
95
|
+
warn(message, ...args) {
|
|
96
|
+
if (!this.shouldLog("warn")) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const formatted = this.formatMessage("warn", `⚠️ ${message}`, ...args);
|
|
100
|
+
console.warn(this.colorize("warn", formatted));
|
|
101
|
+
}
|
|
102
|
+
error(message, ...args) {
|
|
103
|
+
if (!this.shouldLog("error")) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const formatted = this.formatMessage("error", `❌ ${message}`, ...args);
|
|
107
|
+
console.error(this.colorize("error", formatted));
|
|
108
|
+
}
|
|
109
|
+
badge() {
|
|
110
|
+
console.log(chalk_1.default.cyan(YAMA_BADGE));
|
|
111
|
+
}
|
|
112
|
+
phase(message) {
|
|
113
|
+
const formatted = `\n🔄 ${message}`;
|
|
114
|
+
console.log(this.options.colors ? chalk_1.default.magenta(formatted) : formatted);
|
|
115
|
+
}
|
|
116
|
+
success(message) {
|
|
117
|
+
const formatted = `✅ ${message}`;
|
|
118
|
+
console.log(this.options.colors ? chalk_1.default.green(formatted) : formatted);
|
|
119
|
+
}
|
|
120
|
+
operation(operation, status) {
|
|
121
|
+
const emoji = status === "started" ? "🚀" : status === "completed" ? "✅" : "❌";
|
|
122
|
+
const color = status === "started" ? "blue" : status === "completed" ? "green" : "red";
|
|
123
|
+
const message = `${emoji} ${operation.toUpperCase()}: ${status}`;
|
|
124
|
+
if (this.options.colors) {
|
|
125
|
+
console.log(chalk_1.default[color](message));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log(message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
violation(severity, message, file) {
|
|
132
|
+
const emoji = {
|
|
133
|
+
CRITICAL: "🚨",
|
|
134
|
+
MAJOR: "⚠️",
|
|
135
|
+
MINOR: "📝",
|
|
136
|
+
SUGGESTION: "💡",
|
|
137
|
+
}[severity] || "📋";
|
|
138
|
+
const color = {
|
|
139
|
+
CRITICAL: "red",
|
|
140
|
+
MAJOR: "yellow",
|
|
141
|
+
MINOR: "blue",
|
|
142
|
+
SUGGESTION: "cyan",
|
|
143
|
+
}[severity] || "white";
|
|
144
|
+
const location = file ? ` in ${file}` : "";
|
|
145
|
+
const formatted = `${emoji} ${severity}: ${message}${location}`;
|
|
146
|
+
if (this.options.colors) {
|
|
147
|
+
console.log(chalk_1.default[color](formatted));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
console.log(formatted);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
progress(current, total, operation) {
|
|
154
|
+
const percentage = Math.round((current / total) * 100);
|
|
155
|
+
const progressBar = this.createProgressBar(percentage);
|
|
156
|
+
const message = `🔄 ${operation}: ${progressBar} ${current}/${total} (${percentage}%)`;
|
|
157
|
+
// Use carriage return to overwrite the line
|
|
158
|
+
process.stdout.write(`\r${message}`);
|
|
159
|
+
// Add newline when complete
|
|
160
|
+
if (current === total) {
|
|
161
|
+
process.stdout.write("\n");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
createProgressBar(percentage) {
|
|
165
|
+
const width = 20;
|
|
166
|
+
const filled = Math.round((percentage / 100) * width);
|
|
167
|
+
const empty = width - filled;
|
|
168
|
+
if (this.options.colors) {
|
|
169
|
+
return chalk_1.default.green("█".repeat(filled)) + chalk_1.default.gray("░".repeat(empty));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return "█".repeat(filled) + "░".repeat(empty);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Method to create child logger with context
|
|
176
|
+
child(context) {
|
|
177
|
+
const childLogger = new Logger(this.options);
|
|
178
|
+
// Override methods to include context
|
|
179
|
+
const originalMethods = ["debug", "info", "warn", "error"];
|
|
180
|
+
originalMethods.forEach((method) => {
|
|
181
|
+
const original = childLogger[method].bind(childLogger);
|
|
182
|
+
childLogger[method] = (message, ...args) => {
|
|
183
|
+
const contextStr = Object.entries(context)
|
|
184
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
185
|
+
.join(" ");
|
|
186
|
+
original(`[${contextStr}] ${message}`, ...args);
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
return childLogger;
|
|
190
|
+
}
|
|
191
|
+
// Method to update log level dynamically
|
|
192
|
+
setLevel(level) {
|
|
193
|
+
this.options.level = level;
|
|
194
|
+
}
|
|
195
|
+
// Method to toggle verbose mode
|
|
196
|
+
setVerbose(verbose) {
|
|
197
|
+
this.options.verbose = verbose;
|
|
198
|
+
}
|
|
199
|
+
// Method to get current configuration
|
|
200
|
+
getConfig() {
|
|
201
|
+
return { ...this.options };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.Logger = Logger;
|
|
205
|
+
// Export singleton instance for convenience with environment-aware defaults
|
|
206
|
+
const loggerOptions = {};
|
|
207
|
+
// Check environment variables for debug mode
|
|
208
|
+
if (process.env.YAMA_DEBUG === "true") {
|
|
209
|
+
loggerOptions.level = "debug";
|
|
210
|
+
loggerOptions.verbose = true;
|
|
211
|
+
}
|
|
212
|
+
exports.logger = new Logger(loggerOptions);
|
|
213
|
+
// Export factory function
|
|
214
|
+
function createLogger(options) {
|
|
215
|
+
return new Logger(options);
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=Logger.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@juspay/yama",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Enterprise-grade Pull Request automation toolkit with AI-powered code review and description enhancement",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pr",
|
|
7
|
+
"pull-request",
|
|
8
|
+
"code-review",
|
|
9
|
+
"ai",
|
|
10
|
+
"automation",
|
|
11
|
+
"bitbucket",
|
|
12
|
+
"github",
|
|
13
|
+
"gitlab",
|
|
14
|
+
"security",
|
|
15
|
+
"quality"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/juspay/yama#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/juspay/yama/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+ssh://git@github.com/juspay/yama.git"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Juspay Technologies <support@juspay.in> (https://juspay.io)",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "dist/index.js",
|
|
29
|
+
"types": "dist/index.d.ts",
|
|
30
|
+
"bin": {
|
|
31
|
+
"yama": "dist/cli/index.js",
|
|
32
|
+
"pr-guardian": "dist/cli/index.js",
|
|
33
|
+
"pr-police": "dist/cli/index.js",
|
|
34
|
+
"pr-scribe": "dist/cli/index.js"
|
|
35
|
+
},
|
|
36
|
+
"directories": {
|
|
37
|
+
"test": "tests"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"!dist/**/*.test.*",
|
|
42
|
+
"!dist/**/*.spec.*",
|
|
43
|
+
"!dist/**/*.map",
|
|
44
|
+
"!dist/**/tests",
|
|
45
|
+
"!dist/**/test-*",
|
|
46
|
+
"README.md",
|
|
47
|
+
"CHANGELOG.md",
|
|
48
|
+
"LICENSE",
|
|
49
|
+
"yama.config.example.yaml"
|
|
50
|
+
],
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc && tsc-alias",
|
|
53
|
+
"dev": "ts-node-dev --respawn --transpile-only src/cli/index.ts",
|
|
54
|
+
"test": "jest",
|
|
55
|
+
"lint": "eslint .",
|
|
56
|
+
"lint:fix": "eslint . --fix",
|
|
57
|
+
"type-check": "tsc --noEmit",
|
|
58
|
+
"format": "prettier --write .",
|
|
59
|
+
"format:check": "prettier --check .",
|
|
60
|
+
"docs": "typedoc src",
|
|
61
|
+
"clean": "rimraf dist",
|
|
62
|
+
"prepare": "npm run build",
|
|
63
|
+
"prepack": "npm run build && npm run test",
|
|
64
|
+
"changeset": "changeset",
|
|
65
|
+
"changeset:version": "changeset version && git add --all",
|
|
66
|
+
"release": "npm run build && npm run test && changeset publish",
|
|
67
|
+
"release:dry": "npm publish --dry-run",
|
|
68
|
+
"release:github": "npm publish --registry https://npm.pkg.github.com",
|
|
69
|
+
"version:check": "npm version --no-git-tag-version",
|
|
70
|
+
"pack:verify": "npm pack && tar -tzf *.tgz | head -20"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@juspay/neurolink": "^5.1.0",
|
|
74
|
+
"@nexus2520/bitbucket-mcp-server": "^0.10.0",
|
|
75
|
+
"chalk": "^4.1.2",
|
|
76
|
+
"commander": "^11.0.0",
|
|
77
|
+
"debug": "^4.3.4",
|
|
78
|
+
"dotenv": "^16.3.0",
|
|
79
|
+
"fast-glob": "^3.3.1",
|
|
80
|
+
"inquirer": "^8.2.6",
|
|
81
|
+
"lodash": "^4.17.21",
|
|
82
|
+
"node-cache": "^5.1.2",
|
|
83
|
+
"ora": "^5.4.1",
|
|
84
|
+
"yaml": "^2.3.0"
|
|
85
|
+
},
|
|
86
|
+
"devDependencies": {
|
|
87
|
+
"@types/commander": "^2.12.5",
|
|
88
|
+
"@types/inquirer": "^9.0.8",
|
|
89
|
+
"@types/jest": "^29.0.0",
|
|
90
|
+
"@types/lodash": "^4.14.0",
|
|
91
|
+
"@types/node": "^20.0.0",
|
|
92
|
+
"@eslint/js": "^9.0.0",
|
|
93
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
94
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
95
|
+
"eslint": "^9.0.0",
|
|
96
|
+
"jest": "^29.0.0",
|
|
97
|
+
"rimraf": "^5.0.0",
|
|
98
|
+
"ts-jest": "^29.0.0",
|
|
99
|
+
"ts-node": "^10.0.0",
|
|
100
|
+
"ts-node-dev": "^2.0.0",
|
|
101
|
+
"tsc-alias": "^1.8.0",
|
|
102
|
+
"typedoc": "^0.25.0",
|
|
103
|
+
"typescript": "^5.0.0",
|
|
104
|
+
"@changesets/changelog-github": "^0.5.1",
|
|
105
|
+
"@changesets/cli": "^2.26.2",
|
|
106
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
107
|
+
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
108
|
+
"@semantic-release/git": "^10.0.1",
|
|
109
|
+
"@semantic-release/github": "^11.0.0",
|
|
110
|
+
"@semantic-release/npm": "^12.0.1",
|
|
111
|
+
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
112
|
+
"semantic-release": "^24.0.0",
|
|
113
|
+
"prettier": "^3.0.0",
|
|
114
|
+
"publint": "^0.3.0"
|
|
115
|
+
},
|
|
116
|
+
"peerDependencies": {
|
|
117
|
+
"typescript": ">=4.5.0"
|
|
118
|
+
},
|
|
119
|
+
"engines": {
|
|
120
|
+
"node": ">=18.0.0",
|
|
121
|
+
"npm": ">=8.0.0",
|
|
122
|
+
"pnpm": ">=8.0.0"
|
|
123
|
+
},
|
|
124
|
+
"os": [
|
|
125
|
+
"darwin",
|
|
126
|
+
"linux",
|
|
127
|
+
"win32"
|
|
128
|
+
],
|
|
129
|
+
"publishConfig": {
|
|
130
|
+
"access": "public",
|
|
131
|
+
"registry": "https://registry.npmjs.org/"
|
|
132
|
+
},
|
|
133
|
+
"pnpm": {
|
|
134
|
+
"onlyBuiltDependencies": [
|
|
135
|
+
"esbuild"
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Yama Configuration Example
|
|
2
|
+
# This file contains all available configuration options with explanations
|
|
3
|
+
|
|
4
|
+
# AI Provider Configuration
|
|
5
|
+
providers:
|
|
6
|
+
ai:
|
|
7
|
+
provider: "auto" # Options: auto, google-ai, openai, anthropic, azure, bedrock
|
|
8
|
+
model: "best" # Model name or "best" for auto-selection
|
|
9
|
+
temperature: 0.3 # Lower = more focused (0.0-1.0)
|
|
10
|
+
maxTokens: 2000000 # Maximum tokens for response
|
|
11
|
+
timeout: "15m" # Timeout for AI operations
|
|
12
|
+
enableAnalytics: true
|
|
13
|
+
enableEvaluation: false
|
|
14
|
+
|
|
15
|
+
# Git Platform Configuration
|
|
16
|
+
git:
|
|
17
|
+
platform: "bitbucket" # Options: bitbucket, github, gitlab, azure-devops
|
|
18
|
+
credentials:
|
|
19
|
+
username: "${BITBUCKET_USERNAME}" # Environment variable
|
|
20
|
+
token: "${BITBUCKET_TOKEN}" # Environment variable
|
|
21
|
+
baseUrl: "${BITBUCKET_BASE_URL}" # Your Bitbucket server URL
|
|
22
|
+
|
|
23
|
+
# Feature Configuration
|
|
24
|
+
features:
|
|
25
|
+
# Code Review Configuration
|
|
26
|
+
codeReview:
|
|
27
|
+
enabled: true
|
|
28
|
+
severityLevels: ["CRITICAL", "MAJOR", "MINOR", "SUGGESTION"]
|
|
29
|
+
categories:
|
|
30
|
+
[
|
|
31
|
+
"security",
|
|
32
|
+
"performance",
|
|
33
|
+
"maintainability",
|
|
34
|
+
"functionality",
|
|
35
|
+
"error_handling",
|
|
36
|
+
]
|
|
37
|
+
excludePatterns:
|
|
38
|
+
- "*.lock"
|
|
39
|
+
- "*.svg"
|
|
40
|
+
- "*.png"
|
|
41
|
+
- "*.jpg"
|
|
42
|
+
- "*.gif"
|
|
43
|
+
- "*.min.js"
|
|
44
|
+
- "*.min.css"
|
|
45
|
+
- "dist/**"
|
|
46
|
+
- "build/**"
|
|
47
|
+
- "vendor/**"
|
|
48
|
+
contextLines: 3 # Lines of context around changes
|
|
49
|
+
focusAreas:
|
|
50
|
+
- "Security vulnerabilities"
|
|
51
|
+
- "Performance bottlenecks"
|
|
52
|
+
- "Error handling"
|
|
53
|
+
- "Code quality"
|
|
54
|
+
|
|
55
|
+
# Description Enhancement Configuration
|
|
56
|
+
descriptionEnhancement:
|
|
57
|
+
enabled: true
|
|
58
|
+
preserveContent: true # Always preserve existing content
|
|
59
|
+
autoFormat: true
|
|
60
|
+
requiredSections:
|
|
61
|
+
- key: "changelog"
|
|
62
|
+
name: "Changelog (Modules Modified)"
|
|
63
|
+
required: true
|
|
64
|
+
- key: "testcases"
|
|
65
|
+
name: "Test Cases (What to be tested)"
|
|
66
|
+
required: true
|
|
67
|
+
- key: "config_changes"
|
|
68
|
+
name: "CAC Config Or Service Config Changes"
|
|
69
|
+
required: true
|
|
70
|
+
|
|
71
|
+
# NEW: Diff Strategy Configuration
|
|
72
|
+
diffStrategy:
|
|
73
|
+
enabled: true
|
|
74
|
+
thresholds:
|
|
75
|
+
wholeDiffMaxFiles: 2 # Use whole diff for ≤2 files
|
|
76
|
+
fileByFileMinFiles: 3 # Use file-by-file for ≥3 files
|
|
77
|
+
# Optional: Force a specific strategy regardless of file count
|
|
78
|
+
# forceStrategy: "file-by-file" # Options: whole, file-by-file, auto
|
|
79
|
+
|
|
80
|
+
# Security Scan Configuration (Future)
|
|
81
|
+
securityScan:
|
|
82
|
+
enabled: false
|
|
83
|
+
level: "strict" # Options: strict, moderate, basic
|
|
84
|
+
scanTypes: ["dependencies", "secrets", "vulnerabilities"]
|
|
85
|
+
|
|
86
|
+
# Analytics Configuration (Future)
|
|
87
|
+
analytics:
|
|
88
|
+
enabled: false
|
|
89
|
+
trackMetrics: true
|
|
90
|
+
exportFormat: "json" # Options: json, csv, yaml
|
|
91
|
+
|
|
92
|
+
# Cache Configuration
|
|
93
|
+
cache:
|
|
94
|
+
enabled: true
|
|
95
|
+
ttl: "30m" # Time to live for cache entries
|
|
96
|
+
maxSize: "100MB"
|
|
97
|
+
storage: "memory" # Options: memory, redis, file
|
|
98
|
+
|
|
99
|
+
# Performance Configuration
|
|
100
|
+
performance:
|
|
101
|
+
batch:
|
|
102
|
+
enabled: true
|
|
103
|
+
maxConcurrent: 5 # Max concurrent API calls
|
|
104
|
+
delayBetween: "1s" # Delay between batches
|
|
105
|
+
optimization:
|
|
106
|
+
reuseConnections: true
|
|
107
|
+
compressRequests: false
|
|
108
|
+
enableHttp2: true
|
|
109
|
+
|
|
110
|
+
# Custom Rules Configuration
|
|
111
|
+
rules:
|
|
112
|
+
security:
|
|
113
|
+
- name: "No hardcoded secrets"
|
|
114
|
+
pattern: "(password|secret|key)\\s*=\\s*[\"'][^\"']+[\"']"
|
|
115
|
+
severity: "CRITICAL"
|
|
116
|
+
message: "Hardcoded secrets detected"
|
|
117
|
+
suggestion: "Use environment variables or secure configuration"
|
|
118
|
+
|
|
119
|
+
- name: "SQL injection prevention"
|
|
120
|
+
pattern: "query\\([^?]+\\+.*\\)"
|
|
121
|
+
severity: "CRITICAL"
|
|
122
|
+
message: "Potential SQL injection vulnerability"
|
|
123
|
+
suggestion: "Use parameterized queries"
|
|
124
|
+
|
|
125
|
+
performance:
|
|
126
|
+
- name: "Avoid N+1 queries"
|
|
127
|
+
pattern: "forEach.*await.*query"
|
|
128
|
+
severity: "MAJOR"
|
|
129
|
+
message: "Potential N+1 query pattern detected"
|
|
130
|
+
suggestion: "Consider batch loading or joins"
|
|
131
|
+
|
|
132
|
+
# Reporting Configuration
|
|
133
|
+
reporting:
|
|
134
|
+
formats: ["markdown", "json"]
|
|
135
|
+
includeAnalytics: true
|
|
136
|
+
includeMetrics: true
|
|
137
|
+
|
|
138
|
+
# Monitoring Configuration (Future)
|
|
139
|
+
monitoring:
|
|
140
|
+
enabled: false
|
|
141
|
+
metrics: ["api_calls", "cache_hits", "processing_time"]
|
|
142
|
+
exportFormat: "prometheus"
|
|
143
|
+
interval: "1m"
|