@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.
@@ -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"