@joeytheman/gemini-mcp-tool 1.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.
Files changed (123) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +239 -0
  3. package/dist/__tests__/ask-gemini.test.d.ts +2 -0
  4. package/dist/__tests__/ask-gemini.test.d.ts.map +1 -0
  5. package/dist/__tests__/ask-gemini.test.js +165 -0
  6. package/dist/__tests__/ask-gemini.test.js.map +1 -0
  7. package/dist/__tests__/server.test.d.ts +2 -0
  8. package/dist/__tests__/server.test.d.ts.map +1 -0
  9. package/dist/__tests__/server.test.js +72 -0
  10. package/dist/__tests__/server.test.js.map +1 -0
  11. package/dist/__tests__/tools.test.d.ts +2 -0
  12. package/dist/__tests__/tools.test.d.ts.map +1 -0
  13. package/dist/__tests__/tools.test.js +131 -0
  14. package/dist/__tests__/tools.test.js.map +1 -0
  15. package/dist/__tests__/utils/changeModeChunker.test.d.ts +2 -0
  16. package/dist/__tests__/utils/changeModeChunker.test.d.ts.map +1 -0
  17. package/dist/__tests__/utils/changeModeChunker.test.js +137 -0
  18. package/dist/__tests__/utils/changeModeChunker.test.js.map +1 -0
  19. package/dist/__tests__/utils/changeModeParser.test.d.ts +2 -0
  20. package/dist/__tests__/utils/changeModeParser.test.d.ts.map +1 -0
  21. package/dist/__tests__/utils/changeModeParser.test.js +254 -0
  22. package/dist/__tests__/utils/changeModeParser.test.js.map +1 -0
  23. package/dist/__tests__/utils/changeModeTranslator.test.d.ts +2 -0
  24. package/dist/__tests__/utils/changeModeTranslator.test.d.ts.map +1 -0
  25. package/dist/__tests__/utils/changeModeTranslator.test.js +112 -0
  26. package/dist/__tests__/utils/changeModeTranslator.test.js.map +1 -0
  27. package/dist/__tests__/utils/chunkCache.test.d.ts +2 -0
  28. package/dist/__tests__/utils/chunkCache.test.d.ts.map +1 -0
  29. package/dist/__tests__/utils/chunkCache.test.js +140 -0
  30. package/dist/__tests__/utils/chunkCache.test.js.map +1 -0
  31. package/dist/__tests__/utils/commandExecutor.test.d.ts +2 -0
  32. package/dist/__tests__/utils/commandExecutor.test.d.ts.map +1 -0
  33. package/dist/__tests__/utils/commandExecutor.test.js +139 -0
  34. package/dist/__tests__/utils/commandExecutor.test.js.map +1 -0
  35. package/dist/__tests__/utils/geminiExecutor.test.d.ts +2 -0
  36. package/dist/__tests__/utils/geminiExecutor.test.d.ts.map +1 -0
  37. package/dist/__tests__/utils/geminiExecutor.test.js +337 -0
  38. package/dist/__tests__/utils/geminiExecutor.test.js.map +1 -0
  39. package/dist/__tests__/utils/responseCache.test.d.ts +2 -0
  40. package/dist/__tests__/utils/responseCache.test.d.ts.map +1 -0
  41. package/dist/__tests__/utils/responseCache.test.js +98 -0
  42. package/dist/__tests__/utils/responseCache.test.js.map +1 -0
  43. package/dist/__tests__/utils/test-helpers.d.ts +17 -0
  44. package/dist/__tests__/utils/test-helpers.d.ts.map +1 -0
  45. package/dist/__tests__/utils/test-helpers.js +50 -0
  46. package/dist/__tests__/utils/test-helpers.js.map +1 -0
  47. package/dist/constants.d.ts +96 -0
  48. package/dist/constants.d.ts.map +1 -0
  49. package/dist/constants.js +89 -0
  50. package/dist/constants.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +186 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/tools/ask-gemini.tool.d.ts +3 -0
  56. package/dist/tools/ask-gemini.tool.d.ts.map +1 -0
  57. package/dist/tools/ask-gemini.tool.js +65 -0
  58. package/dist/tools/ask-gemini.tool.js.map +1 -0
  59. package/dist/tools/brainstorm.tool.d.ts +3 -0
  60. package/dist/tools/brainstorm.tool.d.ts.map +1 -0
  61. package/dist/tools/brainstorm.tool.js +147 -0
  62. package/dist/tools/brainstorm.tool.js.map +1 -0
  63. package/dist/tools/fetch-chunk.tool.d.ts +3 -0
  64. package/dist/tools/fetch-chunk.tool.d.ts.map +1 -0
  65. package/dist/tools/fetch-chunk.tool.js +67 -0
  66. package/dist/tools/fetch-chunk.tool.js.map +1 -0
  67. package/dist/tools/index.d.ts +2 -0
  68. package/dist/tools/index.d.ts.map +1 -0
  69. package/dist/tools/index.js +10 -0
  70. package/dist/tools/index.js.map +1 -0
  71. package/dist/tools/registry.d.ts +43 -0
  72. package/dist/tools/registry.d.ts.map +1 -0
  73. package/dist/tools/registry.js +81 -0
  74. package/dist/tools/registry.js.map +1 -0
  75. package/dist/tools/simple-tools.d.ts +4 -0
  76. package/dist/tools/simple-tools.d.ts.map +1 -0
  77. package/dist/tools/simple-tools.js +42 -0
  78. package/dist/tools/simple-tools.js.map +1 -0
  79. package/dist/tools/test-tool.example.d.ts +13 -0
  80. package/dist/tools/test-tool.example.d.ts.map +1 -0
  81. package/dist/tools/test-tool.example.js +32 -0
  82. package/dist/tools/test-tool.example.js.map +1 -0
  83. package/dist/tools/timeout-test.tool.d.ts +3 -0
  84. package/dist/tools/timeout-test.tool.d.ts.map +1 -0
  85. package/dist/tools/timeout-test.tool.js +36 -0
  86. package/dist/tools/timeout-test.tool.js.map +1 -0
  87. package/dist/utils/changeModeChunker.d.ts +11 -0
  88. package/dist/utils/changeModeChunker.d.ts.map +1 -0
  89. package/dist/utils/changeModeChunker.js +89 -0
  90. package/dist/utils/changeModeChunker.js.map +1 -0
  91. package/dist/utils/changeModeParser.d.ts +15 -0
  92. package/dist/utils/changeModeParser.d.ts.map +1 -0
  93. package/dist/utils/changeModeParser.js +67 -0
  94. package/dist/utils/changeModeParser.js.map +1 -0
  95. package/dist/utils/changeModeTranslator.d.ts +8 -0
  96. package/dist/utils/changeModeTranslator.d.ts.map +1 -0
  97. package/dist/utils/changeModeTranslator.js +70 -0
  98. package/dist/utils/changeModeTranslator.js.map +1 -0
  99. package/dist/utils/chunkCache.d.ts +22 -0
  100. package/dist/utils/chunkCache.d.ts.map +1 -0
  101. package/dist/utils/chunkCache.js +161 -0
  102. package/dist/utils/chunkCache.js.map +1 -0
  103. package/dist/utils/commandExecutor.d.ts +2 -0
  104. package/dist/utils/commandExecutor.d.ts.map +1 -0
  105. package/dist/utils/commandExecutor.js +79 -0
  106. package/dist/utils/commandExecutor.js.map +1 -0
  107. package/dist/utils/geminiExecutor.d.ts +17 -0
  108. package/dist/utils/geminiExecutor.d.ts.map +1 -0
  109. package/dist/utils/geminiExecutor.js +238 -0
  110. package/dist/utils/geminiExecutor.js.map +1 -0
  111. package/dist/utils/logger.d.ts +13 -0
  112. package/dist/utils/logger.d.ts.map +1 -0
  113. package/dist/utils/logger.js +42 -0
  114. package/dist/utils/logger.js.map +1 -0
  115. package/dist/utils/responseCache.d.ts +33 -0
  116. package/dist/utils/responseCache.d.ts.map +1 -0
  117. package/dist/utils/responseCache.js +87 -0
  118. package/dist/utils/responseCache.js.map +1 -0
  119. package/dist/utils/timeoutManager.d.ts +2 -0
  120. package/dist/utils/timeoutManager.d.ts.map +1 -0
  121. package/dist/utils/timeoutManager.js +2 -0
  122. package/dist/utils/timeoutManager.js.map +1 -0
  123. package/package.json +79 -0
@@ -0,0 +1,10 @@
1
+ // Tool Registry Index - Registers all tools
2
+ import { toolRegistry } from './registry.js';
3
+ import { askGeminiTool } from './ask-gemini.tool.js';
4
+ import { pingTool, helpTool } from './simple-tools.js';
5
+ import { brainstormTool } from './brainstorm.tool.js';
6
+ import { fetchChunkTool } from './fetch-chunk.tool.js';
7
+ import { timeoutTestTool } from './timeout-test.tool.js';
8
+ toolRegistry.push(askGeminiTool, pingTool, helpTool, brainstormTool, fetchChunkTool, timeoutTestTool);
9
+ export * from './registry.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,YAAY,CAAC,IAAI,CACf,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,CAChB,CAAC;AAEF,cAAc,eAAe,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { Tool, Prompt } from "@modelcontextprotocol/sdk/types.js";
2
+ import { ToolArguments } from "../constants.js";
3
+ import { ZodTypeAny } from "zod";
4
+ /**
5
+ * MCP Tool annotations per specification.
6
+ * @see https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations
7
+ */
8
+ export interface ToolAnnotations {
9
+ /** Human-readable title for the tool */
10
+ title?: string;
11
+ /** If true, the tool does not modify its environment */
12
+ readOnlyHint?: boolean;
13
+ /** If true, the tool may perform destructive updates */
14
+ destructiveHint?: boolean;
15
+ /** If true, repeated calls with same args have no additional effect */
16
+ idempotentHint?: boolean;
17
+ /** If true, the tool interacts with external entities */
18
+ openWorldHint?: boolean;
19
+ }
20
+ export interface UnifiedTool {
21
+ name: string;
22
+ description: string;
23
+ zodSchema: ZodTypeAny;
24
+ prompt?: {
25
+ description: string;
26
+ arguments?: Array<{
27
+ name: string;
28
+ description: string;
29
+ required: boolean;
30
+ }>;
31
+ };
32
+ execute: (args: ToolArguments, onProgress?: (newOutput: string) => void) => Promise<string>;
33
+ category?: 'simple' | 'gemini' | 'utility';
34
+ /** MCP tool annotations for AI assistants */
35
+ annotations?: ToolAnnotations;
36
+ }
37
+ export declare const toolRegistry: UnifiedTool[];
38
+ export declare function toolExists(toolName: string): boolean;
39
+ export declare function getToolDefinitions(): Tool[];
40
+ export declare function getPromptDefinitions(): Prompt[];
41
+ export declare function executeTool(toolName: string, args: ToolArguments, onProgress?: (newOutput: string) => void): Promise<string>;
42
+ export declare function getPromptMessage(toolName: string, args: Record<string, any>): string;
43
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAY,MAAM,KAAK,CAAC;AAG3C;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wDAAwD;IACxD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC;IAEtB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,KAAK,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC,CAAC;KACJ,CAAC;IAEF,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC3C,6CAA6C;IAC7C,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,WAAW,EAAO,CAAC;AAC9C,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AACD,wBAAgB,kBAAkB,IAAI,IAAI,EAAE,CAiB3C;AAcD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAQ/C;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlI;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAsBpF"}
@@ -0,0 +1,81 @@
1
+ import { ZodError } from "zod";
2
+ import { zodToJsonSchema } from "zod-to-json-schema";
3
+ export const toolRegistry = [];
4
+ export function toolExists(toolName) {
5
+ return toolRegistry.some(t => t.name === toolName);
6
+ }
7
+ export function getToolDefinitions() {
8
+ return toolRegistry.map(tool => {
9
+ const raw = zodToJsonSchema(tool.zodSchema, tool.name);
10
+ const def = raw.definitions?.[tool.name] ?? raw;
11
+ const inputSchema = {
12
+ type: "object",
13
+ properties: def.properties || {},
14
+ required: def.required || [],
15
+ };
16
+ return {
17
+ name: tool.name,
18
+ description: tool.description,
19
+ inputSchema,
20
+ annotations: tool.annotations,
21
+ };
22
+ });
23
+ }
24
+ function extractPromptArguments(zodSchema) {
25
+ const jsonSchema = zodToJsonSchema(zodSchema);
26
+ const properties = jsonSchema.properties || {};
27
+ const required = jsonSchema.required || [];
28
+ return Object.entries(properties).map(([name, prop]) => ({
29
+ name,
30
+ description: prop.description || `${name} parameter`,
31
+ required: required.includes(name)
32
+ }));
33
+ }
34
+ export function getPromptDefinitions() {
35
+ return toolRegistry
36
+ .filter(tool => tool.prompt)
37
+ .map(tool => ({
38
+ name: tool.name,
39
+ description: tool.prompt.description,
40
+ arguments: tool.prompt.arguments || extractPromptArguments(tool.zodSchema),
41
+ }));
42
+ }
43
+ export async function executeTool(toolName, args, onProgress) {
44
+ const tool = toolRegistry.find(t => t.name === toolName);
45
+ if (!tool) {
46
+ throw new Error(`Unknown tool: ${toolName}`);
47
+ }
48
+ try {
49
+ const validatedArgs = tool.zodSchema.parse(args);
50
+ return tool.execute(validatedArgs, onProgress);
51
+ }
52
+ catch (error) {
53
+ if (error instanceof ZodError) {
54
+ const issues = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join(', ');
55
+ throw new Error(`Invalid arguments for ${toolName}: ${issues}`);
56
+ }
57
+ throw error;
58
+ }
59
+ }
60
+ export function getPromptMessage(toolName, args) {
61
+ const tool = toolRegistry.find(t => t.name === toolName);
62
+ if (!tool?.prompt) {
63
+ throw new Error(`No prompt defined for tool: ${toolName}`);
64
+ }
65
+ const paramStrings = [];
66
+ if (args.prompt) {
67
+ paramStrings.push(args.prompt);
68
+ }
69
+ Object.entries(args).forEach(([key, value]) => {
70
+ if (key !== 'prompt' && value !== undefined && value !== null && value !== false) {
71
+ if (typeof value === 'boolean' && value) {
72
+ paramStrings.push(`[${key}]`);
73
+ }
74
+ else if (typeof value !== 'boolean') {
75
+ paramStrings.push(`(${key}: ${value})`);
76
+ }
77
+ }
78
+ });
79
+ return `Use the ${toolName} tool${paramStrings.length > 0 ? ': ' + paramStrings.join(' ') : ''}`;
80
+ }
81
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { UnifiedTool } from './registry.js';
2
+ export declare const pingTool: UnifiedTool;
3
+ export declare const helpTool: UnifiedTool;
4
+ //# sourceMappingURL=simple-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-tools.d.ts","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,eAAO,MAAM,QAAQ,EAAE,WAiBtB,CAAC;AAIF,eAAO,MAAM,QAAQ,EAAE,WAgBtB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ import { executeCommand } from '../utils/commandExecutor.js';
3
+ const pingArgsSchema = z.object({
4
+ prompt: z.string().default('').describe("Message to echo "),
5
+ });
6
+ export const pingTool = {
7
+ name: "ping",
8
+ description: "Echo",
9
+ zodSchema: pingArgsSchema,
10
+ prompt: {
11
+ description: "Echo test message with structured response.",
12
+ },
13
+ category: 'simple',
14
+ annotations: {
15
+ title: "Ping",
16
+ readOnlyHint: true,
17
+ idempotentHint: true,
18
+ },
19
+ execute: async (args, onProgress) => {
20
+ const message = args.prompt || args.message || "Pong!";
21
+ return executeCommand("echo", [message], onProgress);
22
+ }
23
+ };
24
+ const helpArgsSchema = z.object({});
25
+ export const helpTool = {
26
+ name: "Help",
27
+ description: "receive help information",
28
+ zodSchema: helpArgsSchema,
29
+ prompt: {
30
+ description: "receive help information",
31
+ },
32
+ category: 'simple',
33
+ annotations: {
34
+ title: "Help",
35
+ readOnlyHint: true,
36
+ openWorldHint: true,
37
+ },
38
+ execute: async (args, onProgress) => {
39
+ return executeCommand("gemini", ["-help"], onProgress);
40
+ }
41
+ };
42
+ //# sourceMappingURL=simple-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-tools.js","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,MAAM;IACnB,SAAS,EAAE,cAAc;IACzB,MAAM,EAAE;QACN,WAAW,EAAE,6CAA6C;KAC3D;IACD,QAAQ,EAAE,QAAQ;IAClB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM;QACb,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,IAAI;KACrB;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;QACvD,OAAO,cAAc,CAAC,MAAM,EAAE,CAAC,OAAiB,CAAC,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC;CACF,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEpC,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,0BAA0B;IACvC,SAAS,EAAE,cAAc;IACzB,MAAM,EAAE;QACN,WAAW,EAAE,0BAA0B;KACxC;IACD,QAAQ,EAAE,QAAQ;IAClB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM;QACb,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,IAAI;KACpB;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,OAAO,cAAc,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;CACF,CAAC"}
@@ -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,WAkC7B,CAAC"}
@@ -0,0 +1,36 @@
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
+ annotations: {
14
+ title: "Timeout Test",
15
+ readOnlyHint: true,
16
+ },
17
+ execute: async (args, onProgress) => {
18
+ const duration = args.duration;
19
+ const steps = Math.ceil(duration / 5000); // Progress every 5 seconds
20
+ const stepDuration = duration / steps;
21
+ const startTime = Date.now();
22
+ const results = [];
23
+ results.push(`Starting timeout test for ${duration}ms (${duration / 1000}s)`);
24
+ for (let i = 1; i <= steps; i++) {
25
+ await new Promise(resolve => setTimeout(resolve, stepDuration));
26
+ const elapsed = Date.now() - startTime;
27
+ results.push(`Step ${i}/${steps} completed - Elapsed: ${Math.round(elapsed / 1000)}s`);
28
+ }
29
+ const totalElapsed = Date.now() - startTime;
30
+ results.push(`\nTimeout test completed successfully!`);
31
+ results.push(`Target duration: ${duration}ms`);
32
+ results.push(`Actual duration: ${totalElapsed}ms`);
33
+ return results.join('\n');
34
+ }
35
+ };
36
+ //# 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,WAAW,EAAE;QACX,KAAK,EAAE,cAAc;QACrB,YAAY,EAAE,IAAI;KACnB;IACD,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,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"}