@maxanatsko/llm-cli-bridge 3.1.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 (131) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +203 -0
  3. package/dist/backends/codex.d.ts +37 -0
  4. package/dist/backends/codex.d.ts.map +1 -0
  5. package/dist/backends/codex.js +438 -0
  6. package/dist/backends/codex.js.map +1 -0
  7. package/dist/backends/gemini.d.ts +17 -0
  8. package/dist/backends/gemini.d.ts.map +1 -0
  9. package/dist/backends/gemini.js +174 -0
  10. package/dist/backends/gemini.js.map +1 -0
  11. package/dist/backends/index.d.ts +8 -0
  12. package/dist/backends/index.d.ts.map +1 -0
  13. package/dist/backends/index.js +9 -0
  14. package/dist/backends/index.js.map +1 -0
  15. package/dist/backends/registry.d.ts +33 -0
  16. package/dist/backends/registry.d.ts.map +1 -0
  17. package/dist/backends/registry.js +80 -0
  18. package/dist/backends/registry.js.map +1 -0
  19. package/dist/backends/types.d.ts +61 -0
  20. package/dist/backends/types.d.ts.map +1 -0
  21. package/dist/backends/types.js +5 -0
  22. package/dist/backends/types.js.map +1 -0
  23. package/dist/constants.d.ts +223 -0
  24. package/dist/constants.d.ts.map +1 -0
  25. package/dist/constants.js +228 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +192 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/tools/ask.tool.d.ts +4 -0
  32. package/dist/tools/ask.tool.d.ts.map +1 -0
  33. package/dist/tools/ask.tool.js +113 -0
  34. package/dist/tools/ask.tool.js.map +1 -0
  35. package/dist/tools/brainstorm.tool.d.ts +3 -0
  36. package/dist/tools/brainstorm.tool.d.ts.map +1 -0
  37. package/dist/tools/brainstorm.tool.js +250 -0
  38. package/dist/tools/brainstorm.tool.js.map +1 -0
  39. package/dist/tools/index.d.ts +5 -0
  40. package/dist/tools/index.d.ts.map +1 -0
  41. package/dist/tools/index.js +13 -0
  42. package/dist/tools/index.js.map +1 -0
  43. package/dist/tools/registry.d.ts +42 -0
  44. package/dist/tools/registry.d.ts.map +1 -0
  45. package/dist/tools/registry.js +85 -0
  46. package/dist/tools/registry.js.map +1 -0
  47. package/dist/tools/review-code.tool.d.ts +3 -0
  48. package/dist/tools/review-code.tool.d.ts.map +1 -0
  49. package/dist/tools/review-code.tool.js +279 -0
  50. package/dist/tools/review-code.tool.js.map +1 -0
  51. package/dist/tools/test-tool.example.d.ts +13 -0
  52. package/dist/tools/test-tool.example.d.ts.map +1 -0
  53. package/dist/tools/test-tool.example.js +32 -0
  54. package/dist/tools/test-tool.example.js.map +1 -0
  55. package/dist/tools/timeout-test.tool.d.ts +3 -0
  56. package/dist/tools/timeout-test.tool.d.ts.map +1 -0
  57. package/dist/tools/timeout-test.tool.js +38 -0
  58. package/dist/tools/timeout-test.tool.js.map +1 -0
  59. package/dist/utils/askSessionManager.d.ts +59 -0
  60. package/dist/utils/askSessionManager.d.ts.map +1 -0
  61. package/dist/utils/askSessionManager.js +123 -0
  62. package/dist/utils/askSessionManager.js.map +1 -0
  63. package/dist/utils/brainstormSessionManager.d.ts +67 -0
  64. package/dist/utils/brainstormSessionManager.d.ts.map +1 -0
  65. package/dist/utils/brainstormSessionManager.js +174 -0
  66. package/dist/utils/brainstormSessionManager.js.map +1 -0
  67. package/dist/utils/changeModeInstructions.d.ts +17 -0
  68. package/dist/utils/changeModeInstructions.d.ts.map +1 -0
  69. package/dist/utils/changeModeInstructions.js +100 -0
  70. package/dist/utils/changeModeInstructions.js.map +1 -0
  71. package/dist/utils/changeModeParser.d.ts +15 -0
  72. package/dist/utils/changeModeParser.d.ts.map +1 -0
  73. package/dist/utils/changeModeParser.js +81 -0
  74. package/dist/utils/changeModeParser.js.map +1 -0
  75. package/dist/utils/changeModeTranslator.d.ts +4 -0
  76. package/dist/utils/changeModeTranslator.d.ts.map +1 -0
  77. package/dist/utils/changeModeTranslator.js +42 -0
  78. package/dist/utils/changeModeTranslator.js.map +1 -0
  79. package/dist/utils/commandExecutor.d.ts +2 -0
  80. package/dist/utils/commandExecutor.d.ts.map +1 -0
  81. package/dist/utils/commandExecutor.js +76 -0
  82. package/dist/utils/commandExecutor.js.map +1 -0
  83. package/dist/utils/envAllowlist.d.ts +17 -0
  84. package/dist/utils/envAllowlist.d.ts.map +1 -0
  85. package/dist/utils/envAllowlist.js +54 -0
  86. package/dist/utils/envAllowlist.js.map +1 -0
  87. package/dist/utils/geminiExecutor.d.ts +3 -0
  88. package/dist/utils/geminiExecutor.d.ts.map +1 -0
  89. package/dist/utils/geminiExecutor.js +94 -0
  90. package/dist/utils/geminiExecutor.js.map +1 -0
  91. package/dist/utils/gitStateDetector.d.ts +32 -0
  92. package/dist/utils/gitStateDetector.d.ts.map +1 -0
  93. package/dist/utils/gitStateDetector.js +68 -0
  94. package/dist/utils/gitStateDetector.js.map +1 -0
  95. package/dist/utils/logger.d.ts +13 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +42 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/reviewFormatter.d.ts +35 -0
  100. package/dist/utils/reviewFormatter.d.ts.map +1 -0
  101. package/dist/utils/reviewFormatter.js +201 -0
  102. package/dist/utils/reviewFormatter.js.map +1 -0
  103. package/dist/utils/reviewPromptBuilder.d.ts +43 -0
  104. package/dist/utils/reviewPromptBuilder.d.ts.map +1 -0
  105. package/dist/utils/reviewPromptBuilder.js +170 -0
  106. package/dist/utils/reviewPromptBuilder.js.map +1 -0
  107. package/dist/utils/reviewResponseParser.d.ts +20 -0
  108. package/dist/utils/reviewResponseParser.d.ts.map +1 -0
  109. package/dist/utils/reviewResponseParser.js +149 -0
  110. package/dist/utils/reviewResponseParser.js.map +1 -0
  111. package/dist/utils/reviewSessionCache.d.ts +81 -0
  112. package/dist/utils/reviewSessionCache.d.ts.map +1 -0
  113. package/dist/utils/reviewSessionCache.js +220 -0
  114. package/dist/utils/reviewSessionCache.js.map +1 -0
  115. package/dist/utils/reviewSessionManager.d.ts +52 -0
  116. package/dist/utils/reviewSessionManager.d.ts.map +1 -0
  117. package/dist/utils/reviewSessionManager.js +65 -0
  118. package/dist/utils/reviewSessionManager.js.map +1 -0
  119. package/dist/utils/sessionManager.d.ts +95 -0
  120. package/dist/utils/sessionManager.d.ts.map +1 -0
  121. package/dist/utils/sessionManager.js +382 -0
  122. package/dist/utils/sessionManager.js.map +1 -0
  123. package/dist/utils/sessionSchemas.d.ts +140 -0
  124. package/dist/utils/sessionSchemas.d.ts.map +1 -0
  125. package/dist/utils/sessionSchemas.js +2 -0
  126. package/dist/utils/sessionSchemas.js.map +1 -0
  127. package/dist/utils/timeoutManager.d.ts +2 -0
  128. package/dist/utils/timeoutManager.d.ts.map +1 -0
  129. package/dist/utils/timeoutManager.js +2 -0
  130. package/dist/utils/timeoutManager.js.map +1 -0
  131. package/package.json +72 -0
@@ -0,0 +1,279 @@
1
+ import { z } from 'zod';
2
+ import { getBackend } from '../backends/index.js';
3
+ import { getCurrentGitState, generateSessionId, detectSessionContinuation } from '../utils/gitStateDetector.js';
4
+ import { loadReviewSession, saveReviewSession, createNewSession } from '../utils/reviewSessionManager.js';
5
+ import { buildReviewPrompt, extractFilesFromPrompt } from '../utils/reviewPromptBuilder.js';
6
+ import { parseReviewResponse, validateComments } from '../utils/reviewResponseParser.js';
7
+ import { formatReviewResponse, formatSessionNotFound, formatGitStateWarning } from '../utils/reviewFormatter.js';
8
+ import { Logger } from '../utils/logger.js';
9
+ import { MODELS } from '../constants.js';
10
+ const reviewCodeArgsSchema = z.object({
11
+ prompt: z
12
+ .string()
13
+ .min(1)
14
+ .describe('Review request or follow-up question'),
15
+ backend: z
16
+ .enum(['gemini', 'codex'])
17
+ .optional()
18
+ .describe("AI backend to use: 'gemini' (default) or 'codex'. Gemini offers 1M+ token context, Codex integrates with OpenAI models."),
19
+ files: z
20
+ .array(z.string())
21
+ .optional()
22
+ .describe('Specific files to review (uses @ syntax internally)'),
23
+ sessionId: z
24
+ .string()
25
+ .optional()
26
+ .describe('Explicit session ID to continue (auto-detected from git if omitted)'),
27
+ forceNewSession: z
28
+ .boolean()
29
+ .default(false)
30
+ .describe('Force create new session ignoring git state'),
31
+ reviewType: z
32
+ .enum(['security', 'performance', 'quality', 'architecture', 'general'])
33
+ .default('general')
34
+ .describe('Type of review to perform'),
35
+ severity: z
36
+ .enum(['all', 'critical-only', 'important-and-above'])
37
+ .default('all')
38
+ .describe('Filter issues by severity level'),
39
+ commentDecisions: z
40
+ .array(z.object({
41
+ commentId: z.string(),
42
+ // Accept both legacy verbs and persisted status values for compatibility.
43
+ decision: z.enum([
44
+ 'accept',
45
+ 'reject',
46
+ 'modify',
47
+ 'defer',
48
+ 'accepted',
49
+ 'rejected',
50
+ 'modified',
51
+ 'deferred'
52
+ ]),
53
+ notes: z.string().optional()
54
+ }))
55
+ .optional()
56
+ .describe('Responses to previous round\'s comments'),
57
+ model: z
58
+ .string()
59
+ .optional()
60
+ .describe("Model override. Gemini: 'gemini-3.1-pro' (default), 'gemini-3-flash', 'gemini-2.5-pro', 'gemini-2.5-flash'. Codex: 'gpt-5.4' (default), 'gpt-5.4-mini', 'gpt-5.3-codex', 'gpt-5.2-codex', 'gpt-5.2'"),
61
+ reasoningEffort: z
62
+ .enum(['low', 'medium', 'high', 'xhigh'])
63
+ .optional()
64
+ .describe("Reasoning effort level (Codex only): 'low', 'medium' (default), 'high', 'xhigh'. Use 'high'/'xhigh' for complex tasks."),
65
+ includeHistory: z
66
+ .boolean()
67
+ .default(true)
68
+ .describe('Include conversation history in prompt'),
69
+ allowedTools: z
70
+ .array(z.string())
71
+ .optional()
72
+ .describe('Tools that AI can auto-approve without confirmation (e.g., [\'run_shell_command\']). Use sparingly for security.'),
73
+ cwd: z
74
+ .string()
75
+ .optional()
76
+ .describe('Working directory for CLI execution. Use this to match your IDE workspace directory if you get \'Directory mismatch\' errors.')
77
+ });
78
+ export const reviewCodeTool = {
79
+ name: 'review-code',
80
+ description: 'Interactive code review with session continuity. Auto-detects git state for session management. Maintains conversation history and tracks review decisions across iterations.',
81
+ zodSchema: reviewCodeArgsSchema,
82
+ annotations: {
83
+ readOnlyHint: true, // Only reads files and git state
84
+ destructiveHint: false, // Doesn't modify or delete data
85
+ idempotentHint: false, // Same input yields different AI responses
86
+ openWorldHint: true, // Interacts with external AI APIs
87
+ },
88
+ category: 'ai',
89
+ execute: async (args, onProgress) => {
90
+ const { prompt, backend: backendChoice, files, sessionId, forceNewSession, reviewType, severity, commentDecisions, model, reasoningEffort, includeHistory, allowedTools, cwd } = args;
91
+ try {
92
+ // Step 1: Determine session
93
+ onProgress?.('🔍 Detecting git state and session...');
94
+ const currentGitState = await getCurrentGitState(cwd);
95
+ const detectedSessionId = generateSessionId(currentGitState);
96
+ // Sanitize user-provided session ID to prevent path traversal
97
+ const sanitizeSessionId = (id) => {
98
+ // Only allow alphanumeric, hyphens, underscores; limit to 100 chars
99
+ return id.replace(/[^a-zA-Z0-9-_]/g, '-').slice(0, 100);
100
+ };
101
+ // If user provides a session ID, incorporate git state to prevent cross-task context bleeding
102
+ // e.g., "iterative-review" becomes "iterative-review-main-abc12345"
103
+ const sanitizedSessionId = sessionId ? sanitizeSessionId(sessionId) : null;
104
+ const targetSessionId = sanitizedSessionId
105
+ ? `${sanitizedSessionId}-${currentGitState.branch.replace(/[^a-zA-Z0-9-_]/g, '-')}-${currentGitState.commitHash.slice(0, 8)}`
106
+ : detectedSessionId;
107
+ Logger.debug(`Current git state: ${currentGitState.branch} @ ${currentGitState.commitHash.slice(0, 8)}`);
108
+ Logger.debug(`Target session ID: ${targetSessionId}`);
109
+ // Step 2: Load or create session
110
+ let session;
111
+ let isNewSession = false;
112
+ if (forceNewSession) {
113
+ Logger.debug('Force new session requested');
114
+ session = createNewSession(targetSessionId, currentGitState, files);
115
+ isNewSession = true;
116
+ }
117
+ else {
118
+ const existing = await loadReviewSession(targetSessionId);
119
+ if (existing) {
120
+ // Validate git state hasn't diverged
121
+ const continuationCheck = detectSessionContinuation(currentGitState, existing.gitState);
122
+ if (!continuationCheck.canContinue) {
123
+ onProgress?.(formatGitStateWarning(continuationCheck.reason, true));
124
+ }
125
+ session = existing;
126
+ session.currentGitState = currentGitState;
127
+ Logger.debug(`Loaded existing session with ${session.totalRounds} rounds`);
128
+ }
129
+ else {
130
+ if (sanitizedSessionId) {
131
+ // User explicitly requested a session that doesn't exist
132
+ return formatSessionNotFound(targetSessionId, currentGitState.branch, currentGitState.commitHash);
133
+ }
134
+ // Create new session
135
+ session = createNewSession(targetSessionId, currentGitState, files);
136
+ isNewSession = true;
137
+ Logger.debug('Created new session');
138
+ }
139
+ }
140
+ // Step 3: Process comment decisions from previous round
141
+ if (commentDecisions && commentDecisions.length > 0) {
142
+ applyCommentDecisions(session, commentDecisions);
143
+ onProgress?.(`✅ Applied ${commentDecisions.length} comment decision(s)`);
144
+ }
145
+ // Step 4: Update files tracked - use Set for efficient uniqueness handling
146
+ if (files && files.length > 0) {
147
+ session.filesTracked = [...new Set([...session.filesTracked, ...files])];
148
+ }
149
+ // Step 5: Build review prompt with context
150
+ const reviewPrompt = buildReviewPrompt({
151
+ userPrompt: prompt,
152
+ session,
153
+ files: files,
154
+ reviewType: reviewType,
155
+ severity: severity,
156
+ includeHistory: !!includeHistory,
157
+ currentGitState
158
+ });
159
+ Logger.debug(`Built review prompt (${reviewPrompt.length} chars)`);
160
+ // Step 6: Execute review via selected backend (defaults to session's last backend, then Gemini)
161
+ const backendType = backendChoice || session.lastBackend || 'gemini';
162
+ const backend = await getBackend(backendType);
163
+ onProgress?.(`🤖 Using ${backend.name} backend...`);
164
+ onProgress?.(`🔍 Round ${session.totalRounds + 1}: Reviewing ${files?.length || 'tracked'} file(s)...`);
165
+ const selectedModel = backendType === 'gemini'
166
+ ? model || MODELS.FLASH
167
+ : model;
168
+ // Pass existing codexThreadId for native session resume when using Codex
169
+ const backendResult = await backend.execute(reviewPrompt, {
170
+ provider: backendType,
171
+ model: selectedModel,
172
+ sandbox: false,
173
+ changeMode: false,
174
+ allowedTools: allowedTools,
175
+ cwd: cwd,
176
+ codexThreadId: session.codexThreadId, // For Codex native session resume
177
+ reasoningEffort: reasoningEffort,
178
+ }, onProgress);
179
+ // Always track which backend was used
180
+ session.lastBackend = backendType;
181
+ // Store Codex thread ID for native session resume
182
+ if (backendResult.codexThreadId && backendResult.codexThreadId.length > 0) {
183
+ session.codexThreadId = backendResult.codexThreadId;
184
+ const threadPreview = backendResult.codexThreadId.slice(0, 8);
185
+ onProgress?.(`🔗 Codex thread: ${threadPreview}...`);
186
+ }
187
+ // Step 7: Parse response into structured comments
188
+ onProgress?.('📝 Parsing review feedback...');
189
+ let newComments = parseReviewResponse(backendResult.response, session.totalRounds + 1);
190
+ newComments = validateComments(newComments);
191
+ // Apply severity filter if requested
192
+ if (severity === 'critical-only') {
193
+ newComments = newComments.filter(c => c.severity === 'critical');
194
+ }
195
+ else if (severity === 'important-and-above') {
196
+ newComments = newComments.filter(c => c.severity === 'critical' || c.severity === 'important');
197
+ }
198
+ Logger.debug(`Parsed ${newComments.length} comments (after filtering)`);
199
+ // Step 8: Create new review round
200
+ const filesReviewed = files || extractFilesFromPrompt(reviewPrompt);
201
+ const newRound = {
202
+ roundNumber: session.totalRounds + 1,
203
+ timestamp: Date.now(),
204
+ filesReviewed: filesReviewed,
205
+ userPrompt: prompt,
206
+ response: backendResult.response,
207
+ commentsGenerated: newComments,
208
+ gitState: currentGitState
209
+ };
210
+ session.rounds.push(newRound);
211
+ session.allComments.push(...newComments);
212
+ session.totalRounds++;
213
+ session.lastAccessedAt = Date.now();
214
+ // Step 9: Save session
215
+ await saveReviewSession(session);
216
+ onProgress?.('💾 Session saved');
217
+ // Step 10: Format and return response
218
+ const formattedResponse = formatReviewResponse({
219
+ session,
220
+ currentRound: newRound,
221
+ newComments,
222
+ showHistory: !!includeHistory
223
+ });
224
+ return formattedResponse;
225
+ }
226
+ catch (error) {
227
+ Logger.error(`Review code execution error: ${error}`);
228
+ throw new Error(`Code review failed: ${error instanceof Error ? error.message : String(error)}`);
229
+ }
230
+ }
231
+ };
232
+ /**
233
+ * Applies comment decisions from the user to the session
234
+ * Uses Map for O(1) comment lookups instead of O(N) linear search
235
+ * @param session The current session
236
+ * @param decisions Array of comment decisions
237
+ */
238
+ function applyCommentDecisions(session, decisions) {
239
+ // Create a Map for O(1) lookups instead of O(N) linear search
240
+ const commentMap = new Map(session.allComments.map(c => [c.id, c]));
241
+ const normalizeDecision = (decision) => {
242
+ switch (decision) {
243
+ case 'accept':
244
+ return 'accepted';
245
+ case 'reject':
246
+ return 'rejected';
247
+ case 'modify':
248
+ return 'modified';
249
+ case 'defer':
250
+ return 'deferred';
251
+ case 'accepted':
252
+ case 'rejected':
253
+ case 'modified':
254
+ case 'deferred':
255
+ return decision;
256
+ default:
257
+ return null;
258
+ }
259
+ };
260
+ for (const decision of decisions) {
261
+ const comment = commentMap.get(decision.commentId);
262
+ if (comment) {
263
+ const normalized = normalizeDecision(decision.decision);
264
+ if (!normalized) {
265
+ Logger.debug(`Ignoring unknown decision '${decision.decision}' for comment ${decision.commentId}`);
266
+ continue;
267
+ }
268
+ comment.status = normalized;
269
+ if (decision.notes) {
270
+ comment.resolution = decision.notes;
271
+ }
272
+ Logger.debug(`Applied decision '${decision.decision}' to comment ${decision.commentId}`);
273
+ }
274
+ else {
275
+ Logger.debug(`Comment ${decision.commentId} not found in session`);
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=review-code.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-code.tool.js","sourceRoot":"","sources":["../../src/tools/review-code.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Example: Adding a new tool with the unified registry
3
+ * To add this tool:
4
+ * 1. Rename this file to remove .example (test-tool.ts)
5
+ * 2. Import and register in src/tools/index.ts:
6
+ * import { testTool } from './test-tool.js';
7
+ * toolRegistry.push(testTool);
8
+ *
9
+ * That's it! No more editing multiple files.
10
+ */
11
+ import { UnifiedTool } from './registry.js';
12
+ export declare const testTool: UnifiedTool;
13
+ //# sourceMappingURL=test-tool.example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-tool.example.d.ts","sourceRoot":"","sources":["../../src/tools/test-tool.example.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,eAAO,MAAM,QAAQ,EAAE,WAgBtB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Example: Adding a new tool with the unified registry
3
+ * To add this tool:
4
+ * 1. Rename this file to remove .example (test-tool.ts)
5
+ * 2. Import and register in src/tools/index.ts:
6
+ * import { testTool } from './test-tool.js';
7
+ * toolRegistry.push(testTool);
8
+ *
9
+ * That's it! No more editing multiple files.
10
+ */
11
+ import { z } from 'zod';
12
+ const testToolArgsSchema = z.object({
13
+ message: z.string().describe("Test message to echo"), // Required field (no .optional())
14
+ });
15
+ export const testTool = {
16
+ name: "test-tool",
17
+ description: "A test tool demonstrating the simplified registration",
18
+ zodSchema: testToolArgsSchema,
19
+ prompt: {
20
+ description: "Test the new unified tool registration",
21
+ arguments: [{
22
+ name: "message",
23
+ description: "Message to test with",
24
+ required: true
25
+ }]
26
+ },
27
+ category: 'utility',
28
+ execute: async (args) => {
29
+ return `Test tool received: ${args.message}`;
30
+ }
31
+ };
32
+ //# sourceMappingURL=test-tool.example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-tool.example.js","sourceRoot":"","sources":["../../src/tools/test-tool.example.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,kCAAkC;CACzF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,uDAAuD;IACpE,SAAS,EAAE,kBAAkB;IAC7B,MAAM,EAAE;QACN,WAAW,EAAE,wCAAwC;QACrD,SAAS,EAAE,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,sBAAsB;gBACnC,QAAQ,EAAE,IAAI;aACf,CAAC;KACH;IACD,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,OAAO,uBAAuB,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/C,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { UnifiedTool } from './registry.js';
2
+ export declare const timeoutTestTool: UnifiedTool;
3
+ //# sourceMappingURL=timeout-test.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-test.tool.d.ts","sourceRoot":"","sources":["../../src/tools/timeout-test.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,eAAO,MAAM,eAAe,EAAE,WAoC7B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { z } from 'zod';
2
+ const timeoutTestArgsSchema = z.object({
3
+ duration: z.number().min(10).describe("Duration in milliseconds (minimum 10ms)"),
4
+ });
5
+ export const timeoutTestTool = {
6
+ name: "timeout-test",
7
+ description: "Test timeout prevention by running for a specified duration",
8
+ zodSchema: timeoutTestArgsSchema,
9
+ annotations: {
10
+ readOnlyHint: true, // Just waits, doesn't modify state
11
+ destructiveHint: false, // Doesn't delete anything
12
+ idempotentHint: true, // Same input yields same result
13
+ openWorldHint: false, // No external interactions
14
+ },
15
+ prompt: {
16
+ description: "Test the timeout prevention system by running a long operation",
17
+ },
18
+ category: 'simple',
19
+ execute: async (args, onProgress) => {
20
+ const duration = args.duration;
21
+ const steps = Math.ceil(duration / 5000); // Progress every 5 seconds
22
+ const stepDuration = duration / steps;
23
+ const startTime = Date.now();
24
+ const results = [];
25
+ results.push(`Starting timeout test for ${duration}ms (${duration / 1000}s)`);
26
+ for (let i = 1; i <= steps; i++) {
27
+ await new Promise(resolve => setTimeout(resolve, stepDuration));
28
+ const elapsed = Date.now() - startTime;
29
+ results.push(`Step ${i}/${steps} completed - Elapsed: ${Math.round(elapsed / 1000)}s`);
30
+ }
31
+ const totalElapsed = Date.now() - startTime;
32
+ results.push(`\nTimeout test completed successfully!`);
33
+ results.push(`Target duration: ${duration}ms`);
34
+ results.push(`Actual duration: ${totalElapsed}ms`);
35
+ return results.join('\n');
36
+ }
37
+ };
38
+ //# sourceMappingURL=timeout-test.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-test.tool.js","sourceRoot":"","sources":["../../src/tools/timeout-test.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CACjF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAgB;IAC1C,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,6DAA6D;IAC1E,SAAS,EAAE,qBAAqB;IAChC,WAAW,EAAE;QACX,YAAY,EAAE,IAAI,EAAO,mCAAmC;QAC5D,eAAe,EAAE,KAAK,EAAG,0BAA0B;QACnD,cAAc,EAAE,IAAI,EAAK,gCAAgC;QACzD,aAAa,EAAE,KAAK,EAAK,2BAA2B;KACrD;IACD,MAAM,EAAE;QACN,WAAW,EAAE,gEAAgE;KAC9E;IACD,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,2BAA2B;QACrE,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,6BAA6B,QAAQ,OAAO,QAAQ,GAAC,IAAI,IAAI,CAAC,CAAC;QAE5E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,yBAAyB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,oBAAoB,QAAQ,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,oBAAoB,YAAY,IAAI,CAAC,CAAC;QAEnD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { AskSessionData } from './sessionSchemas.js';
2
+ /**
3
+ * Session manager for ask tool
4
+ * Tracks multi-turn conversations with context across backends
5
+ */
6
+ export declare class AskSessionManager {
7
+ private sessionManager;
8
+ constructor();
9
+ /**
10
+ * Creates a new conversation session
11
+ */
12
+ createSession(sessionId: string): AskSessionData;
13
+ /**
14
+ * Adds a conversation round to the session
15
+ */
16
+ addRound(session: AskSessionData, userPrompt: string, response: string, model: string, contextFiles?: string[], backend?: 'gemini' | 'codex', codexThreadId?: string): AskSessionData;
17
+ /**
18
+ * Builds conversation context from history for inclusion in prompts
19
+ * @param session The session to build context from
20
+ * @param maxRounds Maximum number of previous rounds to include (default: 3)
21
+ * @returns Formatted conversation context
22
+ */
23
+ buildConversationContext(session: AskSessionData, maxRounds?: number): string;
24
+ /**
25
+ * Saves a session
26
+ */
27
+ save(session: AskSessionData): Promise<void>;
28
+ /**
29
+ * Loads a session
30
+ */
31
+ load(sessionId: string): Promise<AskSessionData | null>;
32
+ /**
33
+ * Lists all sessions
34
+ */
35
+ list(): Promise<AskSessionData[]>;
36
+ /**
37
+ * Deletes a session
38
+ */
39
+ delete(sessionId: string): Promise<boolean>;
40
+ /**
41
+ * Gets or creates a session
42
+ */
43
+ getOrCreate(sessionId: string): Promise<AskSessionData>;
44
+ /**
45
+ * Gets cache statistics
46
+ */
47
+ getStats(): Promise<{
48
+ toolName: string;
49
+ sessionCount: number;
50
+ ttl: number;
51
+ maxSessions: number;
52
+ evictionPolicy: string;
53
+ cacheDir: string;
54
+ }>;
55
+ }
56
+ export declare const askSessionManager: AskSessionManager;
57
+ export declare const AskGeminiSessionManager: typeof AskSessionManager;
58
+ export declare const askGeminiSessionManager: AskSessionManager;
59
+ //# sourceMappingURL=askSessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"askSessionManager.d.ts","sourceRoot":"","sources":["../../src/utils/askSessionManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,cAAc,CAAiC;;IAMvD;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;IAahD;;OAEG;IACH,QAAQ,CACN,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,cAAc;IA+BjB;;;;;OAKG;IACH,wBAAwB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,GAAE,MAAU,GAAG,MAAM;IAsBhF;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI7D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAIvC;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQ7D;;OAEG;IACG,QAAQ;;;;;;;;CAGf;AAGD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC;AAGzD,eAAO,MAAM,uBAAuB,0BAAoB,CAAC;AACzD,eAAO,MAAM,uBAAuB,mBAAoB,CAAC"}
@@ -0,0 +1,123 @@
1
+ import { SessionManager } from './sessionManager.js';
2
+ /**
3
+ * Session manager for ask tool
4
+ * Tracks multi-turn conversations with context across backends
5
+ */
6
+ export class AskSessionManager {
7
+ sessionManager;
8
+ constructor() {
9
+ this.sessionManager = new SessionManager('ask');
10
+ }
11
+ /**
12
+ * Creates a new conversation session
13
+ */
14
+ createSession(sessionId) {
15
+ const now = Date.now();
16
+ return {
17
+ sessionId,
18
+ createdAt: now,
19
+ lastAccessedAt: now,
20
+ conversationHistory: [],
21
+ totalRounds: 0,
22
+ contextFiles: [],
23
+ metadata: {}
24
+ };
25
+ }
26
+ /**
27
+ * Adds a conversation round to the session
28
+ */
29
+ addRound(session, userPrompt, response, model, contextFiles, backend, codexThreadId) {
30
+ session.conversationHistory.push({
31
+ roundNumber: session.totalRounds + 1,
32
+ timestamp: Date.now(),
33
+ userPrompt,
34
+ response,
35
+ model,
36
+ backend
37
+ });
38
+ session.totalRounds++;
39
+ session.lastAccessedAt = Date.now();
40
+ // Track context files
41
+ if (contextFiles && contextFiles.length > 0) {
42
+ session.contextFiles = [...new Set([...session.contextFiles, ...contextFiles])];
43
+ }
44
+ // Store Codex thread ID for native session resume
45
+ if (codexThreadId) {
46
+ session.codexThreadId = codexThreadId;
47
+ }
48
+ // Track which backend was used last
49
+ if (backend) {
50
+ session.lastBackend = backend;
51
+ }
52
+ return session;
53
+ }
54
+ /**
55
+ * Builds conversation context from history for inclusion in prompts
56
+ * @param session The session to build context from
57
+ * @param maxRounds Maximum number of previous rounds to include (default: 3)
58
+ * @returns Formatted conversation context
59
+ */
60
+ buildConversationContext(session, maxRounds = 3) {
61
+ if (session.conversationHistory.length === 0) {
62
+ return '';
63
+ }
64
+ const recentRounds = session.conversationHistory.slice(-maxRounds);
65
+ const contextParts = recentRounds.map(round => {
66
+ // Truncate long responses for context
67
+ const truncatedResponse = round.response.length > 500
68
+ ? round.response.slice(0, 500) + '...'
69
+ : round.response;
70
+ const backendLabel = round.backend === 'codex' ? 'Codex' : 'Gemini';
71
+ return `[Round ${round.roundNumber}]
72
+ User: ${round.userPrompt}
73
+ ${backendLabel}: ${truncatedResponse}`;
74
+ });
75
+ return `# Conversation History\n\n${contextParts.join('\n\n')}`;
76
+ }
77
+ /**
78
+ * Saves a session
79
+ */
80
+ async save(session) {
81
+ await this.sessionManager.save(session.sessionId, session);
82
+ }
83
+ /**
84
+ * Loads a session
85
+ */
86
+ async load(sessionId) {
87
+ return await this.sessionManager.load(sessionId);
88
+ }
89
+ /**
90
+ * Lists all sessions
91
+ */
92
+ async list() {
93
+ return await this.sessionManager.list();
94
+ }
95
+ /**
96
+ * Deletes a session
97
+ */
98
+ async delete(sessionId) {
99
+ return await this.sessionManager.delete(sessionId);
100
+ }
101
+ /**
102
+ * Gets or creates a session
103
+ */
104
+ async getOrCreate(sessionId) {
105
+ const existing = await this.load(sessionId);
106
+ if (existing) {
107
+ return existing;
108
+ }
109
+ return this.createSession(sessionId);
110
+ }
111
+ /**
112
+ * Gets cache statistics
113
+ */
114
+ async getStats() {
115
+ return await this.sessionManager.getStats();
116
+ }
117
+ }
118
+ // Export singleton instance
119
+ export const askSessionManager = new AskSessionManager();
120
+ // Backward compatibility aliases
121
+ export const AskGeminiSessionManager = AskSessionManager;
122
+ export const askGeminiSessionManager = askSessionManager;
123
+ //# sourceMappingURL=askSessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"askSessionManager.js","sourceRoot":"","sources":["../../src/utils/askSessionManager.ts"],"names":[],"mappings":"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"}