@juspay/yama 2.2.2 → 2.4.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +14 -0
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +2 -0
  5. package/dist/v2/config/ConfigLoader.d.ts +15 -0
  6. package/dist/v2/config/ConfigLoader.js +72 -4
  7. package/dist/v2/config/DefaultConfig.js +14 -0
  8. package/dist/v2/core/LearningOrchestrator.d.ts +1 -0
  9. package/dist/v2/core/LearningOrchestrator.js +64 -4
  10. package/dist/v2/core/SessionManager.d.ts +3 -1
  11. package/dist/v2/core/SessionManager.js +30 -0
  12. package/dist/v2/core/YamaV2Orchestrator.d.ts +16 -7
  13. package/dist/v2/core/YamaV2Orchestrator.js +213 -35
  14. package/dist/v2/exploration/ContextExplorerService.d.ts +39 -0
  15. package/dist/v2/exploration/ContextExplorerService.js +451 -0
  16. package/dist/v2/exploration/ExplorerPromptBuilder.d.ts +5 -0
  17. package/dist/v2/exploration/ExplorerPromptBuilder.js +67 -0
  18. package/dist/v2/exploration/RulesContextLoader.d.ts +12 -0
  19. package/dist/v2/exploration/RulesContextLoader.js +106 -0
  20. package/dist/v2/exploration/types.d.ts +26 -0
  21. package/dist/v2/exploration/types.js +2 -0
  22. package/dist/v2/learning/types.d.ts +10 -0
  23. package/dist/v2/memory/MemoryManager.d.ts +65 -0
  24. package/dist/v2/memory/MemoryManager.js +207 -0
  25. package/dist/v2/prompts/LangfusePromptManager.js +6 -0
  26. package/dist/v2/prompts/PromptBuilder.d.ts +18 -1
  27. package/dist/v2/prompts/PromptBuilder.js +131 -29
  28. package/dist/v2/prompts/ReviewSystemPrompt.d.ts +9 -4
  29. package/dist/v2/prompts/ReviewSystemPrompt.js +46 -239
  30. package/dist/v2/types/config.types.d.ts +70 -1
  31. package/dist/v2/types/v2.types.d.ts +28 -0
  32. package/package.json +3 -3
  33. package/yama.config.example.yaml +25 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [2.4.0](https://github.com/juspay/yama/compare/v2.3.0...v2.4.0) (2026-04-15)
2
+
3
+
4
+ ### Features
5
+
6
+ * **v2:** bootstrap repo standards from recent PRs before review ([8c5b1cd](https://github.com/juspay/yama/commit/8c5b1cdd38b684397e7445e04b4db4bc45b5f2a8))
7
+
8
+ # [2.3.0](https://github.com/juspay/yama/compare/v2.2.2...v2.3.0) (2026-04-01)
9
+
10
+
11
+ ### Features
12
+
13
+ * **memory:** add per-repo memory management and configuration ([0b1fd5d](https://github.com/juspay/yama/commit/0b1fd5de8f0e46402f3c54766a5e0c7bd937cca2))
14
+
1
15
  ## [2.2.2](https://github.com/juspay/yama/compare/v2.2.1...v2.2.2) (2026-03-26)
2
16
 
3
17
 
package/README.md CHANGED
@@ -28,6 +28,8 @@
28
28
  ```
29
29
  YamaOrchestrator
30
30
 
31
+ MemoryManager (per-repo condensed memory)
32
+
31
33
  NeuroLink AI Agent (Autonomous)
32
34
 
33
35
  MCP Tools (Bitbucket + Jira)
@@ -38,6 +40,7 @@ Pull Request Operations
38
40
  ### AI Autonomous Workflow
39
41
 
40
42
  1. **Context Gathering** (AI-driven)
43
+ - Reads per-repo memory (past review learnings)
41
44
  - Reads PR details
42
45
  - Finds and reads Jira ticket
43
46
  - Loads project standards from memory-bank
@@ -311,6 +314,17 @@ AI uses tools to understand code:
311
314
  - `get_file_content()` - Read related files
312
315
  - `list_directory_content()` - Explore structure
313
316
 
317
+ ### Per-Repo Memory
318
+
319
+ AI learns from past reviews and remembers across PRs:
320
+
321
+ - Reads condensed memory before each review for context
322
+ - Writes learnings after PR merge (false positives, missed issues, team conventions)
323
+ - LLM-powered condensation keeps memory within a configurable word limit
324
+ - Per-repo isolation — each repository gets independent memory keyed by `workspace-repository`
325
+ - Storage as `.md` files at configurable path (e.g., `memory-bank/yama/memory/`)
326
+ - Environment variable overrides for all settings (`YAMA_MEMORY_ENABLED`, `YAMA_MEMORY_MAX_WORDS`, etc.)
327
+
314
328
  ## Blocking Criteria
315
329
 
316
330
  AI applies these criteria automatically:
package/dist/index.d.ts CHANGED
@@ -3,12 +3,14 @@
3
3
  * Main export file
4
4
  */
5
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";
11
+ export { MemoryManager } from "./v2/memory/MemoryManager.js";
10
12
  export type { LocalReviewFinding, LocalReviewRequest, LocalReviewResult, ReviewRequest, ReviewMode, ReviewResult, ReviewUpdate, ReviewSession, ReviewStatistics, IssuesBySeverity, TokenUsage, UnifiedReviewRequest, } from "./v2/types/v2.types.js";
11
- export type { YamaConfig, YamaInitOptions, YamaConfig as YamaV2Config, AIConfig, MCPServersConfig, ReviewConfig, DescriptionEnhancementConfig, } from "./v2/types/config.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
15
  export declare const VERSION = "2.2.1";
14
16
  export { createYama as default } from "./v2/core/YamaV2Orchestrator.js";
package/dist/index.js CHANGED
@@ -6,10 +6,12 @@
6
6
  // Core Exports
7
7
  // ============================================================================
8
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
  // ============================================================================
@@ -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
  */
@@ -32,6 +32,7 @@ export class ConfigLoader {
32
32
  else {
33
33
  console.log(" Using default configuration (no config file found)");
34
34
  }
35
+ config.memory = this.applyMemoryOverrides(config.memory);
35
36
  // Layer 4: Apply SDK instance overrides (highest priority)
36
37
  if (instanceOverrides) {
37
38
  config = this.mergeConfigs(config, instanceOverrides);
@@ -179,13 +180,19 @@ export class ConfigLoader {
179
180
  if (process.env.AI_MODEL) {
180
181
  config.ai.model = process.env.AI_MODEL;
181
182
  }
182
- // Override temperature if env var set
183
+ // Override temperature if env var set (ignore non-finite values)
183
184
  if (process.env.AI_TEMPERATURE) {
184
- config.ai.temperature = parseFloat(process.env.AI_TEMPERATURE);
185
+ const temperature = Number(process.env.AI_TEMPERATURE);
186
+ if (Number.isFinite(temperature)) {
187
+ config.ai.temperature = temperature;
188
+ }
185
189
  }
186
- // Override max tokens if env var set
190
+ // Override max tokens if env var set (ignore non-integer / non-positive values)
187
191
  if (process.env.AI_MAX_TOKENS) {
188
- config.ai.maxTokens = parseInt(process.env.AI_MAX_TOKENS, 10);
192
+ const maxTokens = Number.parseInt(process.env.AI_MAX_TOKENS, 10);
193
+ if (Number.isInteger(maxTokens) && maxTokens > 0) {
194
+ config.ai.maxTokens = maxTokens;
195
+ }
189
196
  }
190
197
  if (process.env.AI_ENABLE_TOOL_FILTERING) {
191
198
  config.ai.enableToolFiltering =
@@ -197,8 +204,69 @@ export class ConfigLoader {
197
204
  config.ai.toolFilteringMode = mode;
198
205
  }
199
206
  }
207
+ if (process.env.AI_EXPLORE_ENABLED) {
208
+ config.ai.explore.enabled = process.env.AI_EXPLORE_ENABLED === "true";
209
+ }
210
+ if (process.env.AI_EXPLORE_PROVIDER) {
211
+ config.ai.explore.provider = process.env.AI_EXPLORE_PROVIDER;
212
+ }
213
+ if (process.env.AI_EXPLORE_MODEL) {
214
+ config.ai.explore.model = process.env.AI_EXPLORE_MODEL;
215
+ }
216
+ if (process.env.AI_EXPLORE_TEMPERATURE) {
217
+ const temperature = Number(process.env.AI_EXPLORE_TEMPERATURE);
218
+ if (Number.isFinite(temperature)) {
219
+ config.ai.explore.temperature = temperature;
220
+ }
221
+ }
222
+ if (process.env.AI_EXPLORE_MAX_TOKENS) {
223
+ const maxTokens = Number.parseInt(process.env.AI_EXPLORE_MAX_TOKENS, 10);
224
+ if (Number.isInteger(maxTokens) && maxTokens > 0) {
225
+ config.ai.explore.maxTokens = maxTokens;
226
+ }
227
+ }
228
+ if (process.env.AI_EXPLORE_TIMEOUT) {
229
+ config.ai.explore.timeout = process.env.AI_EXPLORE_TIMEOUT;
230
+ }
231
+ if (process.env.AI_EXPLORE_CACHE_RESULTS) {
232
+ config.ai.explore.cacheResults =
233
+ process.env.AI_EXPLORE_CACHE_RESULTS === "true";
234
+ }
200
235
  return config;
201
236
  }
237
+ /**
238
+ * Apply memory-related environment variable overrides.
239
+ *
240
+ * Env vars (YAMA_MEMORY_*) take precedence over yaml config.
241
+ * If YAMA_MEMORY_ENABLED is set but no memory config exists in yaml,
242
+ * a default config is created so the other overrides have a target.
243
+ *
244
+ * Supported env vars:
245
+ * YAMA_MEMORY_ENABLED — "true" / "false"
246
+ * YAMA_MEMORY_STORAGE_PATH — e.g. "memory-bank/yama/memory"
247
+ * YAMA_MEMORY_MAX_WORDS — e.g. "200"
248
+ * YAMA_MEMORY_AUTO_COMMIT — "true" / "false"
249
+ * YAMA_MEMORY_PROMPT — custom condensation prompt
250
+ */
251
+ applyMemoryOverrides(memory) {
252
+ const env = process.env;
253
+ if (env.YAMA_MEMORY_ENABLED) {
254
+ memory.enabled = env.YAMA_MEMORY_ENABLED === "true";
255
+ }
256
+ if (env.YAMA_MEMORY_STORAGE_PATH) {
257
+ memory.storagePath = env.YAMA_MEMORY_STORAGE_PATH;
258
+ }
259
+ if (env.YAMA_MEMORY_MAX_WORDS) {
260
+ memory.maxWords = parseInt(env.YAMA_MEMORY_MAX_WORDS, 10);
261
+ }
262
+ if (env.YAMA_MEMORY_AUTO_COMMIT) {
263
+ memory.autoCommit = env.YAMA_MEMORY_AUTO_COMMIT === "true";
264
+ }
265
+ if (env.YAMA_MEMORY_PROMPT) {
266
+ memory.prompt = env.YAMA_MEMORY_PROMPT;
267
+ }
268
+ return memory;
269
+ }
202
270
  /**
203
271
  * Basic configuration validation
204
272
  */
@@ -31,6 +31,15 @@ export class DefaultConfig {
31
31
  maxTurnsPerSession: 300,
32
32
  enableSummarization: false,
33
33
  },
34
+ explore: {
35
+ enabled: true,
36
+ provider: "auto",
37
+ model: "gemini-2.5-flash",
38
+ temperature: 0.1,
39
+ maxTokens: 32000,
40
+ timeout: "5m",
41
+ cacheResults: true,
42
+ },
34
43
  },
35
44
  mcpServers: {
36
45
  bitbucket: {
@@ -158,6 +167,11 @@ export class DefaultConfig {
158
167
  summaryRetentionCount: 20,
159
168
  autoCommit: false,
160
169
  },
170
+ memory: {
171
+ enabled: false,
172
+ storagePath: ".yama/memory",
173
+ maxWords: 200,
174
+ },
161
175
  projectStandards: {
162
176
  customPromptsPath: "config/prompts/",
163
177
  additionalFocusAreas: [],
@@ -9,6 +9,7 @@ export declare class LearningOrchestrator {
9
9
  private mcpManager;
10
10
  private configLoader;
11
11
  private promptManager;
12
+ private memoryManager;
12
13
  private config;
13
14
  private initialized;
14
15
  constructor();
@@ -8,12 +8,14 @@ import { MCPServerManager } from "./MCPServerManager.js";
8
8
  import { ConfigLoader } from "../config/ConfigLoader.js";
9
9
  import { LangfusePromptManager } from "../prompts/LangfusePromptManager.js";
10
10
  import { KnowledgeBaseManager } from "../learning/KnowledgeBaseManager.js";
11
+ import { MemoryManager } from "../memory/MemoryManager.js";
11
12
  import { buildObservabilityConfigFromEnv, validateObservabilityConfig, } from "../utils/ObservabilityConfig.js";
12
13
  export class LearningOrchestrator {
13
14
  neurolink;
14
15
  mcpManager;
15
16
  configLoader;
16
17
  promptManager;
18
+ memoryManager = null;
17
19
  config;
18
20
  initialized = false;
19
21
  constructor() {
@@ -32,7 +34,12 @@ export class LearningOrchestrator {
32
34
  try {
33
35
  // Load configuration
34
36
  this.config = await this.configLoader.loadConfig(configPath);
35
- // Initialize NeuroLink
37
+ // Initialize Memory Manager (if enabled) — must happen before NeuroLink
38
+ if (this.config.memory?.enabled) {
39
+ this.memoryManager = new MemoryManager(this.config.memory, this.config.ai.provider, this.config.ai.model);
40
+ console.log(" 🧠 Per-repo memory enabled\n");
41
+ }
42
+ // Initialize NeuroLink with memory config injected
36
43
  console.log(" 🔧 Initializing NeuroLink AI engine...");
37
44
  this.neurolink = this.initializeNeurolink();
38
45
  console.log(" ✅ NeuroLink initialized\n");
@@ -126,6 +133,52 @@ export class LearningOrchestrator {
126
133
  if (duplicateCount > 0) {
127
134
  console.log(` ⏭️ Skipped ${duplicateCount} duplicates`);
128
135
  }
136
+ // Resolve commit mode: commitMode takes precedence, fall back to legacy commit flag
137
+ const commitMode = request.commitMode ||
138
+ (request.commit || this.config.knowledgeBase.autoCommit
139
+ ? "kb"
140
+ : undefined);
141
+ const shouldCommitMemory = commitMode === "memory" || commitMode === "all";
142
+ const shouldCommitKb = commitMode === "kb" || commitMode === "all";
143
+ // Store learnings in per-repo memory via NeuroLink
144
+ // read: false (we don't need to read memory here)
145
+ // write: true (condense learnings into memory file)
146
+ if (this.memoryManager && addedCount > 0 && shouldCommitMemory) {
147
+ try {
148
+ const byCategory = new Map();
149
+ for (const l of learnings) {
150
+ const cat = l.category.replace(/_/g, " ");
151
+ if (!byCategory.has(cat)) {
152
+ byCategory.set(cat, []);
153
+ }
154
+ byCategory.get(cat).push(l.learning);
155
+ }
156
+ const parts = [];
157
+ for (const [category, items] of byCategory) {
158
+ parts.push(`${category}: ${items.join("; ")}`);
159
+ }
160
+ const ownerId = MemoryManager.buildOwnerId(request.workspace, request.repository);
161
+ await this.neurolink.generate({
162
+ input: { text: parts.join(". ") },
163
+ provider: this.config.ai.provider,
164
+ model: this.config.ai.model,
165
+ temperature: 0.1,
166
+ maxTokens: 100,
167
+ disableTools: true,
168
+ context: {
169
+ userId: ownerId,
170
+ operation: "memory-store-learnings",
171
+ },
172
+ memory: { read: false, write: true },
173
+ });
174
+ console.log(` 🧠 Learning memory stored for ${ownerId}`);
175
+ // Auto-commit and push memory files to repo
176
+ await this.memoryManager.commitMemoryChanges();
177
+ }
178
+ catch (error) {
179
+ console.warn(` ⚠️ Failed to store learning memory: ${error.message}`);
180
+ }
181
+ }
129
182
  // Check if summarization is needed
130
183
  let summarized = false;
131
184
  if (request.summarize || (await kbManager.needsSummarization())) {
@@ -134,9 +187,9 @@ export class LearningOrchestrator {
134
187
  summarized = true;
135
188
  console.log(" ✅ Summarization complete");
136
189
  }
137
- // Commit if requested
190
+ // Commit knowledge base if requested
138
191
  let committed = false;
139
- if (request.commit || this.config.knowledgeBase.autoCommit) {
192
+ if (shouldCommitKb) {
140
193
  console.log("\n📤 Committing knowledge base...");
141
194
  await kbManager.commit(request.pullRequestId, addedCount);
142
195
  committed = true;
@@ -352,8 +405,15 @@ Analyze the PR data above and extract learnings.
352
405
  */
353
406
  initializeNeurolink() {
354
407
  const observabilityConfig = buildObservabilityConfigFromEnv();
408
+ const conversationMemory = {
409
+ ...this.config.ai.conversationMemory,
410
+ };
411
+ if (this.memoryManager) {
412
+ conversationMemory.memory =
413
+ this.memoryManager.buildNeuroLinkMemoryConfig();
414
+ }
355
415
  const neurolinkConfig = {
356
- conversationMemory: this.config.ai.conversationMemory,
416
+ conversationMemory,
357
417
  };
358
418
  if (observabilityConfig &&
359
419
  validateObservabilityConfig(observabilityConfig)) {
@@ -2,7 +2,7 @@
2
2
  * Session Manager for Yama
3
3
  * Tracks review sessions, tool calls, and maintains state
4
4
  */
5
- import { ReviewSession, ReviewRequest, ReviewResult, SessionMetadata } from "../types/v2.types.js";
5
+ import { ReviewSession, ReviewRequest, ReviewResult, SessionMetadata, ExplorationResult } from "../types/v2.types.js";
6
6
  export declare class SessionManager {
7
7
  private sessions;
8
8
  private maxSessions;
@@ -22,6 +22,8 @@ export declare class SessionManager {
22
22
  * Update session metadata
23
23
  */
24
24
  updateMetadata(sessionId: string, updates: Partial<SessionMetadata>): void;
25
+ recordExploration(sessionId: string, cacheKey: string, task: string, focus: string[], result: ExplorationResult, cached?: boolean): void;
26
+ findExploration(sessionId: string, cacheKey: string): ExplorationResult | null;
25
27
  /**
26
28
  * Mark session as completed
27
29
  */
@@ -25,6 +25,7 @@ export class SessionManager {
25
25
  totalCost: 0,
26
26
  cacheHitRatio: 0,
27
27
  },
28
+ explorations: [],
28
29
  };
29
30
  this.sessions.set(sessionId, session);
30
31
  // Clean up old sessions if we exceed max
@@ -68,6 +69,26 @@ export class SessionManager {
68
69
  ...updates,
69
70
  };
70
71
  }
72
+ recordExploration(sessionId, cacheKey, task, focus, result, cached = false) {
73
+ const session = this.getSession(sessionId);
74
+ session.explorations = session.explorations || [];
75
+ session.explorations.push({
76
+ task,
77
+ cacheKey,
78
+ focus,
79
+ result,
80
+ createdAt: new Date(),
81
+ cached,
82
+ });
83
+ }
84
+ findExploration(sessionId, cacheKey) {
85
+ const session = this.getSession(sessionId);
86
+ const match = (session.explorations || [])
87
+ .slice()
88
+ .reverse()
89
+ .find((exploration) => exploration.cacheKey === cacheKey);
90
+ return match?.result || null;
91
+ }
71
92
  /**
72
93
  * Mark session as completed
73
94
  */
@@ -166,6 +187,15 @@ export class SessionManager {
166
187
  // Don't include full result in export (can be very large)
167
188
  resultSummary: this.summarizeToolResult(tc.result),
168
189
  })),
190
+ explorations: (session.explorations || []).map((exploration) => ({
191
+ task: exploration.task,
192
+ cacheKey: exploration.cacheKey,
193
+ focus: exploration.focus,
194
+ createdAt: exploration.createdAt.toISOString(),
195
+ cached: exploration.cached,
196
+ // Don't include full result in export (can be very large / may contain sensitive data)
197
+ resultSummary: this.summarizeToolResult(exploration.result),
198
+ })),
169
199
  };
170
200
  }
171
201
  /**
@@ -6,16 +6,21 @@ import { LocalReviewRequest, LocalReviewResult, ReviewRequest, ReviewResult, Rev
6
6
  import { YamaInitOptions } from "../types/config.types.js";
7
7
  export declare class YamaOrchestrator {
8
8
  private neurolink;
9
+ private explorer;
9
10
  private mcpManager;
10
11
  private configLoader;
11
12
  private promptBuilder;
12
13
  private sessionManager;
14
+ private memoryManager;
13
15
  private localDiffSource;
14
16
  private config;
15
17
  private initialized;
16
18
  private mcpInitialized;
17
19
  private localGitMcpInitialized;
20
+ private exploreToolRegistered;
21
+ private currentToolContext;
18
22
  private initOptions;
23
+ private bootstrapStandardsCache;
19
24
  constructor(options?: YamaInitOptions);
20
25
  /**
21
26
  * Initialize Yama with configuration and MCP servers
@@ -64,10 +69,10 @@ export declare class YamaOrchestrator {
64
69
  * Export session data
65
70
  */
66
71
  exportSession(sessionId: string): any;
67
- /**
68
- * Create tool context for AI
69
- */
72
+ private getUserId;
70
73
  private createToolContext;
74
+ private createLocalToolContext;
75
+ private setToolContext;
71
76
  /**
72
77
  * Parse AI response into structured review result
73
78
  */
@@ -105,10 +110,6 @@ export declare class YamaOrchestrator {
105
110
  */
106
111
  private calculateCost;
107
112
  private toSafeNumber;
108
- /**
109
- * Generate userId for NeuroLink context from repository and branch/PR
110
- */
111
- private generateUserId;
112
113
  private isLocalReviewRequest;
113
114
  /**
114
115
  * Query-level tool filtering for PR mode.
@@ -125,6 +126,14 @@ export declare class YamaOrchestrator {
125
126
  * Initialize NeuroLink with observability configuration
126
127
  */
127
128
  private initializeNeurolink;
129
+ private registerExploreTool;
130
+ /**
131
+ * Bootstrap repo-level standards by delegating to explore_context.
132
+ * Runs once per (workspace/repository) per process lifetime.
133
+ * Output is injected into the review prompt as <bootstrapped-standards>.
134
+ * Graceful: any failure returns empty and the review proceeds without it.
135
+ */
136
+ private getBootstrappedStandards;
128
137
  /**
129
138
  * Ensure orchestrator is initialized
130
139
  */