@maxanatsko/gemini-mcp-tool 2.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 (119) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +230 -0
  3. package/dist/constants.d.ts +153 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +150 -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 +188 -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 +74 -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 +202 -0
  18. package/dist/tools/brainstorm.tool.js.map +1 -0
  19. package/dist/tools/fetch-chunk.tool.d.ts +3 -0
  20. package/dist/tools/fetch-chunk.tool.d.ts.map +1 -0
  21. package/dist/tools/fetch-chunk.tool.js +62 -0
  22. package/dist/tools/fetch-chunk.tool.js.map +1 -0
  23. package/dist/tools/index.d.ts +2 -0
  24. package/dist/tools/index.d.ts.map +1 -0
  25. package/dist/tools/index.js +11 -0
  26. package/dist/tools/index.js.map +1 -0
  27. package/dist/tools/registry.d.ts +25 -0
  28. package/dist/tools/registry.d.ts.map +1 -0
  29. package/dist/tools/registry.js +80 -0
  30. package/dist/tools/registry.js.map +1 -0
  31. package/dist/tools/review-code.tool.d.ts +3 -0
  32. package/dist/tools/review-code.tool.d.ts.map +1 -0
  33. package/dist/tools/review-code.tool.js +186 -0
  34. package/dist/tools/review-code.tool.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/utils/askGeminiSessionManager.d.ts +57 -0
  48. package/dist/utils/askGeminiSessionManager.d.ts.map +1 -0
  49. package/dist/utils/askGeminiSessionManager.js +110 -0
  50. package/dist/utils/askGeminiSessionManager.js.map +1 -0
  51. package/dist/utils/brainstormSessionManager.d.ts +67 -0
  52. package/dist/utils/brainstormSessionManager.d.ts.map +1 -0
  53. package/dist/utils/brainstormSessionManager.js +165 -0
  54. package/dist/utils/brainstormSessionManager.js.map +1 -0
  55. package/dist/utils/changeModeChunker.d.ts +11 -0
  56. package/dist/utils/changeModeChunker.d.ts.map +1 -0
  57. package/dist/utils/changeModeChunker.js +89 -0
  58. package/dist/utils/changeModeChunker.js.map +1 -0
  59. package/dist/utils/changeModeParser.d.ts +15 -0
  60. package/dist/utils/changeModeParser.d.ts.map +1 -0
  61. package/dist/utils/changeModeParser.js +67 -0
  62. package/dist/utils/changeModeParser.js.map +1 -0
  63. package/dist/utils/changeModeTranslator.d.ts +8 -0
  64. package/dist/utils/changeModeTranslator.d.ts.map +1 -0
  65. package/dist/utils/changeModeTranslator.js +70 -0
  66. package/dist/utils/changeModeTranslator.js.map +1 -0
  67. package/dist/utils/chunkCache.d.ts +22 -0
  68. package/dist/utils/chunkCache.d.ts.map +1 -0
  69. package/dist/utils/chunkCache.js +161 -0
  70. package/dist/utils/chunkCache.js.map +1 -0
  71. package/dist/utils/commandExecutor.d.ts +2 -0
  72. package/dist/utils/commandExecutor.d.ts.map +1 -0
  73. package/dist/utils/commandExecutor.js +74 -0
  74. package/dist/utils/commandExecutor.js.map +1 -0
  75. package/dist/utils/geminiExecutor.d.ts +3 -0
  76. package/dist/utils/geminiExecutor.d.ts.map +1 -0
  77. package/dist/utils/geminiExecutor.js +170 -0
  78. package/dist/utils/geminiExecutor.js.map +1 -0
  79. package/dist/utils/gitStateDetector.d.ts +31 -0
  80. package/dist/utils/gitStateDetector.d.ts.map +1 -0
  81. package/dist/utils/gitStateDetector.js +67 -0
  82. package/dist/utils/gitStateDetector.js.map +1 -0
  83. package/dist/utils/logger.d.ts +13 -0
  84. package/dist/utils/logger.d.ts.map +1 -0
  85. package/dist/utils/logger.js +42 -0
  86. package/dist/utils/logger.js.map +1 -0
  87. package/dist/utils/reviewFormatter.d.ts +35 -0
  88. package/dist/utils/reviewFormatter.d.ts.map +1 -0
  89. package/dist/utils/reviewFormatter.js +198 -0
  90. package/dist/utils/reviewFormatter.js.map +1 -0
  91. package/dist/utils/reviewPromptBuilder.d.ts +35 -0
  92. package/dist/utils/reviewPromptBuilder.d.ts.map +1 -0
  93. package/dist/utils/reviewPromptBuilder.js +146 -0
  94. package/dist/utils/reviewPromptBuilder.js.map +1 -0
  95. package/dist/utils/reviewResponseParser.d.ts +20 -0
  96. package/dist/utils/reviewResponseParser.d.ts.map +1 -0
  97. package/dist/utils/reviewResponseParser.js +149 -0
  98. package/dist/utils/reviewResponseParser.js.map +1 -0
  99. package/dist/utils/reviewSessionCache.d.ts +81 -0
  100. package/dist/utils/reviewSessionCache.d.ts.map +1 -0
  101. package/dist/utils/reviewSessionCache.js +220 -0
  102. package/dist/utils/reviewSessionCache.js.map +1 -0
  103. package/dist/utils/reviewSessionManager.d.ts +52 -0
  104. package/dist/utils/reviewSessionManager.d.ts.map +1 -0
  105. package/dist/utils/reviewSessionManager.js +65 -0
  106. package/dist/utils/reviewSessionManager.js.map +1 -0
  107. package/dist/utils/sessionManager.d.ts +94 -0
  108. package/dist/utils/sessionManager.d.ts.map +1 -0
  109. package/dist/utils/sessionManager.js +374 -0
  110. package/dist/utils/sessionManager.js.map +1 -0
  111. package/dist/utils/sessionSchemas.d.ts +126 -0
  112. package/dist/utils/sessionSchemas.d.ts.map +1 -0
  113. package/dist/utils/sessionSchemas.js +2 -0
  114. package/dist/utils/sessionSchemas.js.map +1 -0
  115. package/dist/utils/timeoutManager.d.ts +2 -0
  116. package/dist/utils/timeoutManager.d.ts.map +1 -0
  117. package/dist/utils/timeoutManager.js +2 -0
  118. package/dist/utils/timeoutManager.js.map +1 -0
  119. package/package.json +71 -0
@@ -0,0 +1,67 @@
1
+ import { BrainstormSessionData } from './sessionSchemas.js';
2
+ /**
3
+ * Session manager for brainstorm tool
4
+ * Tracks iterative ideation with ideas and feedback
5
+ */
6
+ export declare class BrainstormSessionManager {
7
+ private sessionManager;
8
+ constructor();
9
+ /**
10
+ * Creates a new brainstorming session
11
+ */
12
+ createSession(sessionId: string, challenge: string, methodology: string, domain?: string, constraints?: string): BrainstormSessionData;
13
+ /**
14
+ * Adds a brainstorming round with generated ideas
15
+ */
16
+ addRound(session: BrainstormSessionData, userPrompt: string, geminiResponse: string, ideas: Array<{
17
+ name: string;
18
+ description: string;
19
+ feasibility?: number;
20
+ impact?: number;
21
+ innovation?: number;
22
+ }>): BrainstormSessionData;
23
+ /**
24
+ * Records idea refinement action
25
+ */
26
+ refineIdeas(session: BrainstormSessionData, action: 'refined' | 'merged' | 'discarded', ideaIds: string[], reason: string): BrainstormSessionData;
27
+ /**
28
+ * Builds context from previous rounds' ideas
29
+ * @param session The session to build context from
30
+ * @param activeOnly Only include active/refined ideas (exclude discarded/merged)
31
+ * @returns Formatted ideas context
32
+ */
33
+ buildIdeasContext(session: BrainstormSessionData, activeOnly?: boolean): string;
34
+ /**
35
+ * Saves a session
36
+ */
37
+ save(session: BrainstormSessionData): Promise<void>;
38
+ /**
39
+ * Loads a session
40
+ */
41
+ load(sessionId: string): Promise<BrainstormSessionData | null>;
42
+ /**
43
+ * Lists all sessions
44
+ */
45
+ list(): Promise<BrainstormSessionData[]>;
46
+ /**
47
+ * Deletes a session
48
+ */
49
+ delete(sessionId: string): Promise<boolean>;
50
+ /**
51
+ * Gets or creates a session
52
+ */
53
+ getOrCreate(sessionId: string, challenge: string, methodology: string, domain?: string, constraints?: string): Promise<BrainstormSessionData>;
54
+ /**
55
+ * Gets cache statistics
56
+ */
57
+ getStats(): Promise<{
58
+ toolName: string;
59
+ sessionCount: number;
60
+ ttl: number;
61
+ maxSessions: number;
62
+ evictionPolicy: string;
63
+ cacheDir: string;
64
+ }>;
65
+ }
66
+ export declare const brainstormSessionManager: BrainstormSessionManager;
67
+ //# sourceMappingURL=brainstormSessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brainstormSessionManager.d.ts","sourceRoot":"","sources":["../../src/utils/brainstormSessionManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D;;;GAGG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,cAAc,CAAwC;;IAM9D;;OAEG;IACH,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,qBAAqB;IAiBxB;;OAEG;IACH,QAAQ,CACN,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,GACD,qBAAqB;IA0BxB;;OAEG;IACH,WAAW,CACT,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,EAC1C,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,GACb,qBAAqB;IA4BxB;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,EAAE,UAAU,GAAE,OAAc,GAAG,MAAM;IAgCrF;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAIpE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAI9C;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD;;OAEG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,qBAAqB,CAAC;IAQjC;;OAEG;IACG,QAAQ;;;;;;;;CAGf;AAGD,eAAO,MAAM,wBAAwB,0BAAiC,CAAC"}
@@ -0,0 +1,165 @@
1
+ import { SessionManager } from './sessionManager.js';
2
+ import { randomUUID } from 'node:crypto';
3
+ /**
4
+ * Session manager for brainstorm tool
5
+ * Tracks iterative ideation with ideas and feedback
6
+ */
7
+ export class BrainstormSessionManager {
8
+ sessionManager;
9
+ constructor() {
10
+ this.sessionManager = new SessionManager('brainstorm');
11
+ }
12
+ /**
13
+ * Creates a new brainstorming session
14
+ */
15
+ createSession(sessionId, challenge, methodology, domain, constraints) {
16
+ const now = Date.now();
17
+ return {
18
+ sessionId,
19
+ createdAt: now,
20
+ lastAccessedAt: now,
21
+ challenge,
22
+ methodology,
23
+ domain,
24
+ constraints,
25
+ rounds: [],
26
+ totalIdeas: 0,
27
+ activeIdeas: 0,
28
+ refinementHistory: []
29
+ };
30
+ }
31
+ /**
32
+ * Adds a brainstorming round with generated ideas
33
+ */
34
+ addRound(session, userPrompt, geminiResponse, ideas) {
35
+ const parsedIdeas = ideas.map(idea => ({
36
+ ideaId: `idea-${randomUUID()}`,
37
+ name: idea.name,
38
+ description: idea.description,
39
+ feasibility: idea.feasibility,
40
+ impact: idea.impact,
41
+ innovation: idea.innovation,
42
+ status: 'active'
43
+ }));
44
+ session.rounds.push({
45
+ roundNumber: session.rounds.length + 1,
46
+ timestamp: Date.now(),
47
+ userPrompt,
48
+ geminiResponse,
49
+ ideasGenerated: parsedIdeas
50
+ });
51
+ session.totalIdeas += parsedIdeas.length;
52
+ session.activeIdeas += parsedIdeas.length;
53
+ session.lastAccessedAt = Date.now();
54
+ return session;
55
+ }
56
+ /**
57
+ * Records idea refinement action
58
+ */
59
+ refineIdeas(session, action, ideaIds, reason) {
60
+ session.refinementHistory.push({
61
+ timestamp: Date.now(),
62
+ action,
63
+ ideaIds,
64
+ reason
65
+ });
66
+ // Update idea statuses
67
+ for (const round of session.rounds) {
68
+ for (const idea of round.ideasGenerated) {
69
+ if (ideaIds.includes(idea.ideaId)) {
70
+ if (action === 'discarded') {
71
+ idea.status = 'discarded';
72
+ session.activeIdeas--;
73
+ }
74
+ else if (action === 'merged') {
75
+ idea.status = 'merged';
76
+ session.activeIdeas--;
77
+ }
78
+ else {
79
+ idea.status = 'refined';
80
+ }
81
+ }
82
+ }
83
+ }
84
+ return session;
85
+ }
86
+ /**
87
+ * Builds context from previous rounds' ideas
88
+ * @param session The session to build context from
89
+ * @param activeOnly Only include active/refined ideas (exclude discarded/merged)
90
+ * @returns Formatted ideas context
91
+ */
92
+ buildIdeasContext(session, activeOnly = true) {
93
+ if (session.rounds.length === 0) {
94
+ return '';
95
+ }
96
+ const allIdeas = session.rounds.flatMap(round => round.ideasGenerated);
97
+ const filteredIdeas = activeOnly
98
+ ? allIdeas.filter(idea => idea.status === 'active' || idea.status === 'refined')
99
+ : allIdeas;
100
+ if (filteredIdeas.length === 0) {
101
+ return '';
102
+ }
103
+ const ideaList = filteredIdeas.map(idea => {
104
+ let ideaText = `- **${idea.name}**: ${idea.description}`;
105
+ if (idea.status !== 'active') {
106
+ ideaText += ` [${idea.status.toUpperCase()}]`;
107
+ }
108
+ if (idea.feasibility || idea.impact || idea.innovation) {
109
+ const scores = [];
110
+ if (idea.feasibility)
111
+ scores.push(`Feasibility: ${idea.feasibility}/10`);
112
+ if (idea.impact)
113
+ scores.push(`Impact: ${idea.impact}/10`);
114
+ if (idea.innovation)
115
+ scores.push(`Innovation: ${idea.innovation}/10`);
116
+ ideaText += ` (${scores.join(', ')})`;
117
+ }
118
+ return ideaText;
119
+ }).join('\n');
120
+ return `# Previously Generated Ideas\n\n${ideaList}`;
121
+ }
122
+ /**
123
+ * Saves a session
124
+ */
125
+ async save(session) {
126
+ await this.sessionManager.save(session.sessionId, session);
127
+ }
128
+ /**
129
+ * Loads a session
130
+ */
131
+ async load(sessionId) {
132
+ return await this.sessionManager.load(sessionId);
133
+ }
134
+ /**
135
+ * Lists all sessions
136
+ */
137
+ async list() {
138
+ return await this.sessionManager.list();
139
+ }
140
+ /**
141
+ * Deletes a session
142
+ */
143
+ async delete(sessionId) {
144
+ return await this.sessionManager.delete(sessionId);
145
+ }
146
+ /**
147
+ * Gets or creates a session
148
+ */
149
+ async getOrCreate(sessionId, challenge, methodology, domain, constraints) {
150
+ const existing = await this.load(sessionId);
151
+ if (existing) {
152
+ return existing;
153
+ }
154
+ return this.createSession(sessionId, challenge, methodology, domain, constraints);
155
+ }
156
+ /**
157
+ * Gets cache statistics
158
+ */
159
+ async getStats() {
160
+ return await this.sessionManager.getStats();
161
+ }
162
+ }
163
+ // Export singleton instance
164
+ export const brainstormSessionManager = new BrainstormSessionManager();
165
+ //# sourceMappingURL=brainstormSessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brainstormSessionManager.js","sourceRoot":"","sources":["../../src/utils/brainstormSessionManager.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"}