@juspay/yama 2.2.1 → 2.3.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 +14 -0
- package/LICENSE +21 -0
- package/README.md +73 -110
- package/dist/cli/cli.d.ts +13 -0
- package/dist/cli/cli.js +341 -0
- package/dist/cli/v2.cli.d.ts +2 -11
- package/dist/cli/v2.cli.js +4 -354
- package/dist/index.d.ts +7 -5
- package/dist/index.js +5 -3
- package/dist/v2/config/ConfigLoader.d.ts +20 -5
- package/dist/v2/config/ConfigLoader.js +76 -24
- package/dist/v2/config/DefaultConfig.d.ts +3 -3
- package/dist/v2/config/DefaultConfig.js +9 -2
- package/dist/v2/core/LearningOrchestrator.d.ts +1 -0
- package/dist/v2/core/LearningOrchestrator.js +64 -4
- package/dist/v2/core/LocalDiffSource.d.ts +26 -0
- package/dist/v2/core/LocalDiffSource.js +129 -0
- package/dist/v2/core/MCPServerManager.d.ts +13 -1
- package/dist/v2/core/MCPServerManager.js +111 -7
- package/dist/v2/core/SessionManager.d.ts +1 -1
- package/dist/v2/core/SessionManager.js +3 -3
- package/dist/v2/core/YamaV2Orchestrator.d.ts +48 -13
- package/dist/v2/core/YamaV2Orchestrator.js +543 -63
- package/dist/v2/learning/types.d.ts +10 -0
- package/dist/v2/memory/MemoryManager.d.ts +57 -0
- package/dist/v2/memory/MemoryManager.js +185 -0
- package/dist/v2/prompts/PromptBuilder.d.ts +10 -4
- package/dist/v2/prompts/PromptBuilder.js +94 -3
- package/dist/v2/prompts/ReviewSystemPrompt.d.ts +1 -1
- package/dist/v2/prompts/ReviewSystemPrompt.js +7 -5
- package/dist/v2/types/config.types.d.ts +61 -1
- package/dist/v2/types/v2.types.d.ts +66 -5
- package/dist/v2/types/v2.types.js +8 -6
- package/package.json +20 -15
- package/yama.config.example.yaml +23 -5
package/dist/cli/v2.cli.js
CHANGED
|
@@ -1,359 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
import { Command } from "commander";
|
|
7
|
-
import dotenv from "dotenv";
|
|
8
|
-
import { createYamaV2 } from "../v2/core/YamaV2Orchestrator.js";
|
|
9
|
-
import { createLearningOrchestrator } from "../v2/core/LearningOrchestrator.js";
|
|
10
|
-
// Load environment variables
|
|
11
|
-
dotenv.config();
|
|
12
|
-
const program = new Command();
|
|
13
|
-
/**
|
|
14
|
-
* Setup V2 CLI
|
|
15
|
-
*/
|
|
16
|
-
export function setupV2CLI() {
|
|
17
|
-
program
|
|
18
|
-
.name("yama")
|
|
19
|
-
.description("Yama - AI-Native Autonomous Code Review")
|
|
20
|
-
.version("2.0.0");
|
|
21
|
-
// Global options
|
|
22
|
-
program
|
|
23
|
-
.option("-v, --verbose", "Enable verbose output")
|
|
24
|
-
.option("-c, --config <path>", "Path to configuration file")
|
|
25
|
-
.option("--dry-run", "Dry run mode - no actual changes")
|
|
26
|
-
.option("--no-banner", "Hide Yama banner");
|
|
27
|
-
// Review command
|
|
28
|
-
setupReviewCommand();
|
|
29
|
-
// Enhance description command
|
|
30
|
-
setupEnhanceCommand();
|
|
31
|
-
// Learn from PR feedback command
|
|
32
|
-
setupLearnCommand();
|
|
33
|
-
// Init command
|
|
34
|
-
setupInitCommand();
|
|
35
|
-
// Migrate config command
|
|
36
|
-
setupMigrateCommand();
|
|
37
|
-
return program;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Main review command
|
|
41
|
-
* Reviews code and enhances description in one session
|
|
42
|
-
*/
|
|
43
|
-
function setupReviewCommand() {
|
|
44
|
-
program
|
|
45
|
-
.command("review")
|
|
46
|
-
.description("Review code and enhance PR description (uses same AI session)")
|
|
47
|
-
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
48
|
-
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
49
|
-
.option("-p, --pr <id>", "Pull request ID")
|
|
50
|
-
.option("-b, --branch <branch>", "Branch name (finds PR automatically)")
|
|
51
|
-
.option("--review-only", "Skip description enhancement, only review code")
|
|
52
|
-
.action(async (options) => {
|
|
53
|
-
try {
|
|
54
|
-
const globalOpts = program.opts();
|
|
55
|
-
// Validate required options
|
|
56
|
-
if (!options.pr && !options.branch) {
|
|
57
|
-
console.error("❌ Error: Either --pr or --branch must be specified");
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
// Parse PR ID with validation
|
|
61
|
-
let pullRequestId;
|
|
62
|
-
if (options.pr) {
|
|
63
|
-
pullRequestId = parseInt(options.pr, 10);
|
|
64
|
-
if (isNaN(pullRequestId)) {
|
|
65
|
-
console.error(`❌ Error: Invalid PR ID "${options.pr}" (must be a number)`);
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const request = {
|
|
70
|
-
workspace: options.workspace,
|
|
71
|
-
repository: options.repository,
|
|
72
|
-
pullRequestId,
|
|
73
|
-
branch: options.branch,
|
|
74
|
-
dryRun: globalOpts.dryRun || false,
|
|
75
|
-
verbose: globalOpts.verbose || false,
|
|
76
|
-
configPath: globalOpts.config,
|
|
77
|
-
};
|
|
78
|
-
// Create orchestrator
|
|
79
|
-
const yama = createYamaV2();
|
|
80
|
-
// Initialize
|
|
81
|
-
await yama.initialize(request.configPath);
|
|
82
|
-
// Start review (with or without description enhancement)
|
|
83
|
-
console.log("🚀 Starting autonomous AI review...\n");
|
|
84
|
-
const result = options.reviewOnly
|
|
85
|
-
? await yama.startReview(request)
|
|
86
|
-
: await yama.startReviewAndEnhance(request);
|
|
87
|
-
// Show results
|
|
88
|
-
console.log("\n📊 Review Results:");
|
|
89
|
-
console.log(` Decision: ${result.decision}`);
|
|
90
|
-
console.log(` Files Reviewed: ${result.statistics.filesReviewed}`);
|
|
91
|
-
console.log(` Total Comments: ${result.totalComments || result.statistics.totalComments || 0}`);
|
|
92
|
-
if (result.descriptionEnhanced !== undefined) {
|
|
93
|
-
console.log(` Description Enhanced: ${result.descriptionEnhanced ? "✅ Yes" : "⏭️ Skipped"}`);
|
|
94
|
-
}
|
|
95
|
-
console.log(` Duration: ${Math.round(result.duration / 1000)}s`);
|
|
96
|
-
console.log(` Token Usage: ${result.tokenUsage.total.toLocaleString()} tokens`);
|
|
97
|
-
if (globalOpts.verbose) {
|
|
98
|
-
console.log("\n📄 Full Results:");
|
|
99
|
-
console.log(JSON.stringify(result, null, 2));
|
|
100
|
-
}
|
|
101
|
-
// Exit with appropriate code
|
|
102
|
-
if (result.decision === "BLOCKED") {
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
process.exit(0);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
console.error("\n❌ Review failed:", error.message);
|
|
111
|
-
if (error.stack && program.opts().verbose) {
|
|
112
|
-
console.error("\nStack trace:");
|
|
113
|
-
console.error(error.stack);
|
|
114
|
-
}
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Enhance description command
|
|
121
|
-
*/
|
|
122
|
-
function setupEnhanceCommand() {
|
|
123
|
-
program
|
|
124
|
-
.command("enhance")
|
|
125
|
-
.description("Enhance PR description using AI (without full review)")
|
|
126
|
-
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
127
|
-
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
128
|
-
.option("-p, --pr <id>", "Pull request ID")
|
|
129
|
-
.option("-b, --branch <branch>", "Branch name")
|
|
130
|
-
.action(async (options) => {
|
|
131
|
-
try {
|
|
132
|
-
const globalOpts = program.opts();
|
|
133
|
-
if (!options.pr && !options.branch) {
|
|
134
|
-
console.error("❌ Error: Either --pr or --branch must be specified");
|
|
135
|
-
process.exit(1);
|
|
136
|
-
}
|
|
137
|
-
// Parse PR ID with validation
|
|
138
|
-
let pullRequestId;
|
|
139
|
-
if (options.pr) {
|
|
140
|
-
pullRequestId = parseInt(options.pr, 10);
|
|
141
|
-
if (isNaN(pullRequestId)) {
|
|
142
|
-
console.error(`❌ Error: Invalid PR ID "${options.pr}" (must be a number)`);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const request = {
|
|
147
|
-
workspace: options.workspace,
|
|
148
|
-
repository: options.repository,
|
|
149
|
-
pullRequestId,
|
|
150
|
-
branch: options.branch,
|
|
151
|
-
dryRun: globalOpts.dryRun || false,
|
|
152
|
-
verbose: globalOpts.verbose || false,
|
|
153
|
-
configPath: globalOpts.config,
|
|
154
|
-
};
|
|
155
|
-
const yama = createYamaV2();
|
|
156
|
-
await yama.initialize(request.configPath);
|
|
157
|
-
const result = await yama.enhanceDescription(request);
|
|
158
|
-
console.log("\n✅ Description enhanced successfully");
|
|
159
|
-
console.log(JSON.stringify(result, null, 2));
|
|
160
|
-
process.exit(0);
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
console.error("\n❌ Enhancement failed:", error.message);
|
|
164
|
-
process.exit(1);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Learn from PR feedback command
|
|
170
|
-
* Extracts learnings from merged PRs to improve future reviews
|
|
171
|
-
*/
|
|
172
|
-
function setupLearnCommand() {
|
|
173
|
-
program
|
|
174
|
-
.command("learn")
|
|
175
|
-
.description("Extract learnings from merged PR to improve future reviews")
|
|
176
|
-
.requiredOption("-w, --workspace <workspace>", "Bitbucket workspace")
|
|
177
|
-
.requiredOption("-r, --repository <repository>", "Repository name")
|
|
178
|
-
.requiredOption("-p, --pr <id>", "Merged pull request ID")
|
|
179
|
-
.option("--commit", "Auto-commit knowledge base changes to git")
|
|
180
|
-
.option("--summarize", "Force summarization of knowledge base")
|
|
181
|
-
.option("--output <path>", "Override knowledge base output path")
|
|
182
|
-
.option("--format <format>", "Output format for dry-run preview (md|json)", "md")
|
|
183
|
-
.action(async (options) => {
|
|
184
|
-
try {
|
|
185
|
-
const globalOpts = program.opts();
|
|
186
|
-
// Parse and validate PR ID
|
|
187
|
-
const pullRequestId = parseInt(options.pr, 10);
|
|
188
|
-
if (isNaN(pullRequestId)) {
|
|
189
|
-
console.error(`❌ Error: Invalid PR ID "${options.pr}" (must be a number)`);
|
|
190
|
-
process.exit(1);
|
|
191
|
-
}
|
|
192
|
-
// Validate format option
|
|
193
|
-
if (options.format && !["md", "json"].includes(options.format)) {
|
|
194
|
-
console.error(`❌ Error: Invalid format "${options.format}" (must be md or json)`);
|
|
195
|
-
process.exit(1);
|
|
196
|
-
}
|
|
197
|
-
const request = {
|
|
198
|
-
workspace: options.workspace,
|
|
199
|
-
repository: options.repository,
|
|
200
|
-
pullRequestId,
|
|
201
|
-
dryRun: globalOpts.dryRun || false,
|
|
202
|
-
commit: options.commit || false,
|
|
203
|
-
summarize: options.summarize || false,
|
|
204
|
-
outputPath: options.output,
|
|
205
|
-
outputFormat: options.format || "md",
|
|
206
|
-
};
|
|
207
|
-
// Create and initialize learning orchestrator
|
|
208
|
-
const orchestrator = createLearningOrchestrator();
|
|
209
|
-
await orchestrator.initialize(globalOpts.config);
|
|
210
|
-
// Extract learnings
|
|
211
|
-
const result = await orchestrator.extractLearnings(request);
|
|
212
|
-
// Handle result
|
|
213
|
-
if (!result.success) {
|
|
214
|
-
console.error(`\n❌ Learning extraction failed: ${result.error}`);
|
|
215
|
-
process.exit(1);
|
|
216
|
-
}
|
|
217
|
-
// Show final summary for live runs
|
|
218
|
-
if (!globalOpts.dryRun && result.learningsAdded > 0) {
|
|
219
|
-
console.log("\n🎉 Knowledge base updated successfully!");
|
|
220
|
-
console.log(` Use 'yama review' to apply these learnings to future reviews.`);
|
|
221
|
-
}
|
|
222
|
-
process.exit(0);
|
|
223
|
-
}
|
|
224
|
-
catch (error) {
|
|
225
|
-
console.error("\n❌ Learning extraction failed:", error.message);
|
|
226
|
-
if (error.stack && program.opts().verbose) {
|
|
227
|
-
console.error("\nStack trace:");
|
|
228
|
-
console.error(error.stack);
|
|
229
|
-
}
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Initialize configuration command
|
|
236
|
-
*/
|
|
237
|
-
function setupInitCommand() {
|
|
238
|
-
program
|
|
239
|
-
.command("init")
|
|
240
|
-
.description("Initialize Yama configuration")
|
|
241
|
-
.option("--interactive", "Interactive configuration setup")
|
|
242
|
-
.action(async (options) => {
|
|
243
|
-
try {
|
|
244
|
-
console.log("\n⚔️ Yama Configuration Setup\n");
|
|
245
|
-
if (options.interactive) {
|
|
246
|
-
console.log("Interactive setup not yet implemented.");
|
|
247
|
-
console.log("Please copy yama.config.example.yaml to yama.config.yaml");
|
|
248
|
-
console.log("and edit it manually.\n");
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
251
|
-
console.log("Creating default configuration file...\n");
|
|
252
|
-
const fs = await import("fs/promises");
|
|
253
|
-
const path = await import("path");
|
|
254
|
-
// Check if config already exists
|
|
255
|
-
if (await fs
|
|
256
|
-
.access("yama.config.yaml")
|
|
257
|
-
.then(() => true)
|
|
258
|
-
.catch(() => false)) {
|
|
259
|
-
console.log("❌ yama.config.yaml already exists");
|
|
260
|
-
console.log(" Remove it first or use a different location\n");
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
// Copy example config
|
|
264
|
-
const examplePath = path.join(process.cwd(), "yama.config.example.yaml");
|
|
265
|
-
const targetPath = path.join(process.cwd(), "yama.config.yaml");
|
|
266
|
-
if (await fs
|
|
267
|
-
.access(examplePath)
|
|
268
|
-
.then(() => true)
|
|
269
|
-
.catch(() => false)) {
|
|
270
|
-
await fs.copyFile(examplePath, targetPath);
|
|
271
|
-
console.log("✅ Created yama.config.yaml from example");
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
console.log("⚠️ Example config not found, creating minimal config...");
|
|
275
|
-
await fs.writeFile(targetPath, `version: 2
|
|
276
|
-
configType: "yama-v2"
|
|
277
|
-
|
|
278
|
-
ai:
|
|
279
|
-
provider: "auto"
|
|
280
|
-
model: "gemini-2.5-pro"
|
|
281
|
-
|
|
282
|
-
mcpServers:
|
|
283
|
-
jira:
|
|
284
|
-
enabled: false
|
|
285
|
-
|
|
286
|
-
review:
|
|
287
|
-
enabled: true
|
|
288
|
-
|
|
289
|
-
descriptionEnhancement:
|
|
290
|
-
enabled: true
|
|
291
|
-
`);
|
|
292
|
-
console.log("✅ Created minimal yama.config.yaml");
|
|
293
|
-
}
|
|
294
|
-
console.log("\n📝 Next steps:");
|
|
295
|
-
console.log(" 1. Edit yama.config.yaml with your settings");
|
|
296
|
-
console.log(" 2. Set environment variables (BITBUCKET_*, JIRA_*)");
|
|
297
|
-
console.log(" 3. Run: yama review --help\n");
|
|
298
|
-
}
|
|
299
|
-
process.exit(0);
|
|
300
|
-
}
|
|
301
|
-
catch (error) {
|
|
302
|
-
console.error("\n❌ Initialization failed:", error.message);
|
|
303
|
-
process.exit(1);
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Migrate V1 config to V2 format
|
|
309
|
-
*/
|
|
310
|
-
function setupMigrateCommand() {
|
|
311
|
-
program
|
|
312
|
-
.command("migrate-config")
|
|
313
|
-
.description("Migrate V1 configuration to V2 format")
|
|
314
|
-
.option("-i, --input <file>", "Input V1 config file", "yama.v1.config.yaml")
|
|
315
|
-
.option("-o, --output <file>", "Output V2 config file", "yama.config.yaml")
|
|
316
|
-
.option("--force", "Overwrite existing output file")
|
|
317
|
-
.action(async (options) => {
|
|
318
|
-
try {
|
|
319
|
-
const globalOpts = program.opts();
|
|
320
|
-
console.log("\n🔄 Yama V1 → V2 Configuration Migration\n");
|
|
321
|
-
// Use child_process to run the migration script
|
|
322
|
-
const { spawn } = await import("child_process");
|
|
323
|
-
const path = await import("path");
|
|
324
|
-
const { fileURLToPath } = await import("url");
|
|
325
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
326
|
-
const __dirname = path.dirname(__filename);
|
|
327
|
-
const scriptPath = path.resolve(__dirname, "../../scripts/migrate-config.cjs");
|
|
328
|
-
const args = ["--input", options.input, "--output", options.output];
|
|
329
|
-
if (options.force) {
|
|
330
|
-
args.push("--force");
|
|
331
|
-
}
|
|
332
|
-
if (globalOpts.dryRun) {
|
|
333
|
-
args.push("--dry-run");
|
|
334
|
-
}
|
|
335
|
-
const child = spawn("node", [scriptPath, ...args], {
|
|
336
|
-
stdio: "inherit",
|
|
337
|
-
cwd: process.cwd(),
|
|
338
|
-
});
|
|
339
|
-
child.on("close", (code) => {
|
|
340
|
-
process.exit(code || 0);
|
|
341
|
-
});
|
|
342
|
-
child.on("error", (err) => {
|
|
343
|
-
console.error("❌ Failed to run migration script:", err.message);
|
|
344
|
-
process.exit(1);
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
catch (error) {
|
|
348
|
-
console.error("\n❌ Migration failed:", error.message);
|
|
349
|
-
process.exit(1);
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
// Only run if this is the main module
|
|
2
|
+
// Backward-compatible entrypoint.
|
|
3
|
+
import program, { setupCLI } from "./cli.js";
|
|
4
|
+
export { setupCLI, program as default };
|
|
354
5
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
355
|
-
const cli =
|
|
6
|
+
const cli = setupCLI();
|
|
356
7
|
cli.parse(process.argv);
|
|
357
8
|
}
|
|
358
|
-
export default program;
|
|
359
9
|
//# sourceMappingURL=v2.cli.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
* Yama - AI-Native Code Review
|
|
3
3
|
* Main export file
|
|
4
4
|
*/
|
|
5
|
-
export { YamaV2Orchestrator, createYamaV2, } from "./v2/core/YamaV2Orchestrator.js";
|
|
5
|
+
export { YamaOrchestrator, createYama, YamaOrchestrator as YamaV2Orchestrator, createYama as createYamaV2, } from "./v2/core/YamaV2Orchestrator.js";
|
|
6
|
+
export { LearningOrchestrator, createLearningOrchestrator, } from "./v2/core/LearningOrchestrator.js";
|
|
6
7
|
export { ConfigLoader } from "./v2/config/ConfigLoader.js";
|
|
7
8
|
export { MCPServerManager } from "./v2/core/MCPServerManager.js";
|
|
8
9
|
export { SessionManager } from "./v2/core/SessionManager.js";
|
|
9
10
|
export { PromptBuilder } from "./v2/prompts/PromptBuilder.js";
|
|
10
|
-
export
|
|
11
|
-
export type {
|
|
11
|
+
export { MemoryManager } from "./v2/memory/MemoryManager.js";
|
|
12
|
+
export type { LocalReviewFinding, LocalReviewRequest, LocalReviewResult, ReviewRequest, ReviewMode, ReviewResult, ReviewUpdate, ReviewSession, ReviewStatistics, IssuesBySeverity, TokenUsage, UnifiedReviewRequest, } from "./v2/types/v2.types.js";
|
|
13
|
+
export type { YamaConfig, YamaInitOptions, YamaConfig as YamaV2Config, AIConfig, MCPServersConfig, ReviewConfig, DescriptionEnhancementConfig, MemoryConfig, } from "./v2/types/config.types.js";
|
|
12
14
|
export type { GetPullRequestResponse, GetPullRequestDiffResponse, GetIssueResponse, SearchCodeResponse, } from "./v2/types/mcp.types.js";
|
|
13
|
-
export declare const VERSION = "2.
|
|
14
|
-
export {
|
|
15
|
+
export declare const VERSION = "2.2.1";
|
|
16
|
+
export { createYama as default } from "./v2/core/YamaV2Orchestrator.js";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
// ============================================================================
|
|
6
6
|
// Core Exports
|
|
7
7
|
// ============================================================================
|
|
8
|
-
export { YamaV2Orchestrator, createYamaV2, } from "./v2/core/YamaV2Orchestrator.js";
|
|
8
|
+
export { YamaOrchestrator, createYama, YamaOrchestrator as YamaV2Orchestrator, createYama as createYamaV2, } from "./v2/core/YamaV2Orchestrator.js";
|
|
9
|
+
export { LearningOrchestrator, createLearningOrchestrator, } from "./v2/core/LearningOrchestrator.js";
|
|
9
10
|
export { ConfigLoader } from "./v2/config/ConfigLoader.js";
|
|
10
11
|
export { MCPServerManager } from "./v2/core/MCPServerManager.js";
|
|
11
12
|
export { SessionManager } from "./v2/core/SessionManager.js";
|
|
12
13
|
export { PromptBuilder } from "./v2/prompts/PromptBuilder.js";
|
|
14
|
+
export { MemoryManager } from "./v2/memory/MemoryManager.js";
|
|
13
15
|
// ============================================================================
|
|
14
16
|
// Version Information
|
|
15
17
|
// ============================================================================
|
|
16
|
-
export const VERSION = "2.
|
|
18
|
+
export const VERSION = "2.2.1";
|
|
17
19
|
// ============================================================================
|
|
18
20
|
// Default Export
|
|
19
21
|
// ============================================================================
|
|
20
|
-
export {
|
|
22
|
+
export { createYama as default } from "./v2/core/YamaV2Orchestrator.js";
|
|
21
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Multi-Layer Configuration Loader for Yama
|
|
2
|
+
* Multi-Layer Configuration Loader for Yama
|
|
3
3
|
* Loads and merges configuration from multiple sources
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { YamaConfig } from "../types/config.types.js";
|
|
6
6
|
export declare class ConfigLoader {
|
|
7
7
|
private config;
|
|
8
8
|
private configPath;
|
|
9
9
|
/**
|
|
10
10
|
* Load configuration from file with multi-layer support
|
|
11
11
|
*/
|
|
12
|
-
loadConfig(configPath?: string): Promise<
|
|
12
|
+
loadConfig(configPath?: string, instanceOverrides?: Partial<YamaConfig>): Promise<YamaConfig>;
|
|
13
13
|
/**
|
|
14
14
|
* Get current loaded configuration
|
|
15
15
|
*/
|
|
16
|
-
getConfig():
|
|
16
|
+
getConfig(): YamaConfig;
|
|
17
17
|
/**
|
|
18
18
|
* Validate configuration completeness and correctness
|
|
19
19
|
*/
|
|
20
|
-
validate(): Promise<void>;
|
|
20
|
+
validate(mode?: "pr" | "local"): Promise<void>;
|
|
21
21
|
/**
|
|
22
22
|
* Resolve configuration file path
|
|
23
23
|
*/
|
|
@@ -42,6 +42,21 @@ export declare class ConfigLoader {
|
|
|
42
42
|
* Apply environment variable overrides
|
|
43
43
|
*/
|
|
44
44
|
private applyEnvironmentOverrides;
|
|
45
|
+
/**
|
|
46
|
+
* Apply memory-related environment variable overrides.
|
|
47
|
+
*
|
|
48
|
+
* Env vars (YAMA_MEMORY_*) take precedence over yaml config.
|
|
49
|
+
* If YAMA_MEMORY_ENABLED is set but no memory config exists in yaml,
|
|
50
|
+
* a default config is created so the other overrides have a target.
|
|
51
|
+
*
|
|
52
|
+
* Supported env vars:
|
|
53
|
+
* YAMA_MEMORY_ENABLED — "true" / "false"
|
|
54
|
+
* YAMA_MEMORY_STORAGE_PATH — e.g. "memory-bank/yama/memory"
|
|
55
|
+
* YAMA_MEMORY_MAX_WORDS — e.g. "200"
|
|
56
|
+
* YAMA_MEMORY_AUTO_COMMIT — "true" / "false"
|
|
57
|
+
* YAMA_MEMORY_PROMPT — custom condensation prompt
|
|
58
|
+
*/
|
|
59
|
+
private applyMemoryOverrides;
|
|
45
60
|
/**
|
|
46
61
|
* Basic configuration validation
|
|
47
62
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Multi-Layer Configuration Loader for Yama
|
|
2
|
+
* Multi-Layer Configuration Loader for Yama
|
|
3
3
|
* Loads and merges configuration from multiple sources
|
|
4
4
|
*/
|
|
5
5
|
import { readFile } from "fs/promises";
|
|
@@ -14,11 +14,14 @@ export class ConfigLoader {
|
|
|
14
14
|
/**
|
|
15
15
|
* Load configuration from file with multi-layer support
|
|
16
16
|
*/
|
|
17
|
-
async loadConfig(configPath) {
|
|
18
|
-
console.log("📋 Loading Yama
|
|
17
|
+
async loadConfig(configPath, instanceOverrides) {
|
|
18
|
+
console.log("📋 Loading Yama configuration...");
|
|
19
19
|
// Layer 1: Start with default config
|
|
20
20
|
let config = DefaultConfig.get();
|
|
21
|
-
// Layer 2:
|
|
21
|
+
// Layer 2: Apply environment variable overrides
|
|
22
|
+
// Lowest user-provided layer in SDK mode precedence.
|
|
23
|
+
config = this.applyEnvironmentOverrides(config);
|
|
24
|
+
// Layer 3: Load from file if provided or search for default locations
|
|
22
25
|
const filePath = await this.resolveConfigPath(configPath);
|
|
23
26
|
if (filePath) {
|
|
24
27
|
console.log(` Reading config from: ${filePath}`);
|
|
@@ -29,8 +32,11 @@ export class ConfigLoader {
|
|
|
29
32
|
else {
|
|
30
33
|
console.log(" Using default configuration (no config file found)");
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
config.memory = this.applyMemoryOverrides(config.memory);
|
|
36
|
+
// Layer 4: Apply SDK instance overrides (highest priority)
|
|
37
|
+
if (instanceOverrides) {
|
|
38
|
+
config = this.mergeConfigs(config, instanceOverrides);
|
|
39
|
+
}
|
|
34
40
|
// Validate configuration
|
|
35
41
|
this.validateConfig(config);
|
|
36
42
|
this.config = config;
|
|
@@ -49,7 +55,7 @@ export class ConfigLoader {
|
|
|
49
55
|
/**
|
|
50
56
|
* Validate configuration completeness and correctness
|
|
51
57
|
*/
|
|
52
|
-
async validate() {
|
|
58
|
+
async validate(mode = "pr") {
|
|
53
59
|
if (!this.config) {
|
|
54
60
|
throw new ConfigurationError("No configuration to validate");
|
|
55
61
|
}
|
|
@@ -61,25 +67,28 @@ export class ConfigLoader {
|
|
|
61
67
|
if (!this.config.ai.model) {
|
|
62
68
|
errors.push("AI model not configured");
|
|
63
69
|
}
|
|
64
|
-
//
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
errors.push("BITBUCKET_TOKEN environment variable not set");
|
|
70
|
-
}
|
|
71
|
-
if (!process.env.BITBUCKET_BASE_URL) {
|
|
72
|
-
errors.push("BITBUCKET_BASE_URL environment variable not set");
|
|
73
|
-
}
|
|
74
|
-
if (this.config.mcpServers.jira.enabled) {
|
|
75
|
-
if (!process.env.JIRA_EMAIL) {
|
|
76
|
-
errors.push("JIRA_EMAIL environment variable not set");
|
|
70
|
+
// Local mode is SDK-first and does not require MCP credentials.
|
|
71
|
+
if (mode === "pr") {
|
|
72
|
+
// Check environment variables for Bitbucket (required in PR mode)
|
|
73
|
+
if (!process.env.BITBUCKET_USERNAME) {
|
|
74
|
+
errors.push("BITBUCKET_USERNAME environment variable not set");
|
|
77
75
|
}
|
|
78
|
-
if (!process.env.
|
|
79
|
-
errors.push("
|
|
76
|
+
if (!process.env.BITBUCKET_TOKEN) {
|
|
77
|
+
errors.push("BITBUCKET_TOKEN environment variable not set");
|
|
80
78
|
}
|
|
81
|
-
if (!process.env.
|
|
82
|
-
errors.push("
|
|
79
|
+
if (!process.env.BITBUCKET_BASE_URL) {
|
|
80
|
+
errors.push("BITBUCKET_BASE_URL environment variable not set");
|
|
81
|
+
}
|
|
82
|
+
if (this.config.mcpServers.jira.enabled) {
|
|
83
|
+
if (!process.env.JIRA_EMAIL) {
|
|
84
|
+
errors.push("JIRA_EMAIL environment variable not set");
|
|
85
|
+
}
|
|
86
|
+
if (!process.env.JIRA_API_TOKEN) {
|
|
87
|
+
errors.push("JIRA_API_TOKEN environment variable not set");
|
|
88
|
+
}
|
|
89
|
+
if (!process.env.JIRA_BASE_URL) {
|
|
90
|
+
errors.push("JIRA_BASE_URL environment variable not set");
|
|
91
|
+
}
|
|
83
92
|
}
|
|
84
93
|
}
|
|
85
94
|
if (errors.length > 0) {
|
|
@@ -179,8 +188,51 @@ export class ConfigLoader {
|
|
|
179
188
|
if (process.env.AI_MAX_TOKENS) {
|
|
180
189
|
config.ai.maxTokens = parseInt(process.env.AI_MAX_TOKENS, 10);
|
|
181
190
|
}
|
|
191
|
+
if (process.env.AI_ENABLE_TOOL_FILTERING) {
|
|
192
|
+
config.ai.enableToolFiltering =
|
|
193
|
+
process.env.AI_ENABLE_TOOL_FILTERING === "true";
|
|
194
|
+
}
|
|
195
|
+
if (process.env.AI_TOOL_FILTERING_MODE) {
|
|
196
|
+
const mode = process.env.AI_TOOL_FILTERING_MODE;
|
|
197
|
+
if (mode === "off" || mode === "log-only" || mode === "active") {
|
|
198
|
+
config.ai.toolFilteringMode = mode;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
182
201
|
return config;
|
|
183
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Apply memory-related environment variable overrides.
|
|
205
|
+
*
|
|
206
|
+
* Env vars (YAMA_MEMORY_*) take precedence over yaml config.
|
|
207
|
+
* If YAMA_MEMORY_ENABLED is set but no memory config exists in yaml,
|
|
208
|
+
* a default config is created so the other overrides have a target.
|
|
209
|
+
*
|
|
210
|
+
* Supported env vars:
|
|
211
|
+
* YAMA_MEMORY_ENABLED — "true" / "false"
|
|
212
|
+
* YAMA_MEMORY_STORAGE_PATH — e.g. "memory-bank/yama/memory"
|
|
213
|
+
* YAMA_MEMORY_MAX_WORDS — e.g. "200"
|
|
214
|
+
* YAMA_MEMORY_AUTO_COMMIT — "true" / "false"
|
|
215
|
+
* YAMA_MEMORY_PROMPT — custom condensation prompt
|
|
216
|
+
*/
|
|
217
|
+
applyMemoryOverrides(memory) {
|
|
218
|
+
const env = process.env;
|
|
219
|
+
if (env.YAMA_MEMORY_ENABLED) {
|
|
220
|
+
memory.enabled = env.YAMA_MEMORY_ENABLED === "true";
|
|
221
|
+
}
|
|
222
|
+
if (env.YAMA_MEMORY_STORAGE_PATH) {
|
|
223
|
+
memory.storagePath = env.YAMA_MEMORY_STORAGE_PATH;
|
|
224
|
+
}
|
|
225
|
+
if (env.YAMA_MEMORY_MAX_WORDS) {
|
|
226
|
+
memory.maxWords = parseInt(env.YAMA_MEMORY_MAX_WORDS, 10);
|
|
227
|
+
}
|
|
228
|
+
if (env.YAMA_MEMORY_AUTO_COMMIT) {
|
|
229
|
+
memory.autoCommit = env.YAMA_MEMORY_AUTO_COMMIT === "true";
|
|
230
|
+
}
|
|
231
|
+
if (env.YAMA_MEMORY_PROMPT) {
|
|
232
|
+
memory.prompt = env.YAMA_MEMORY_PROMPT;
|
|
233
|
+
}
|
|
234
|
+
return memory;
|
|
235
|
+
}
|
|
184
236
|
/**
|
|
185
237
|
* Basic configuration validation
|
|
186
238
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default Configuration for Yama
|
|
2
|
+
* Default Configuration for Yama
|
|
3
3
|
* Provides sensible defaults when no config file is present
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { YamaConfig } from "../types/config.types.js";
|
|
6
6
|
export declare class DefaultConfig {
|
|
7
|
-
static get():
|
|
7
|
+
static get(): YamaConfig;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=DefaultConfig.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default Configuration for Yama
|
|
2
|
+
* Default Configuration for Yama
|
|
3
3
|
* Provides sensible defaults when no config file is present
|
|
4
4
|
*/
|
|
5
5
|
export class DefaultConfig {
|
|
6
6
|
static get() {
|
|
7
7
|
return {
|
|
8
8
|
version: 2,
|
|
9
|
-
configType: "yama
|
|
9
|
+
configType: "yama",
|
|
10
10
|
display: {
|
|
11
11
|
showBanner: true,
|
|
12
12
|
streamingMode: false,
|
|
@@ -22,6 +22,8 @@ export class DefaultConfig {
|
|
|
22
22
|
enableEvaluation: false,
|
|
23
23
|
timeout: "15m",
|
|
24
24
|
retryAttempts: 3,
|
|
25
|
+
enableToolFiltering: false,
|
|
26
|
+
toolFilteringMode: "off",
|
|
25
27
|
conversationMemory: {
|
|
26
28
|
enabled: true,
|
|
27
29
|
store: "memory",
|
|
@@ -156,6 +158,11 @@ export class DefaultConfig {
|
|
|
156
158
|
summaryRetentionCount: 20,
|
|
157
159
|
autoCommit: false,
|
|
158
160
|
},
|
|
161
|
+
memory: {
|
|
162
|
+
enabled: false,
|
|
163
|
+
storagePath: ".yama/memory",
|
|
164
|
+
maxWords: 200,
|
|
165
|
+
},
|
|
159
166
|
projectStandards: {
|
|
160
167
|
customPromptsPath: "config/prompts/",
|
|
161
168
|
additionalFocusAreas: [],
|