@juspay/yama 1.1.0 ā 1.1.1
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 +27 -1
- package/README.md +151 -119
- package/dist/cli/index.js +201 -200
- package/dist/core/ContextGatherer.d.ts +3 -3
- package/dist/core/ContextGatherer.js +145 -149
- package/dist/core/Guardian.d.ts +1 -1
- package/dist/core/Guardian.js +122 -122
- package/dist/core/providers/BitbucketProvider.d.ts +3 -3
- package/dist/core/providers/BitbucketProvider.js +129 -121
- package/dist/features/CodeReviewer.d.ts +3 -3
- package/dist/features/CodeReviewer.js +290 -221
- package/dist/features/DescriptionEnhancer.d.ts +3 -3
- package/dist/features/DescriptionEnhancer.js +115 -94
- package/dist/index.d.ts +11 -11
- package/dist/index.js +10 -48
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +13 -18
- package/dist/utils/Cache.d.ts +1 -1
- package/dist/utils/Cache.js +62 -68
- package/dist/utils/ConfigManager.d.ts +1 -1
- package/dist/utils/ConfigManager.js +281 -253
- package/dist/utils/Logger.d.ts +2 -2
- package/dist/utils/Logger.js +69 -67
- package/package.json +7 -6
- package/yama.config.example.yaml +28 -21
package/dist/cli/index.js
CHANGED
|
@@ -1,50 +1,45 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
/**
|
|
4
3
|
* Yama CLI - Enhanced command line interface
|
|
5
4
|
* Provides backward compatibility with pr-police.js and pr-describe.js
|
|
6
5
|
* Plus new unified commands for the enhanced functionality
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const Guardian_1 = require("../core/Guardian");
|
|
19
|
-
const Logger_1 = require("../utils/Logger");
|
|
20
|
-
const ConfigManager_1 = require("../utils/ConfigManager");
|
|
21
|
-
const Cache_1 = require("../utils/Cache");
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import ora from "ora";
|
|
10
|
+
import inquirer from "inquirer";
|
|
11
|
+
import dotenv from "dotenv";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
import { Guardian } from "../core/Guardian.js";
|
|
14
|
+
import { logger } from "../utils/Logger.js";
|
|
15
|
+
import { configManager } from "../utils/ConfigManager.js";
|
|
16
|
+
import { cache } from "../utils/Cache.js";
|
|
22
17
|
// Load environment variables
|
|
23
|
-
|
|
24
|
-
const program = new
|
|
18
|
+
dotenv.config();
|
|
19
|
+
const program = new Command();
|
|
25
20
|
// Package info
|
|
26
21
|
const packageInfo = {
|
|
27
|
-
name:
|
|
28
|
-
version:
|
|
29
|
-
description:
|
|
22
|
+
name: "@juspay/yama",
|
|
23
|
+
version: "1.2.1",
|
|
24
|
+
description: "Enterprise-grade Pull Request automation toolkit",
|
|
30
25
|
};
|
|
31
26
|
/**
|
|
32
27
|
* Main CLI setup
|
|
33
28
|
*/
|
|
34
29
|
function setupCLI() {
|
|
35
30
|
program
|
|
36
|
-
.name(
|
|
31
|
+
.name("yama")
|
|
37
32
|
.description(packageInfo.description)
|
|
38
33
|
.version(packageInfo.version);
|
|
39
34
|
// Global options
|
|
40
35
|
program
|
|
41
|
-
.option(
|
|
42
|
-
.option(
|
|
43
|
-
.option(
|
|
44
|
-
.option(
|
|
36
|
+
.option("-v, --verbose", "Enable verbose logging")
|
|
37
|
+
.option("-c, --config <path>", "Path to configuration file")
|
|
38
|
+
.option("--dry-run", "Preview mode - no changes made")
|
|
39
|
+
.option("--no-cache", "Disable caching");
|
|
45
40
|
// Configure help options (removed custom formatter to fix recursion)
|
|
46
41
|
program.configureHelp({
|
|
47
|
-
sortSubcommands: true
|
|
42
|
+
sortSubcommands: true,
|
|
48
43
|
});
|
|
49
44
|
// Setup commands
|
|
50
45
|
setupProcessCommand();
|
|
@@ -62,15 +57,15 @@ function setupCLI() {
|
|
|
62
57
|
*/
|
|
63
58
|
function setupProcessCommand() {
|
|
64
59
|
program
|
|
65
|
-
.command(
|
|
66
|
-
.description(
|
|
67
|
-
.requiredOption(
|
|
68
|
-
.requiredOption(
|
|
69
|
-
.option(
|
|
70
|
-
.option(
|
|
71
|
-
.option(
|
|
72
|
-
.option(
|
|
73
|
-
.option(
|
|
60
|
+
.command("process")
|
|
61
|
+
.description("Process PR with multiple operations using unified context (NEW)")
|
|
62
|
+
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
63
|
+
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
64
|
+
.option("-b, --branch <branch>", "Branch name")
|
|
65
|
+
.option("-p, --pr <id>", "Pull request ID")
|
|
66
|
+
.option("-o, --operations <operations>", "Operations to perform (review,enhance-description,all)", "all")
|
|
67
|
+
.option("--exclude <patterns>", "Comma-separated exclude patterns", "*.lock,*.svg")
|
|
68
|
+
.option("--context-lines <number>", "Context lines for diff", "3")
|
|
74
69
|
.action(async (options) => {
|
|
75
70
|
try {
|
|
76
71
|
await handleGlobalOptions(options);
|
|
@@ -82,33 +77,33 @@ function setupProcessCommand() {
|
|
|
82
77
|
pullRequestId: options.pr,
|
|
83
78
|
operations,
|
|
84
79
|
dryRun: options.dryRun,
|
|
85
|
-
verbose: options.verbose
|
|
80
|
+
verbose: options.verbose,
|
|
86
81
|
};
|
|
87
|
-
const guardian = new
|
|
82
|
+
const guardian = new Guardian();
|
|
88
83
|
await guardian.initialize(options.config);
|
|
89
84
|
if (options.verbose) {
|
|
90
85
|
// Use streaming for verbose mode
|
|
91
|
-
console.log(
|
|
86
|
+
console.log(chalk.blue("\nš” Starting streaming processing...\n"));
|
|
92
87
|
for await (const update of guardian.processPRStream(operationOptions)) {
|
|
93
88
|
logStreamUpdate(update);
|
|
94
89
|
}
|
|
95
90
|
}
|
|
96
91
|
else {
|
|
97
92
|
// Use regular processing
|
|
98
|
-
const spinner = (
|
|
93
|
+
const spinner = ora("Processing PR...").start();
|
|
99
94
|
try {
|
|
100
95
|
const result = await guardian.processPR(operationOptions);
|
|
101
|
-
spinner.succeed(
|
|
96
|
+
spinner.succeed("Processing completed");
|
|
102
97
|
printProcessResult(result);
|
|
103
98
|
}
|
|
104
99
|
catch (error) {
|
|
105
|
-
spinner.fail(
|
|
100
|
+
spinner.fail("Processing failed");
|
|
106
101
|
throw error;
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
}
|
|
110
105
|
catch (error) {
|
|
111
|
-
console.error(
|
|
106
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
112
107
|
process.exit(1);
|
|
113
108
|
}
|
|
114
109
|
});
|
|
@@ -118,15 +113,15 @@ function setupProcessCommand() {
|
|
|
118
113
|
*/
|
|
119
114
|
function setupReviewCommand() {
|
|
120
115
|
program
|
|
121
|
-
.command(
|
|
122
|
-
.alias(
|
|
123
|
-
.description(
|
|
124
|
-
.requiredOption(
|
|
125
|
-
.requiredOption(
|
|
126
|
-
.option(
|
|
127
|
-
.option(
|
|
128
|
-
.option(
|
|
129
|
-
.option(
|
|
116
|
+
.command("review")
|
|
117
|
+
.alias("police") // Backward compatibility
|
|
118
|
+
.description("AI-powered code review (equivalent to pr-police.js)")
|
|
119
|
+
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
120
|
+
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
121
|
+
.option("-b, --branch <branch>", "Branch name")
|
|
122
|
+
.option("-p, --pr <id>", "Pull request ID")
|
|
123
|
+
.option("--exclude <patterns>", "Comma-separated exclude patterns", "*.lock,*.svg")
|
|
124
|
+
.option("--context-lines <number>", "Context lines for diff", "3")
|
|
130
125
|
.action(async (options) => {
|
|
131
126
|
try {
|
|
132
127
|
await handleGlobalOptions(options);
|
|
@@ -137,24 +132,26 @@ function setupReviewCommand() {
|
|
|
137
132
|
pullRequestId: options.pr,
|
|
138
133
|
dryRun: options.dryRun,
|
|
139
134
|
verbose: options.verbose,
|
|
140
|
-
excludePatterns: options.exclude
|
|
141
|
-
|
|
135
|
+
excludePatterns: options.exclude
|
|
136
|
+
?.split(",")
|
|
137
|
+
.map((p) => p.trim()),
|
|
138
|
+
contextLines: parseInt(options.contextLines),
|
|
142
139
|
};
|
|
143
|
-
const guardian = new
|
|
140
|
+
const guardian = new Guardian();
|
|
144
141
|
await guardian.initialize(options.config);
|
|
145
|
-
const spinner = (
|
|
142
|
+
const spinner = ora("Conducting code review...").start();
|
|
146
143
|
try {
|
|
147
144
|
const result = await guardian.reviewCode(reviewOptions);
|
|
148
|
-
spinner.succeed(
|
|
145
|
+
spinner.succeed("Code review completed");
|
|
149
146
|
printReviewResult(result);
|
|
150
147
|
}
|
|
151
148
|
catch (error) {
|
|
152
|
-
spinner.fail(
|
|
149
|
+
spinner.fail("Code review failed");
|
|
153
150
|
throw error;
|
|
154
151
|
}
|
|
155
152
|
}
|
|
156
153
|
catch (error) {
|
|
157
|
-
console.error(
|
|
154
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
158
155
|
process.exit(1);
|
|
159
156
|
}
|
|
160
157
|
});
|
|
@@ -164,14 +161,14 @@ function setupReviewCommand() {
|
|
|
164
161
|
*/
|
|
165
162
|
function setupEnhanceCommand() {
|
|
166
163
|
program
|
|
167
|
-
.command(
|
|
168
|
-
.alias(
|
|
169
|
-
.description(
|
|
170
|
-
.requiredOption(
|
|
171
|
-
.requiredOption(
|
|
172
|
-
.option(
|
|
173
|
-
.option(
|
|
174
|
-
.option(
|
|
164
|
+
.command("enhance")
|
|
165
|
+
.alias("scribe") // Backward compatibility
|
|
166
|
+
.description("AI-powered description enhancement (equivalent to pr-describe.js)")
|
|
167
|
+
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
168
|
+
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
169
|
+
.option("-b, --branch <branch>", "Branch name")
|
|
170
|
+
.option("-p, --pr <id>", "Pull request ID")
|
|
171
|
+
.option("--no-preserve", "Disable content preservation")
|
|
175
172
|
.action(async (options) => {
|
|
176
173
|
try {
|
|
177
174
|
await handleGlobalOptions(options);
|
|
@@ -183,23 +180,23 @@ function setupEnhanceCommand() {
|
|
|
183
180
|
dryRun: options.dryRun,
|
|
184
181
|
verbose: options.verbose,
|
|
185
182
|
preserveContent: options.preserve !== false,
|
|
186
|
-
ensureRequiredSections: true
|
|
183
|
+
ensureRequiredSections: true,
|
|
187
184
|
};
|
|
188
|
-
const guardian = new
|
|
185
|
+
const guardian = new Guardian();
|
|
189
186
|
await guardian.initialize(options.config);
|
|
190
|
-
const spinner = (
|
|
187
|
+
const spinner = ora("Enhancing PR description...").start();
|
|
191
188
|
try {
|
|
192
189
|
const result = await guardian.enhanceDescription(enhancementOptions);
|
|
193
|
-
spinner.succeed(
|
|
190
|
+
spinner.succeed("Description enhancement completed");
|
|
194
191
|
printEnhancementResult(result);
|
|
195
192
|
}
|
|
196
193
|
catch (error) {
|
|
197
|
-
spinner.fail(
|
|
194
|
+
spinner.fail("Description enhancement failed");
|
|
198
195
|
throw error;
|
|
199
196
|
}
|
|
200
197
|
}
|
|
201
198
|
catch (error) {
|
|
202
|
-
console.error(
|
|
199
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
203
200
|
process.exit(1);
|
|
204
201
|
}
|
|
205
202
|
});
|
|
@@ -209,24 +206,24 @@ function setupEnhanceCommand() {
|
|
|
209
206
|
*/
|
|
210
207
|
function setupInitCommand() {
|
|
211
208
|
program
|
|
212
|
-
.command(
|
|
213
|
-
.description(
|
|
214
|
-
.option(
|
|
215
|
-
.option(
|
|
209
|
+
.command("init")
|
|
210
|
+
.description("Initialize Yama configuration")
|
|
211
|
+
.option("-o, --output <path>", "Output configuration file path")
|
|
212
|
+
.option("-i, --interactive", "Interactive configuration setup")
|
|
216
213
|
.action(async (options) => {
|
|
217
214
|
try {
|
|
218
215
|
if (options.interactive) {
|
|
219
216
|
await interactiveInit();
|
|
220
217
|
}
|
|
221
218
|
else {
|
|
222
|
-
const configPath = await
|
|
223
|
-
console.log(
|
|
224
|
-
console.log(
|
|
225
|
-
console.log(
|
|
219
|
+
const configPath = await configManager.createDefaultConfig(options.output);
|
|
220
|
+
console.log(chalk.green(`ā
Configuration file created: ${configPath}`));
|
|
221
|
+
console.log(chalk.yellow("š” Edit the configuration file to customize settings"));
|
|
222
|
+
console.log(chalk.blue("š Visit https://github.com/juspay/yama for documentation"));
|
|
226
223
|
}
|
|
227
224
|
}
|
|
228
225
|
catch (error) {
|
|
229
|
-
console.error(
|
|
226
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
230
227
|
process.exit(1);
|
|
231
228
|
}
|
|
232
229
|
});
|
|
@@ -236,37 +233,37 @@ function setupInitCommand() {
|
|
|
236
233
|
*/
|
|
237
234
|
function setupStatusCommand() {
|
|
238
235
|
program
|
|
239
|
-
.command(
|
|
240
|
-
.description(
|
|
241
|
-
.option(
|
|
236
|
+
.command("status")
|
|
237
|
+
.description("Check Yama status and health")
|
|
238
|
+
.option("-d, --detailed", "Show detailed status information")
|
|
242
239
|
.action(async (options) => {
|
|
243
240
|
try {
|
|
244
241
|
await handleGlobalOptions(options);
|
|
245
|
-
const guardian = new
|
|
242
|
+
const guardian = new Guardian();
|
|
246
243
|
await guardian.initialize(options.config);
|
|
247
244
|
const health = await guardian.healthCheck();
|
|
248
245
|
const stats = guardian.getStats();
|
|
249
|
-
console.log(
|
|
246
|
+
console.log(chalk.cyan("\nš”ļø Yama Status\n"));
|
|
250
247
|
// Health status
|
|
251
|
-
const healthEmoji = health.healthy ?
|
|
252
|
-
console.log(`${healthEmoji} Overall Health: ${health.healthy ?
|
|
248
|
+
const healthEmoji = health.healthy ? "ā
" : "ā";
|
|
249
|
+
console.log(`${healthEmoji} Overall Health: ${health.healthy ? "Healthy" : "Issues Detected"}`);
|
|
253
250
|
// Component status
|
|
254
|
-
console.log(
|
|
251
|
+
console.log("\nš Component Status:");
|
|
255
252
|
Object.entries(health.components).forEach(([component, status]) => {
|
|
256
|
-
const emoji = status.healthy ?
|
|
257
|
-
console.log(` ${emoji} ${component}: ${status.healthy ?
|
|
253
|
+
const emoji = status.healthy ? "ā
" : "ā";
|
|
254
|
+
console.log(` ${emoji} ${component}: ${status.healthy ? "OK" : "Error"}`);
|
|
258
255
|
});
|
|
259
256
|
// Statistics
|
|
260
257
|
if (options.detailed) {
|
|
261
|
-
console.log(
|
|
258
|
+
console.log("\nš Statistics:");
|
|
262
259
|
console.log(JSON.stringify(stats, null, 2));
|
|
263
260
|
}
|
|
264
261
|
// Cache status
|
|
265
|
-
const cacheStats =
|
|
266
|
-
console.log(`\nš¾ Cache: ${cacheStats.keys} keys, ${cacheStats.hits} hits, ${Math.round(
|
|
262
|
+
const cacheStats = cache.stats();
|
|
263
|
+
console.log(`\nš¾ Cache: ${cacheStats.keys} keys, ${cacheStats.hits} hits, ${Math.round(cache.getHitRatio() * 100)}% hit ratio`);
|
|
267
264
|
}
|
|
268
265
|
catch (error) {
|
|
269
|
-
console.error(
|
|
266
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
270
267
|
process.exit(1);
|
|
271
268
|
}
|
|
272
269
|
});
|
|
@@ -276,27 +273,27 @@ function setupStatusCommand() {
|
|
|
276
273
|
*/
|
|
277
274
|
function setupCacheCommand() {
|
|
278
275
|
const cacheCommand = program
|
|
279
|
-
.command(
|
|
280
|
-
.description(
|
|
276
|
+
.command("cache")
|
|
277
|
+
.description("Cache management operations");
|
|
281
278
|
cacheCommand
|
|
282
|
-
.command(
|
|
283
|
-
.description(
|
|
279
|
+
.command("clear")
|
|
280
|
+
.description("Clear all caches")
|
|
284
281
|
.action(() => {
|
|
285
|
-
|
|
286
|
-
console.log(
|
|
282
|
+
cache.clear();
|
|
283
|
+
console.log(chalk.green("ā
All caches cleared"));
|
|
287
284
|
});
|
|
288
285
|
cacheCommand
|
|
289
|
-
.command(
|
|
290
|
-
.description(
|
|
286
|
+
.command("stats")
|
|
287
|
+
.description("Show cache statistics")
|
|
291
288
|
.action(() => {
|
|
292
|
-
const stats =
|
|
293
|
-
const detailed =
|
|
294
|
-
console.log(
|
|
289
|
+
const stats = cache.stats();
|
|
290
|
+
const detailed = cache.debug();
|
|
291
|
+
console.log(chalk.cyan("\nš¾ Cache Statistics\n"));
|
|
295
292
|
console.log(`Keys: ${stats.keys}`);
|
|
296
293
|
console.log(`Hits: ${stats.hits}`);
|
|
297
294
|
console.log(`Misses: ${stats.misses}`);
|
|
298
|
-
console.log(`Hit Ratio: ${Math.round(
|
|
299
|
-
console.log(
|
|
295
|
+
console.log(`Hit Ratio: ${Math.round(cache.getHitRatio() * 100)}%`);
|
|
296
|
+
console.log("\nš Detailed Stats:");
|
|
300
297
|
console.log(JSON.stringify(detailed, null, 2));
|
|
301
298
|
});
|
|
302
299
|
}
|
|
@@ -305,39 +302,39 @@ function setupCacheCommand() {
|
|
|
305
302
|
*/
|
|
306
303
|
function setupConfigCommand() {
|
|
307
304
|
const configCommand = program
|
|
308
|
-
.command(
|
|
309
|
-
.description(
|
|
305
|
+
.command("config")
|
|
306
|
+
.description("Configuration management");
|
|
310
307
|
configCommand
|
|
311
|
-
.command(
|
|
312
|
-
.description(
|
|
313
|
-
.option(
|
|
308
|
+
.command("validate")
|
|
309
|
+
.description("Validate configuration file")
|
|
310
|
+
.option("-c, --config <path>", "Configuration file path")
|
|
314
311
|
.action(async (options) => {
|
|
315
312
|
try {
|
|
316
|
-
await
|
|
317
|
-
console.log(
|
|
313
|
+
await configManager.loadConfig(options.config);
|
|
314
|
+
console.log(chalk.green("ā
Configuration is valid"));
|
|
318
315
|
}
|
|
319
316
|
catch (error) {
|
|
320
|
-
console.error(
|
|
317
|
+
console.error(chalk.red(`ā Configuration error: ${error.message}`));
|
|
321
318
|
process.exit(1);
|
|
322
319
|
}
|
|
323
320
|
});
|
|
324
321
|
configCommand
|
|
325
|
-
.command(
|
|
326
|
-
.description(
|
|
327
|
-
.option(
|
|
322
|
+
.command("show")
|
|
323
|
+
.description("Show current configuration")
|
|
324
|
+
.option("-c, --config <path>", "Configuration file path")
|
|
328
325
|
.action(async (options) => {
|
|
329
326
|
try {
|
|
330
|
-
const config = await
|
|
331
|
-
console.log(
|
|
327
|
+
const config = await configManager.loadConfig(options.config);
|
|
328
|
+
console.log(chalk.cyan("\nāļø Current Configuration\n"));
|
|
332
329
|
// Mask sensitive information
|
|
333
330
|
const sanitizedConfig = { ...config };
|
|
334
331
|
if (sanitizedConfig.providers?.git?.credentials?.token) {
|
|
335
|
-
sanitizedConfig.providers.git.credentials.token =
|
|
332
|
+
sanitizedConfig.providers.git.credentials.token = "***MASKED***";
|
|
336
333
|
}
|
|
337
334
|
console.log(JSON.stringify(sanitizedConfig, null, 2));
|
|
338
335
|
}
|
|
339
336
|
catch (error) {
|
|
340
|
-
console.error(
|
|
337
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
341
338
|
process.exit(1);
|
|
342
339
|
}
|
|
343
340
|
});
|
|
@@ -347,16 +344,17 @@ function setupConfigCommand() {
|
|
|
347
344
|
*/
|
|
348
345
|
function setupBackwardCompatibility() {
|
|
349
346
|
// pr-police.js compatibility
|
|
350
|
-
if (process.argv[1]?.includes(
|
|
347
|
+
if (process.argv[1]?.includes("pr-police")) {
|
|
351
348
|
// Redirect to review command
|
|
352
349
|
const args = process.argv.slice(2);
|
|
353
|
-
process.argv = [
|
|
350
|
+
process.argv = ["node", "yama", "review", ...args];
|
|
354
351
|
}
|
|
355
352
|
// pr-describe.js / pr-scribe.js compatibility
|
|
356
|
-
if (process.argv[1]?.includes(
|
|
353
|
+
if (process.argv[1]?.includes("pr-scribe") ||
|
|
354
|
+
process.argv[1]?.includes("pr-describe")) {
|
|
357
355
|
// Redirect to enhance command
|
|
358
356
|
const args = process.argv.slice(2);
|
|
359
|
-
process.argv = [
|
|
357
|
+
process.argv = ["node", "yama", "enhance", ...args];
|
|
360
358
|
}
|
|
361
359
|
}
|
|
362
360
|
/**
|
|
@@ -365,70 +363,71 @@ function setupBackwardCompatibility() {
|
|
|
365
363
|
async function handleGlobalOptions(options) {
|
|
366
364
|
// Set up logging
|
|
367
365
|
if (options.verbose) {
|
|
368
|
-
|
|
369
|
-
|
|
366
|
+
logger.setVerbose(true);
|
|
367
|
+
logger.setLevel("debug");
|
|
370
368
|
}
|
|
371
369
|
// Handle cache disabling
|
|
372
370
|
if (options.cache === false) {
|
|
373
|
-
|
|
371
|
+
cache.clear();
|
|
374
372
|
}
|
|
375
373
|
}
|
|
376
374
|
function parseOperations(operationsStr) {
|
|
377
375
|
const operationMap = {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
376
|
+
review: "review",
|
|
377
|
+
enhance: "enhance-description",
|
|
378
|
+
"enhance-description": "enhance-description",
|
|
379
|
+
security: "security-scan",
|
|
380
|
+
"security-scan": "security-scan",
|
|
381
|
+
analytics: "analytics",
|
|
382
|
+
all: "all",
|
|
385
383
|
};
|
|
386
|
-
return operationsStr
|
|
387
|
-
.
|
|
388
|
-
.map(op =>
|
|
389
|
-
.
|
|
384
|
+
return operationsStr
|
|
385
|
+
.split(",")
|
|
386
|
+
.map((op) => op.trim())
|
|
387
|
+
.map((op) => operationMap[op] || op)
|
|
388
|
+
.filter((op) => op);
|
|
390
389
|
}
|
|
391
390
|
function logStreamUpdate(update) {
|
|
392
391
|
const timestamp = new Date(update.timestamp).toLocaleTimeString();
|
|
393
|
-
const progressStr = update.progress ? ` (${update.progress}%)` :
|
|
392
|
+
const progressStr = update.progress ? ` (${update.progress}%)` : "";
|
|
394
393
|
switch (update.status) {
|
|
395
|
-
case
|
|
396
|
-
console.log(
|
|
394
|
+
case "started":
|
|
395
|
+
console.log(chalk.blue(`š [${timestamp}] ${update.operation}: ${update.message}`));
|
|
397
396
|
break;
|
|
398
|
-
case
|
|
399
|
-
console.log(
|
|
397
|
+
case "progress":
|
|
398
|
+
console.log(chalk.yellow(`š [${timestamp}] ${update.operation}: ${update.message}${progressStr}`));
|
|
400
399
|
break;
|
|
401
|
-
case
|
|
402
|
-
console.log(
|
|
400
|
+
case "completed":
|
|
401
|
+
console.log(chalk.green(`ā
[${timestamp}] ${update.operation}: ${update.message}${progressStr}`));
|
|
403
402
|
break;
|
|
404
|
-
case
|
|
405
|
-
console.log(
|
|
403
|
+
case "error":
|
|
404
|
+
console.log(chalk.red(`ā [${timestamp}] ${update.operation}: ${update.message}`));
|
|
406
405
|
break;
|
|
407
406
|
}
|
|
408
407
|
}
|
|
409
408
|
function printProcessResult(result) {
|
|
410
|
-
console.log(
|
|
409
|
+
console.log(chalk.cyan("\nš”ļø Yama Process Result\n"));
|
|
411
410
|
console.log(`PR: #${result.pullRequest.id} - ${result.pullRequest.title}`);
|
|
412
411
|
console.log(`Author: ${result.pullRequest.author}`);
|
|
413
412
|
console.log(`Operations: ${result.operations.length}`);
|
|
414
|
-
console.log(
|
|
413
|
+
console.log("\nš Summary:");
|
|
415
414
|
console.log(`ā
Success: ${result.summary.successCount}`);
|
|
416
415
|
console.log(`ā Errors: ${result.summary.errorCount}`);
|
|
417
416
|
console.log(`āļø Skipped: ${result.summary.skippedCount}`);
|
|
418
417
|
console.log(`ā±ļø Total Duration: ${Math.round(result.summary.totalDuration / 1000)}s`);
|
|
419
418
|
// Show individual operation results
|
|
420
|
-
console.log(
|
|
419
|
+
console.log("\nš Operations:");
|
|
421
420
|
result.operations.forEach((op) => {
|
|
422
|
-
const emoji = op.status ===
|
|
421
|
+
const emoji = op.status === "success" ? "ā
" : op.status === "error" ? "ā" : "āļø";
|
|
423
422
|
console.log(` ${emoji} ${op.operation}: ${op.status} (${Math.round(op.duration / 1000)}s)`);
|
|
424
423
|
if (op.error) {
|
|
425
|
-
console.log(
|
|
424
|
+
console.log(chalk.red(` Error: ${op.error}`));
|
|
426
425
|
}
|
|
427
426
|
});
|
|
428
427
|
}
|
|
429
428
|
function printReviewResult(result) {
|
|
430
429
|
const stats = result.statistics;
|
|
431
|
-
console.log(
|
|
430
|
+
console.log(chalk.cyan("\nš”ļø Code Review Results\n"));
|
|
432
431
|
console.log(`š Total Issues: ${stats.totalIssues}`);
|
|
433
432
|
console.log(`šØ Critical: ${stats.criticalCount}`);
|
|
434
433
|
console.log(`ā ļø Major: ${stats.majorCount}`);
|
|
@@ -436,78 +435,78 @@ function printReviewResult(result) {
|
|
|
436
435
|
console.log(`š” Suggestions: ${stats.suggestionCount}`);
|
|
437
436
|
console.log(`š Files Reviewed: ${stats.filesReviewed}`);
|
|
438
437
|
if (stats.criticalCount > 0) {
|
|
439
|
-
console.log(
|
|
438
|
+
console.log(chalk.red("\nā CRITICAL issues found - must fix before merge!"));
|
|
440
439
|
}
|
|
441
440
|
else if (stats.majorCount > 0) {
|
|
442
|
-
console.log(
|
|
441
|
+
console.log(chalk.yellow("\nā ļø Major issues found - should fix before merge"));
|
|
443
442
|
}
|
|
444
443
|
else if (stats.minorCount > 0) {
|
|
445
|
-
console.log(
|
|
444
|
+
console.log(chalk.blue("\nš Minor improvements suggested"));
|
|
446
445
|
}
|
|
447
446
|
else {
|
|
448
|
-
console.log(
|
|
447
|
+
console.log(chalk.green("\nā
Code quality approved!"));
|
|
449
448
|
}
|
|
450
449
|
}
|
|
451
450
|
function printEnhancementResult(result) {
|
|
452
|
-
console.log(
|
|
451
|
+
console.log(chalk.cyan("\nš Description Enhancement Results\n"));
|
|
453
452
|
console.log(`š Original Length: ${result.statistics.originalLength} characters`);
|
|
454
453
|
console.log(`š Enhanced Length: ${result.statistics.enhancedLength} characters`);
|
|
455
454
|
console.log(`š Sections Completed: ${result.statistics.completedSections}/${result.statistics.totalSections}`);
|
|
456
455
|
if (result.sectionsAdded.length > 0) {
|
|
457
|
-
console.log(`ā Sections Added: ${result.sectionsAdded.join(
|
|
456
|
+
console.log(`ā Sections Added: ${result.sectionsAdded.join(", ")}`);
|
|
458
457
|
}
|
|
459
458
|
if (result.sectionsEnhanced.length > 0) {
|
|
460
|
-
console.log(`⨠Sections Enhanced: ${result.sectionsEnhanced.join(
|
|
459
|
+
console.log(`⨠Sections Enhanced: ${result.sectionsEnhanced.join(", ")}`);
|
|
461
460
|
}
|
|
462
461
|
console.log(`š Content Preserved: ${result.preservedItems.media} media, ${result.preservedItems.files} files, ${result.preservedItems.links} links`);
|
|
463
462
|
if (result.statistics.completedSections === result.statistics.totalSections) {
|
|
464
|
-
console.log(
|
|
463
|
+
console.log(chalk.green("\nā
All required sections completed!"));
|
|
465
464
|
}
|
|
466
465
|
else {
|
|
467
|
-
console.log(
|
|
466
|
+
console.log(chalk.yellow("\nā ļø Some required sections may still need attention"));
|
|
468
467
|
}
|
|
469
468
|
}
|
|
470
469
|
async function interactiveInit() {
|
|
471
|
-
console.log(
|
|
472
|
-
await
|
|
470
|
+
console.log(chalk.cyan("\nš”ļø Yama Interactive Setup\n"));
|
|
471
|
+
await inquirer.prompt([
|
|
473
472
|
{
|
|
474
|
-
type:
|
|
475
|
-
name:
|
|
476
|
-
message:
|
|
477
|
-
default:
|
|
473
|
+
type: "input",
|
|
474
|
+
name: "workspace",
|
|
475
|
+
message: "Default Bitbucket workspace:",
|
|
476
|
+
default: "YOUR_WORKSPACE",
|
|
478
477
|
},
|
|
479
478
|
{
|
|
480
|
-
type:
|
|
481
|
-
name:
|
|
482
|
-
message:
|
|
483
|
-
default:
|
|
479
|
+
type: "input",
|
|
480
|
+
name: "baseUrl",
|
|
481
|
+
message: "Bitbucket server URL:",
|
|
482
|
+
default: "https://your-bitbucket-server.com",
|
|
484
483
|
},
|
|
485
484
|
{
|
|
486
|
-
type:
|
|
487
|
-
name:
|
|
488
|
-
message:
|
|
489
|
-
choices: [
|
|
490
|
-
default:
|
|
485
|
+
type: "list",
|
|
486
|
+
name: "aiProvider",
|
|
487
|
+
message: "AI provider:",
|
|
488
|
+
choices: ["auto", "google-ai", "openai", "anthropic"],
|
|
489
|
+
default: "auto",
|
|
491
490
|
},
|
|
492
491
|
{
|
|
493
|
-
type:
|
|
494
|
-
name:
|
|
495
|
-
message:
|
|
496
|
-
default: true
|
|
492
|
+
type: "confirm",
|
|
493
|
+
name: "enableAnalytics",
|
|
494
|
+
message: "Enable AI analytics:",
|
|
495
|
+
default: true,
|
|
497
496
|
},
|
|
498
497
|
{
|
|
499
|
-
type:
|
|
500
|
-
name:
|
|
501
|
-
message:
|
|
502
|
-
default: true
|
|
503
|
-
}
|
|
498
|
+
type: "confirm",
|
|
499
|
+
name: "enableCache",
|
|
500
|
+
message: "Enable caching:",
|
|
501
|
+
default: true,
|
|
502
|
+
},
|
|
504
503
|
]);
|
|
505
|
-
const configPath = await
|
|
506
|
-
console.log(
|
|
507
|
-
console.log(
|
|
508
|
-
console.log(
|
|
509
|
-
console.log(
|
|
510
|
-
console.log(
|
|
504
|
+
const configPath = await configManager.createDefaultConfig();
|
|
505
|
+
console.log(chalk.green(`\nā
Configuration created: ${configPath}`));
|
|
506
|
+
console.log(chalk.yellow("š” Don't forget to set your environment variables:"));
|
|
507
|
+
console.log(chalk.blue(" BITBUCKET_USERNAME=your-username"));
|
|
508
|
+
console.log(chalk.blue(" BITBUCKET_TOKEN=your-token"));
|
|
509
|
+
console.log(chalk.blue(" GOOGLE_AI_API_KEY=your-api-key"));
|
|
511
510
|
}
|
|
512
511
|
/**
|
|
513
512
|
* Main execution
|
|
@@ -522,16 +521,18 @@ function main() {
|
|
|
522
521
|
}
|
|
523
522
|
}
|
|
524
523
|
// Handle uncaught errors
|
|
525
|
-
process.on(
|
|
526
|
-
console.error(
|
|
524
|
+
process.on("uncaughtException", (error) => {
|
|
525
|
+
console.error(chalk.red(`\nš„ Uncaught Exception: ${error.message}`));
|
|
527
526
|
process.exit(1);
|
|
528
527
|
});
|
|
529
|
-
process.on(
|
|
530
|
-
console.error(
|
|
528
|
+
process.on("unhandledRejection", (reason) => {
|
|
529
|
+
console.error(chalk.red(`\nš„ Unhandled Rejection: ${reason}`));
|
|
531
530
|
process.exit(1);
|
|
532
531
|
});
|
|
533
532
|
// Run if this is the main module
|
|
534
|
-
|
|
533
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
534
|
+
if (process.argv[1] === __filename) {
|
|
535
535
|
main();
|
|
536
536
|
}
|
|
537
|
+
export { main };
|
|
537
538
|
//# sourceMappingURL=index.js.map
|