gemini-as-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +303 -0
  3. package/dist/constants.d.ts +74 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +73 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +187 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/tools/ask-gemini.tool.d.ts +3 -0
  12. package/dist/tools/ask-gemini.tool.d.ts.map +1 -0
  13. package/dist/tools/ask-gemini.tool.js +36 -0
  14. package/dist/tools/ask-gemini.tool.js.map +1 -0
  15. package/dist/tools/brainstorm.tool.d.ts +3 -0
  16. package/dist/tools/brainstorm.tool.d.ts.map +1 -0
  17. package/dist/tools/brainstorm.tool.js +136 -0
  18. package/dist/tools/brainstorm.tool.js.map +1 -0
  19. package/dist/tools/codebase-tools.d.ts +4 -0
  20. package/dist/tools/codebase-tools.d.ts.map +1 -0
  21. package/dist/tools/codebase-tools.js +104 -0
  22. package/dist/tools/codebase-tools.js.map +1 -0
  23. package/dist/tools/fetch-chunk.tool.d.ts +3 -0
  24. package/dist/tools/fetch-chunk.tool.d.ts.map +1 -0
  25. package/dist/tools/fetch-chunk.tool.js +62 -0
  26. package/dist/tools/fetch-chunk.tool.js.map +1 -0
  27. package/dist/tools/index.d.ts +2 -0
  28. package/dist/tools/index.d.ts.map +1 -0
  29. package/dist/tools/index.js +12 -0
  30. package/dist/tools/index.js.map +1 -0
  31. package/dist/tools/registry.d.ts +25 -0
  32. package/dist/tools/registry.d.ts.map +1 -0
  33. package/dist/tools/registry.js +80 -0
  34. package/dist/tools/registry.js.map +1 -0
  35. package/dist/tools/simple-tools.d.ts +4 -0
  36. package/dist/tools/simple-tools.d.ts.map +1 -0
  37. package/dist/tools/simple-tools.js +32 -0
  38. package/dist/tools/simple-tools.js.map +1 -0
  39. package/dist/tools/test-tool.example.d.ts +13 -0
  40. package/dist/tools/test-tool.example.d.ts.map +1 -0
  41. package/dist/tools/test-tool.example.js +32 -0
  42. package/dist/tools/test-tool.example.js.map +1 -0
  43. package/dist/tools/timeout-test.tool.d.ts +3 -0
  44. package/dist/tools/timeout-test.tool.d.ts.map +1 -0
  45. package/dist/tools/timeout-test.tool.js +32 -0
  46. package/dist/tools/timeout-test.tool.js.map +1 -0
  47. package/dist/tools/web-tools.d.ts +4 -0
  48. package/dist/tools/web-tools.d.ts.map +1 -0
  49. package/dist/tools/web-tools.js +78 -0
  50. package/dist/tools/web-tools.js.map +1 -0
  51. package/dist/utils/changeModeChunker.d.ts +11 -0
  52. package/dist/utils/changeModeChunker.d.ts.map +1 -0
  53. package/dist/utils/changeModeChunker.js +89 -0
  54. package/dist/utils/changeModeChunker.js.map +1 -0
  55. package/dist/utils/changeModeParser.d.ts +15 -0
  56. package/dist/utils/changeModeParser.d.ts.map +1 -0
  57. package/dist/utils/changeModeParser.js +67 -0
  58. package/dist/utils/changeModeParser.js.map +1 -0
  59. package/dist/utils/changeModeTranslator.d.ts +8 -0
  60. package/dist/utils/changeModeTranslator.d.ts.map +1 -0
  61. package/dist/utils/changeModeTranslator.js +70 -0
  62. package/dist/utils/changeModeTranslator.js.map +1 -0
  63. package/dist/utils/chunkCache.d.ts +22 -0
  64. package/dist/utils/chunkCache.d.ts.map +1 -0
  65. package/dist/utils/chunkCache.js +161 -0
  66. package/dist/utils/chunkCache.js.map +1 -0
  67. package/dist/utils/commandExecutor.d.ts +2 -0
  68. package/dist/utils/commandExecutor.d.ts.map +1 -0
  69. package/dist/utils/commandExecutor.js +74 -0
  70. package/dist/utils/commandExecutor.js.map +1 -0
  71. package/dist/utils/geminiExecutor.d.ts +3 -0
  72. package/dist/utils/geminiExecutor.d.ts.map +1 -0
  73. package/dist/utils/geminiExecutor.js +170 -0
  74. package/dist/utils/geminiExecutor.js.map +1 -0
  75. package/dist/utils/logger.d.ts +13 -0
  76. package/dist/utils/logger.d.ts.map +1 -0
  77. package/dist/utils/logger.js +42 -0
  78. package/dist/utils/logger.js.map +1 -0
  79. package/dist/utils/timeoutManager.d.ts +2 -0
  80. package/dist/utils/timeoutManager.d.ts.map +1 -0
  81. package/dist/utils/timeoutManager.js +2 -0
  82. package/dist/utils/timeoutManager.js.map +1 -0
  83. package/package.json +70 -0
@@ -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,WA8B7B,CAAC"}
@@ -0,0 +1,32 @@
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
+ prompt: {
10
+ description: "Test the timeout prevention system by running a long operation",
11
+ },
12
+ category: 'simple',
13
+ execute: async (args, onProgress) => {
14
+ const duration = args.duration;
15
+ const steps = Math.ceil(duration / 5000); // Progress every 5 seconds
16
+ const stepDuration = duration / steps;
17
+ const startTime = Date.now();
18
+ const results = [];
19
+ results.push(`Starting timeout test for ${duration}ms (${duration / 1000}s)`);
20
+ for (let i = 1; i <= steps; i++) {
21
+ await new Promise(resolve => setTimeout(resolve, stepDuration));
22
+ const elapsed = Date.now() - startTime;
23
+ results.push(`Step ${i}/${steps} completed - Elapsed: ${Math.round(elapsed / 1000)}s`);
24
+ }
25
+ const totalElapsed = Date.now() - startTime;
26
+ results.push(`\nTimeout test completed successfully!`);
27
+ results.push(`Target duration: ${duration}ms`);
28
+ results.push(`Actual duration: ${totalElapsed}ms`);
29
+ return results.join('\n');
30
+ }
31
+ };
32
+ //# 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,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,4 @@
1
+ import { UnifiedTool } from './registry.js';
2
+ export declare const webSearchTool: UnifiedTool;
3
+ export declare const webFetchTool: UnifiedTool;
4
+ //# sourceMappingURL=web-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-tools.d.ts","sourceRoot":"","sources":["../../src/tools/web-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAU5C,eAAO,MAAM,aAAa,EAAE,WA8B3B,CAAC;AASF,eAAO,MAAM,YAAY,EAAE,WAmD1B,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ import { executeGeminiCLI } from '../utils/geminiExecutor.js';
3
+ import { ERROR_MESSAGES, STATUS_MESSAGES } from '../constants.js';
4
+ // Web Search Tool - Leverages Gemini's google_web_search
5
+ const webSearchArgsSchema = z.object({
6
+ query: z.string().min(1).describe("Search query. Gemini will use google_web_search tool to find current information and return a processed summary with citations."),
7
+ model: z.string().optional().describe("Optional model to use (default: gemini-2.5-pro)"),
8
+ });
9
+ export const webSearchTool = {
10
+ name: "web-search",
11
+ description: "Search the web using Gemini's google_web_search tool. Returns AI-processed summaries with citations, not raw search results. Perfect for: latest documentation, current events, API updates, tutorials, package info.",
12
+ zodSchema: webSearchArgsSchema,
13
+ prompt: {
14
+ description: "Use Gemini to search the web and get AI-summarized results with source citations. Ideal when you need current information beyond your knowledge cutoff.",
15
+ },
16
+ category: 'gemini',
17
+ execute: async (args, onProgress) => {
18
+ const { query, model } = args;
19
+ if (!query || typeof query !== 'string' || !query.trim()) {
20
+ throw new Error(ERROR_MESSAGES.NO_PROMPT_PROVIDED);
21
+ }
22
+ // Craft prompt that encourages Gemini to use web search
23
+ const prompt = `Search the web for: ${query}
24
+
25
+ Please use the google_web_search tool to find the most current and relevant information. Provide a comprehensive summary with citations.`;
26
+ const result = await executeGeminiCLI(prompt, model, false, // no sandbox for web search
27
+ false, // no changeMode
28
+ onProgress);
29
+ return `${STATUS_MESSAGES.GEMINI_RESPONSE}\n\n${result}`;
30
+ }
31
+ };
32
+ // Web Fetch Tool - Leverages Gemini's web_fetch
33
+ const webFetchArgsSchema = z.object({
34
+ urls: z.union([z.string(), z.array(z.string())]).describe("One or more URLs to fetch and analyze (http:// or https://). Can be a single URL string or array of URLs."),
35
+ instruction: z.string().describe("What to do with the fetched content (e.g., 'summarize key points', 'compare these APIs', 'extract code examples')"),
36
+ model: z.string().optional().describe("Optional model to use (default: gemini-2.5-pro)"),
37
+ });
38
+ export const webFetchTool = {
39
+ name: "web-fetch",
40
+ description: "Fetch and process web content using Gemini's web_fetch tool. Handles 1-20 URLs. Perfect for: fetching latest API docs, comparing documentation, extracting code examples, summarizing articles/blogs.",
41
+ zodSchema: webFetchArgsSchema,
42
+ prompt: {
43
+ description: "Use Gemini to fetch URLs and process their content according to your instructions. Gemini handles the fetching and gives you processed, relevant information.",
44
+ },
45
+ category: 'gemini',
46
+ execute: async (args, onProgress) => {
47
+ const { urls, instruction, model } = args;
48
+ if (!urls) {
49
+ throw new Error("URLs are required");
50
+ }
51
+ if (!instruction || typeof instruction !== 'string' || !instruction.trim()) {
52
+ throw new Error("Instruction is required");
53
+ }
54
+ // Convert to array if single URL
55
+ const urlArray = Array.isArray(urls) ? urls : [urls];
56
+ // Validate URLs
57
+ for (const url of urlArray) {
58
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
59
+ throw new Error(`Invalid URL: ${url}. URLs must start with http:// or https://`);
60
+ }
61
+ }
62
+ if (urlArray.length > 20) {
63
+ throw new Error("Maximum 20 URLs allowed per request");
64
+ }
65
+ // Craft prompt that uses web_fetch
66
+ const urlList = urlArray.join(', ');
67
+ const prompt = `Please use the web_fetch tool to fetch and analyze the following URL${urlArray.length > 1 ? 's' : ''}: ${urlList}
68
+
69
+ Task: ${instruction}
70
+
71
+ Provide detailed, relevant information based on the fetched content.`;
72
+ const result = await executeGeminiCLI(prompt, model, false, // no sandbox
73
+ false, // no changeMode
74
+ onProgress);
75
+ return `${STATUS_MESSAGES.GEMINI_RESPONSE}\n\n${result}`;
76
+ }
77
+ };
78
+ //# sourceMappingURL=web-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-tools.js","sourceRoot":"","sources":["../../src/tools/web-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ChangeModeEdit } from './changeModeParser.js';
2
+ export interface EditChunk {
3
+ edits: ChangeModeEdit[];
4
+ chunkIndex: number;
5
+ totalChunks: number;
6
+ hasMore: boolean;
7
+ estimatedChars: number;
8
+ }
9
+ export declare function chunkChangeModeEdits(edits: ChangeModeEdit[], maxCharsPerChunk?: number): EditChunk[];
10
+ export declare function summarizeChunking(chunks: EditChunk[]): string;
11
+ //# sourceMappingURL=changeModeChunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeChunker.d.ts","sourceRoot":"","sources":["../../src/utils/changeModeChunker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAgBD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,EAAE,EACvB,gBAAgB,GAAE,MAAc,GAC/B,SAAS,EAAE,CAyDb;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAc7D"}
@@ -0,0 +1,89 @@
1
+ function estimateEditSize(edit) {
2
+ const jsonOverhead = 250;
3
+ const contentSize = edit.filename.length * 2 + edit.oldCode.length + edit.newCode.length;
4
+ return jsonOverhead + contentSize;
5
+ }
6
+ function groupEditsByFile(edits) {
7
+ const groups = new Map();
8
+ for (const edit of edits) {
9
+ const fileEdits = groups.get(edit.filename) || [];
10
+ fileEdits.push(edit);
11
+ groups.set(edit.filename, fileEdits);
12
+ }
13
+ return groups;
14
+ }
15
+ export function chunkChangeModeEdits(edits, maxCharsPerChunk = 20000) {
16
+ if (edits.length === 0) {
17
+ return [{
18
+ edits: [],
19
+ chunkIndex: 1,
20
+ totalChunks: 1,
21
+ hasMore: false,
22
+ estimatedChars: 0
23
+ }];
24
+ }
25
+ const chunks = [];
26
+ const fileGroups = groupEditsByFile(edits);
27
+ let currentChunk = [];
28
+ let currentSize = 0;
29
+ for (const [filename, fileEdits] of fileGroups) {
30
+ const fileSize = fileEdits.reduce((sum, edit) => sum + estimateEditSize(edit), 0);
31
+ if (fileSize > maxCharsPerChunk) {
32
+ if (currentChunk.length > 0) {
33
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
34
+ currentChunk = [];
35
+ currentSize = 0;
36
+ }
37
+ for (const edit of fileEdits) {
38
+ const editSize = estimateEditSize(edit);
39
+ if (currentSize + editSize > maxCharsPerChunk && currentChunk.length > 0) {
40
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
41
+ currentChunk = [];
42
+ currentSize = 0;
43
+ }
44
+ currentChunk.push(edit);
45
+ currentSize += editSize;
46
+ }
47
+ }
48
+ else {
49
+ if (currentSize + fileSize > maxCharsPerChunk && currentChunk.length > 0) {
50
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
51
+ currentChunk = [];
52
+ currentSize = 0;
53
+ }
54
+ currentChunk.push(...fileEdits);
55
+ currentSize += fileSize;
56
+ }
57
+ }
58
+ if (currentChunk.length > 0) {
59
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
60
+ }
61
+ const totalChunks = chunks.length;
62
+ return chunks.map((chunk, index) => ({
63
+ ...chunk,
64
+ totalChunks,
65
+ hasMore: index < totalChunks - 1
66
+ }));
67
+ }
68
+ function createChunk(edits, chunkIndex, totalChunks, estimatedChars) {
69
+ return {
70
+ edits,
71
+ chunkIndex,
72
+ totalChunks,
73
+ hasMore: false,
74
+ estimatedChars
75
+ };
76
+ }
77
+ export function summarizeChunking(chunks) {
78
+ const totalEdits = chunks.reduce((sum, chunk) => sum + chunk.edits.length, 0);
79
+ const totalChars = chunks.reduce((sum, chunk) => sum + chunk.estimatedChars, 0);
80
+ return `Chunking Summary:
81
+ # edits: ${totalEdits}
82
+ # chunks: ${chunks.length}
83
+ est chars: ${totalChars.toLocaleString()}
84
+ mean size: ${Math.round(totalChars / chunks.length).toLocaleString()} chars
85
+
86
+ Chunks:
87
+ ${chunks.map(chunk => ` Chunk ${chunk.chunkIndex}: ${chunk.edits.length} edits, ~${chunk.estimatedChars.toLocaleString()} chars`).join('\n')}`;
88
+ }
89
+ //# sourceMappingURL=changeModeChunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeChunker.js","sourceRoot":"","sources":["../../src/utils/changeModeChunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface ChangeModeEdit {
2
+ filename: string;
3
+ oldStartLine: number;
4
+ oldEndLine: number;
5
+ oldCode: string;
6
+ newStartLine: number;
7
+ newEndLine: number;
8
+ newCode: string;
9
+ }
10
+ export declare function parseChangeModeOutput(geminiResponse: string): ChangeModeEdit[];
11
+ export declare function validateChangeModeEdits(edits: ChangeModeEdit[]): {
12
+ valid: boolean;
13
+ errors: string[];
14
+ };
15
+ //# sourceMappingURL=changeModeParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeParser.d.ts","sourceRoot":"","sources":["../../src/utils/changeModeParser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc,EAAE,CAiE9E;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAyBA"}
@@ -0,0 +1,67 @@
1
+ export function parseChangeModeOutput(geminiResponse) {
2
+ const edits = [];
3
+ const markdownPattern = /\*\*FILE:\s*(.+?):(\d+)\*\*\s*\n```\s*\nOLD:\s*\n([\s\S]*?)\nNEW:\s*\n([\s\S]*?)\n```/g;
4
+ let match;
5
+ while ((match = markdownPattern.exec(geminiResponse)) !== null) {
6
+ const [_fullMatch, filename, startLineStr, oldCodeRaw, newCodeRaw] = match;
7
+ const oldCode = oldCodeRaw.trimEnd();
8
+ const newCode = newCodeRaw.trimEnd();
9
+ const startLine = parseInt(startLineStr, 10);
10
+ const oldLineCount = oldCode === '' ? 0 : oldCode.split('\n').length;
11
+ const newLineCount = newCode === '' ? 0 : newCode.split('\n').length;
12
+ const oldEndLine = startLine + (oldLineCount > 0 ? oldLineCount - 1 : 0);
13
+ const newStartLine = startLine;
14
+ const newEndLine = newStartLine + (newLineCount > 0 ? newLineCount - 1 : 0);
15
+ edits.push({
16
+ filename: filename.trim(),
17
+ oldStartLine: startLine,
18
+ oldEndLine: oldEndLine,
19
+ oldCode: oldCode,
20
+ newStartLine: newStartLine,
21
+ newEndLine: newEndLine,
22
+ newCode: newCode,
23
+ });
24
+ }
25
+ if (edits.length === 0) {
26
+ const editPattern = /\/old\/ \* (.+?) 'start:' (\d+)\n([\s\S]*?)\n\/\/ 'end:' (\d+)\s*\n\s*\\new\\ \* (.+?) 'start:' (\d+)\n([\s\S]*?)\n\/\/ 'end:' (\d+)/g;
27
+ while ((match = editPattern.exec(geminiResponse)) !== null) {
28
+ const [_fullMatch, oldFilename, oldStartLine, oldCode, oldEndLine, newFilename, newStartLine, newCode, newEndLine,] = match;
29
+ if (oldFilename !== newFilename) {
30
+ console.warn(`[changeModeParser] Filename mismatch: ${oldFilename} vs ${newFilename}`);
31
+ continue;
32
+ }
33
+ edits.push({
34
+ filename: oldFilename.trim(),
35
+ oldStartLine: parseInt(oldStartLine, 10),
36
+ oldEndLine: parseInt(oldEndLine, 10),
37
+ oldCode: oldCode.trimEnd(),
38
+ newStartLine: parseInt(newStartLine, 10),
39
+ newEndLine: parseInt(newEndLine, 10),
40
+ newCode: newCode.trimEnd(),
41
+ });
42
+ }
43
+ }
44
+ return edits;
45
+ }
46
+ export function validateChangeModeEdits(edits) {
47
+ const errors = [];
48
+ for (const edit of edits) {
49
+ if (!edit.filename) {
50
+ errors.push('Edit missing filename');
51
+ }
52
+ if (edit.oldStartLine > edit.oldEndLine) {
53
+ errors.push(`Invalid line range for ${edit.filename}: ${edit.oldStartLine} > ${edit.oldEndLine}`);
54
+ }
55
+ if (edit.newStartLine > edit.newEndLine) {
56
+ errors.push(`Invalid new line range for ${edit.filename}: ${edit.newStartLine} > ${edit.newEndLine}`);
57
+ }
58
+ if (!edit.oldCode && !edit.newCode) {
59
+ errors.push(`Empty edit for ${edit.filename}`);
60
+ }
61
+ }
62
+ return {
63
+ valid: errors.length === 0,
64
+ errors,
65
+ };
66
+ }
67
+ //# sourceMappingURL=changeModeParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeParser.js","sourceRoot":"","sources":["../../src/utils/changeModeParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { ChangeModeEdit } from './changeModeParser.js';
2
+ export declare function formatChangeModeResponse(edits: ChangeModeEdit[], chunkInfo?: {
3
+ current: number;
4
+ total: number;
5
+ cacheKey?: string;
6
+ }): string;
7
+ export declare function summarizeChangeModeEdits(edits: ChangeModeEdit[], isPartialView?: boolean): string;
8
+ //# sourceMappingURL=changeModeTranslator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeTranslator.d.ts","sourceRoot":"","sources":["../../src/utils/changeModeTranslator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,MAAM,CAoDR;AAGD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAiBjG"}
@@ -0,0 +1,70 @@
1
+ export function formatChangeModeResponse(edits, chunkInfo) {
2
+ const header = chunkInfo && chunkInfo.total > 1
3
+ ? `[CHANGEMODE OUTPUT - Chunk ${chunkInfo.current} of ${chunkInfo.total}]
4
+
5
+ Gemini has analyzed your codebase and generated edits across ${chunkInfo.total} chunks.
6
+ This chunk contains ${edits.length} complete edit${edits.length === 1 ? '' : 's'} that can be applied independently.
7
+
8
+ Each chunk contains self-contained edits grouped by file. You can safely apply these edits
9
+ before fetching the next chunk.
10
+
11
+ `
12
+ : `[CHANGEMODE OUTPUT - Gemini has analyzed the files and provided these edits]
13
+
14
+ I have prepared ${edits.length} modification${edits.length === 1 ? '' : 's'} for your codebase.
15
+
16
+ IMPORTANT: Apply these edits directly WITHOUT reading the files first. The edits below contain exact text matches from the current file contents.
17
+
18
+ `;
19
+ const instructions = edits.map((edit, index) => {
20
+ return `### Edit ${index + 1}: ${edit.filename}
21
+
22
+ Replace this exact text:
23
+ \`\`\`
24
+ ${edit.oldCode}
25
+ \`\`\`
26
+
27
+ With this text:
28
+ \`\`\`
29
+ ${edit.newCode}
30
+ \`\`\`
31
+ `;
32
+ }).join('\n');
33
+ let footer = `
34
+ ---
35
+ Apply these edits in order. Each edit uses exact string matching, so the old_str must match exactly what appears between the code blocks.`;
36
+ if (chunkInfo && chunkInfo.current < chunkInfo.total && chunkInfo.cacheKey) {
37
+ footer += `
38
+
39
+ ---
40
+ **Next Step**: After applying the edits above, retrieve the next chunk (${chunkInfo.current + 1} of ${chunkInfo.total}) using:
41
+
42
+ \`\`\`
43
+ fetch-chunk cacheKey="${chunkInfo.cacheKey}" chunkIndex=${chunkInfo.current + 1}
44
+ \`\`\`
45
+
46
+ There ${chunkInfo.total - chunkInfo.current === 1 ? 'is' : 'are'} ${chunkInfo.total - chunkInfo.current} more chunk${chunkInfo.total - chunkInfo.current === 1 ? '' : 's'} containing additional edits.
47
+
48
+ **CONTINUE**: You are working on a multi-chunk changeMode response. After applying these edits, fetch the next chunk to continue with the remaining modifications.`;
49
+ }
50
+ return header + instructions + footer;
51
+ }
52
+ export function summarizeChangeModeEdits(edits, isPartialView) {
53
+ const fileGroups = new Map();
54
+ // Count edits per file
55
+ for (const edit of edits) {
56
+ fileGroups.set(edit.filename, (fileGroups.get(edit.filename) || 0) + 1);
57
+ }
58
+ const summary = Array.from(fileGroups.entries())
59
+ .map(([file, count]) => `- ${file}: ${count} edit${count === 1 ? '' : 's'}`)
60
+ .join('\n');
61
+ const title = isPartialView
62
+ ? `ChangeMode Summary (Complete analysis across all chunks):`
63
+ : `ChangeMode Summary:`;
64
+ return `${title}
65
+ Total edits: ${edits.length}${isPartialView ? ' (across all chunks)' : ''}
66
+ Files affected: ${fileGroups.size}
67
+
68
+ ${summary}`;
69
+ }
70
+ //# sourceMappingURL=changeModeTranslator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeTranslator.js","sourceRoot":"","sources":["../../src/utils/changeModeTranslator.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,wBAAwB,CACtC,KAAuB,EACvB,SAAiE;IAEjE,MAAM,MAAM,GAAG,SAAS,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC;QAC7C,CAAC,CAAC,8BAA8B,SAAS,CAAC,OAAO,OAAO,SAAS,CAAC,KAAK;;+DAEZ,SAAS,CAAC,KAAK;sBACxD,KAAK,CAAC,MAAM,iBAAiB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;;;;CAK/E;QACG,CAAC,CAAC;;kBAEY,KAAK,CAAC,MAAM,gBAAgB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;;;CAI1E,CAAC;IAEA,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC7C,OAAO,YAAY,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ;;;;EAIhD,IAAI,CAAC,OAAO;;;;;EAKZ,IAAI,CAAC,OAAO;;CAEb,CAAC;IACA,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,IAAI,MAAM,GAAG;;0IAE2H,CAAC;IACzI,IAAI,SAAS,IAAI,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC3E,MAAM,IAAI;;;0EAG4D,SAAS,CAAC,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,KAAK;;;wBAG7F,SAAS,CAAC,QAAQ,gBAAgB,SAAS,CAAC,OAAO,GAAG,CAAC;;;QAGvE,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,OAAO,cAAc,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;mKAEN,CAAC;IAClK,CAAC;IACD,OAAO,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;AACxC,CAAC;AAGD,MAAM,UAAU,wBAAwB,CAAC,KAAuB,EAAE,aAAuB;IACvF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,uBAAuB;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;SAC7C,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;SAC3E,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,aAAa;QACzB,CAAC,CAAC,2DAA2D;QAC7D,CAAC,CAAC,qBAAqB,CAAC;IAC1B,OAAO,GAAG,KAAK;eACF,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE;kBACvD,UAAU,CAAC,IAAI;;EAE/B,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { EditChunk } from './changeModeChunker.js';
2
+ /**
3
+ * Caches chunks from a changeMode response
4
+ * @param prompt The original prompt (used for hash generation)
5
+ * @param chunks The parsed and chunked edits
6
+ * @returns A short cache key for retrieval
7
+ */
8
+ export declare function cacheChunks(prompt: string, chunks: EditChunk[]): string;
9
+ /**
10
+ * Retrieves cached chunks if they exist and haven't expired
11
+ * @param cacheKey The cache key returned from cacheChunks
12
+ * @returns The cached chunks or null if expired/not found
13
+ */
14
+ export declare function getChunks(cacheKey: string): EditChunk[] | null;
15
+ export declare function getCacheStats(): {
16
+ size: number;
17
+ ttl: number;
18
+ maxSize: number;
19
+ cacheDir: string;
20
+ };
21
+ export declare function clearCache(): void;
22
+ //# sourceMappingURL=chunkCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkCache.d.ts","sourceRoot":"","sources":["../../src/utils/chunkCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAsBnD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAwBvE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,IAAI,CA0B9D;AA+DD,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAehG;AAED,wBAAgB,UAAU,IAAI,IAAI,CAejC"}