@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.
- package/LICENSE +26 -0
- package/README.md +239 -0
- package/dist/__tests__/ask-gemini.test.d.ts +2 -0
- package/dist/__tests__/ask-gemini.test.d.ts.map +1 -0
- package/dist/__tests__/ask-gemini.test.js +165 -0
- package/dist/__tests__/ask-gemini.test.js.map +1 -0
- package/dist/__tests__/server.test.d.ts +2 -0
- package/dist/__tests__/server.test.d.ts.map +1 -0
- package/dist/__tests__/server.test.js +72 -0
- package/dist/__tests__/server.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +131 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/utils/changeModeChunker.test.d.ts +2 -0
- package/dist/__tests__/utils/changeModeChunker.test.d.ts.map +1 -0
- package/dist/__tests__/utils/changeModeChunker.test.js +137 -0
- package/dist/__tests__/utils/changeModeChunker.test.js.map +1 -0
- package/dist/__tests__/utils/changeModeParser.test.d.ts +2 -0
- package/dist/__tests__/utils/changeModeParser.test.d.ts.map +1 -0
- package/dist/__tests__/utils/changeModeParser.test.js +254 -0
- package/dist/__tests__/utils/changeModeParser.test.js.map +1 -0
- package/dist/__tests__/utils/changeModeTranslator.test.d.ts +2 -0
- package/dist/__tests__/utils/changeModeTranslator.test.d.ts.map +1 -0
- package/dist/__tests__/utils/changeModeTranslator.test.js +112 -0
- package/dist/__tests__/utils/changeModeTranslator.test.js.map +1 -0
- package/dist/__tests__/utils/chunkCache.test.d.ts +2 -0
- package/dist/__tests__/utils/chunkCache.test.d.ts.map +1 -0
- package/dist/__tests__/utils/chunkCache.test.js +140 -0
- package/dist/__tests__/utils/chunkCache.test.js.map +1 -0
- package/dist/__tests__/utils/commandExecutor.test.d.ts +2 -0
- package/dist/__tests__/utils/commandExecutor.test.d.ts.map +1 -0
- package/dist/__tests__/utils/commandExecutor.test.js +139 -0
- package/dist/__tests__/utils/commandExecutor.test.js.map +1 -0
- package/dist/__tests__/utils/geminiExecutor.test.d.ts +2 -0
- package/dist/__tests__/utils/geminiExecutor.test.d.ts.map +1 -0
- package/dist/__tests__/utils/geminiExecutor.test.js +337 -0
- package/dist/__tests__/utils/geminiExecutor.test.js.map +1 -0
- package/dist/__tests__/utils/responseCache.test.d.ts +2 -0
- package/dist/__tests__/utils/responseCache.test.d.ts.map +1 -0
- package/dist/__tests__/utils/responseCache.test.js +98 -0
- package/dist/__tests__/utils/responseCache.test.js.map +1 -0
- package/dist/__tests__/utils/test-helpers.d.ts +17 -0
- package/dist/__tests__/utils/test-helpers.d.ts.map +1 -0
- package/dist/__tests__/utils/test-helpers.js +50 -0
- package/dist/__tests__/utils/test-helpers.js.map +1 -0
- package/dist/constants.d.ts +96 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +89 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/ask-gemini.tool.d.ts +3 -0
- package/dist/tools/ask-gemini.tool.d.ts.map +1 -0
- package/dist/tools/ask-gemini.tool.js +65 -0
- package/dist/tools/ask-gemini.tool.js.map +1 -0
- package/dist/tools/brainstorm.tool.d.ts +3 -0
- package/dist/tools/brainstorm.tool.d.ts.map +1 -0
- package/dist/tools/brainstorm.tool.js +147 -0
- package/dist/tools/brainstorm.tool.js.map +1 -0
- package/dist/tools/fetch-chunk.tool.d.ts +3 -0
- package/dist/tools/fetch-chunk.tool.d.ts.map +1 -0
- package/dist/tools/fetch-chunk.tool.js +67 -0
- package/dist/tools/fetch-chunk.tool.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +43 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +81 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/simple-tools.d.ts +4 -0
- package/dist/tools/simple-tools.d.ts.map +1 -0
- package/dist/tools/simple-tools.js +42 -0
- package/dist/tools/simple-tools.js.map +1 -0
- package/dist/tools/test-tool.example.d.ts +13 -0
- package/dist/tools/test-tool.example.d.ts.map +1 -0
- package/dist/tools/test-tool.example.js +32 -0
- package/dist/tools/test-tool.example.js.map +1 -0
- package/dist/tools/timeout-test.tool.d.ts +3 -0
- package/dist/tools/timeout-test.tool.d.ts.map +1 -0
- package/dist/tools/timeout-test.tool.js +36 -0
- package/dist/tools/timeout-test.tool.js.map +1 -0
- package/dist/utils/changeModeChunker.d.ts +11 -0
- package/dist/utils/changeModeChunker.d.ts.map +1 -0
- package/dist/utils/changeModeChunker.js +89 -0
- package/dist/utils/changeModeChunker.js.map +1 -0
- package/dist/utils/changeModeParser.d.ts +15 -0
- package/dist/utils/changeModeParser.d.ts.map +1 -0
- package/dist/utils/changeModeParser.js +67 -0
- package/dist/utils/changeModeParser.js.map +1 -0
- package/dist/utils/changeModeTranslator.d.ts +8 -0
- package/dist/utils/changeModeTranslator.d.ts.map +1 -0
- package/dist/utils/changeModeTranslator.js +70 -0
- package/dist/utils/changeModeTranslator.js.map +1 -0
- package/dist/utils/chunkCache.d.ts +22 -0
- package/dist/utils/chunkCache.d.ts.map +1 -0
- package/dist/utils/chunkCache.js +161 -0
- package/dist/utils/chunkCache.js.map +1 -0
- package/dist/utils/commandExecutor.d.ts +2 -0
- package/dist/utils/commandExecutor.d.ts.map +1 -0
- package/dist/utils/commandExecutor.js +79 -0
- package/dist/utils/commandExecutor.js.map +1 -0
- package/dist/utils/geminiExecutor.d.ts +17 -0
- package/dist/utils/geminiExecutor.d.ts.map +1 -0
- package/dist/utils/geminiExecutor.js +238 -0
- package/dist/utils/geminiExecutor.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +42 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/responseCache.d.ts +33 -0
- package/dist/utils/responseCache.d.ts.map +1 -0
- package/dist/utils/responseCache.js +87 -0
- package/dist/utils/responseCache.js.map +1 -0
- package/dist/utils/timeoutManager.d.ts +2 -0
- package/dist/utils/timeoutManager.d.ts.map +1 -0
- package/dist/utils/timeoutManager.js +2 -0
- package/dist/utils/timeoutManager.js.map +1 -0
- package/package.json +79 -0
|
@@ -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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { Logger } from './logger.js';
|
|
6
|
+
const CACHE_DIR = path.join(os.tmpdir(), 'gemini-mcp-chunks');
|
|
7
|
+
const CACHE_TTL = 10 * 60 * 1000;
|
|
8
|
+
const MAX_CACHE_FILES = 50;
|
|
9
|
+
function ensureCacheDir() {
|
|
10
|
+
if (!fs.existsSync(CACHE_DIR)) {
|
|
11
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Caches chunks from a changeMode response
|
|
16
|
+
* @param prompt The original prompt (used for hash generation)
|
|
17
|
+
* @param chunks The parsed and chunked edits
|
|
18
|
+
* @returns A short cache key for retrieval
|
|
19
|
+
*/
|
|
20
|
+
export function cacheChunks(prompt, chunks) {
|
|
21
|
+
ensureCacheDir();
|
|
22
|
+
cleanExpiredFiles(); // Cleanup on each write
|
|
23
|
+
// Generate deterministic cache key from prompt
|
|
24
|
+
const promptHash = createHash('sha256').update(prompt).digest('hex');
|
|
25
|
+
const cacheKey = promptHash.slice(0, 8);
|
|
26
|
+
const filePath = path.join(CACHE_DIR, `${cacheKey}.json`);
|
|
27
|
+
// Store with metadata
|
|
28
|
+
const cacheData = {
|
|
29
|
+
chunks,
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
promptHash
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
fs.writeFileSync(filePath, JSON.stringify(cacheData));
|
|
35
|
+
Logger.debug(`Cached ${chunks.length} chunks to file: ${cacheKey}.json`);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
Logger.error(`Failed to cache chunks: ${error}`);
|
|
39
|
+
}
|
|
40
|
+
enforceFileLimits();
|
|
41
|
+
return cacheKey;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves cached chunks if they exist and haven't expired
|
|
45
|
+
* @param cacheKey The cache key returned from cacheChunks
|
|
46
|
+
* @returns The cached chunks or null if expired/not found
|
|
47
|
+
*/
|
|
48
|
+
export function getChunks(cacheKey) {
|
|
49
|
+
const filePath = path.join(CACHE_DIR, `${cacheKey}.json`);
|
|
50
|
+
try {
|
|
51
|
+
if (!fs.existsSync(filePath)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
55
|
+
const data = JSON.parse(fileContent);
|
|
56
|
+
if (Date.now() - data.timestamp > CACHE_TTL) {
|
|
57
|
+
fs.unlinkSync(filePath);
|
|
58
|
+
Logger.debug(`Cache expired for ${cacheKey}, deleted file`);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
Logger.debug(`Cache hit for ${cacheKey}, returning ${data.chunks.length} chunks`);
|
|
62
|
+
return data.chunks;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
Logger.debug(`Cache read error for ${cacheKey}: ${error}`);
|
|
66
|
+
try {
|
|
67
|
+
fs.unlinkSync(filePath); // Clean up bad file
|
|
68
|
+
}
|
|
69
|
+
catch { }
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function cleanExpiredFiles() {
|
|
74
|
+
try {
|
|
75
|
+
ensureCacheDir();
|
|
76
|
+
const files = fs.readdirSync(CACHE_DIR);
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
let cleaned = 0;
|
|
79
|
+
for (const file of files) {
|
|
80
|
+
if (!file.endsWith('.json'))
|
|
81
|
+
continue;
|
|
82
|
+
const filePath = path.join(CACHE_DIR, file);
|
|
83
|
+
try {
|
|
84
|
+
const stats = fs.statSync(filePath);
|
|
85
|
+
if (now - stats.mtimeMs > CACHE_TTL) {
|
|
86
|
+
fs.unlinkSync(filePath);
|
|
87
|
+
cleaned++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// Individual file error - continue with others
|
|
92
|
+
Logger.debug(`Error checking file ${file}: ${error}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (cleaned > 0) {
|
|
96
|
+
Logger.debug(`Cleaned ${cleaned} expired cache files`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// Non-critical, just log
|
|
101
|
+
Logger.debug(`Cache cleanup error: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// maximum file count limit (FIFO) --> LRU?
|
|
105
|
+
function enforceFileLimits() {
|
|
106
|
+
try {
|
|
107
|
+
const files = fs.readdirSync(CACHE_DIR)
|
|
108
|
+
.filter(f => f.endsWith('.json'))
|
|
109
|
+
.map(f => ({
|
|
110
|
+
name: f,
|
|
111
|
+
path: path.join(CACHE_DIR, f),
|
|
112
|
+
mtime: fs.statSync(path.join(CACHE_DIR, f)).mtimeMs
|
|
113
|
+
}))
|
|
114
|
+
.sort((a, b) => a.mtime - b.mtime); // Oldest first
|
|
115
|
+
// Remove oldest files if over limit
|
|
116
|
+
if (files.length > MAX_CACHE_FILES) {
|
|
117
|
+
const toRemove = files.slice(0, files.length - MAX_CACHE_FILES);
|
|
118
|
+
for (const file of toRemove) {
|
|
119
|
+
try {
|
|
120
|
+
fs.unlinkSync(file.path);
|
|
121
|
+
}
|
|
122
|
+
catch { }
|
|
123
|
+
}
|
|
124
|
+
Logger.debug(`Removed ${toRemove.length} old cache files to enforce limit`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
Logger.debug(`Error enforcing file limits: ${error}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function getCacheStats() {
|
|
132
|
+
ensureCacheDir();
|
|
133
|
+
let size = 0;
|
|
134
|
+
try {
|
|
135
|
+
const files = fs.readdirSync(CACHE_DIR);
|
|
136
|
+
size = files.filter(f => f.endsWith('.json')).length;
|
|
137
|
+
}
|
|
138
|
+
catch { }
|
|
139
|
+
return {
|
|
140
|
+
size,
|
|
141
|
+
ttl: CACHE_TTL,
|
|
142
|
+
maxSize: MAX_CACHE_FILES,
|
|
143
|
+
cacheDir: CACHE_DIR
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
export function clearCache() {
|
|
147
|
+
try {
|
|
148
|
+
ensureCacheDir();
|
|
149
|
+
const files = fs.readdirSync(CACHE_DIR);
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
if (file.endsWith('.json')) {
|
|
152
|
+
fs.unlinkSync(path.join(CACHE_DIR, file));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
Logger.debug('Cache emptied');
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
Logger.error(`Failed to empty cache: ${error}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=chunkCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunkCache.js","sourceRoot":"","sources":["../../src/utils/chunkCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandExecutor.d.ts","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EACxC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAmFjB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import { Logger } from "./logger.js";
|
|
3
|
+
export async function executeCommand(command, args, onProgress, cwd) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const startTime = Date.now();
|
|
6
|
+
Logger.commandExecution(command, args, startTime);
|
|
7
|
+
const childProcess = spawn(command, args, {
|
|
8
|
+
env: process.env,
|
|
9
|
+
shell: process.platform === "win32",
|
|
10
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11
|
+
...(cwd && { cwd }),
|
|
12
|
+
});
|
|
13
|
+
// Use array buffers for O(n) performance instead of O(n²) string concatenation
|
|
14
|
+
const stdoutChunks = [];
|
|
15
|
+
const stderrChunks = [];
|
|
16
|
+
let isResolved = false;
|
|
17
|
+
childProcess.stdout.on("data", (data) => {
|
|
18
|
+
const chunk = data.toString();
|
|
19
|
+
stdoutChunks.push(chunk);
|
|
20
|
+
// Report immediately if callback provided (no substring calculation needed)
|
|
21
|
+
if (onProgress) {
|
|
22
|
+
onProgress(chunk);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
// CLI level errors
|
|
26
|
+
childProcess.stderr.on("data", (data) => {
|
|
27
|
+
const chunk = data.toString();
|
|
28
|
+
stderrChunks.push(chunk);
|
|
29
|
+
// find RESOURCE_EXHAUSTED when Gemini Pro quota is exceeded
|
|
30
|
+
if (chunk.includes("RESOURCE_EXHAUSTED")) {
|
|
31
|
+
const stderrSoFar = stderrChunks.join('');
|
|
32
|
+
const modelMatch = stderrSoFar.match(/Quota exceeded for quota metric '([^']+)'/);
|
|
33
|
+
const statusMatch = stderrSoFar.match(/status["\s]*[:=]\s*(\d+)/);
|
|
34
|
+
const reasonMatch = stderrSoFar.match(/"reason":\s*"([^"]+)"/);
|
|
35
|
+
const model = modelMatch ? modelMatch[1] : "Unknown Model";
|
|
36
|
+
const status = statusMatch ? statusMatch[1] : "429";
|
|
37
|
+
const reason = reasonMatch ? reasonMatch[1] : "rateLimitExceeded";
|
|
38
|
+
const errorJson = {
|
|
39
|
+
error: {
|
|
40
|
+
code: parseInt(status),
|
|
41
|
+
message: `GMCPT: --> Quota exceeded for ${model}`,
|
|
42
|
+
details: {
|
|
43
|
+
model: model,
|
|
44
|
+
reason: reason,
|
|
45
|
+
statusText: "Too Many Requests -- > try using gemini-3-flash-preview by asking",
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Logger.error(`Gemini Quota Error: ${JSON.stringify(errorJson, null, 2)}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
childProcess.on("error", (error) => {
|
|
53
|
+
if (!isResolved) {
|
|
54
|
+
isResolved = true;
|
|
55
|
+
Logger.error(`Process error:`, error);
|
|
56
|
+
reject(new Error(`Failed to spawn command: ${error.message}`));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
childProcess.on("close", (code) => {
|
|
60
|
+
if (!isResolved) {
|
|
61
|
+
isResolved = true;
|
|
62
|
+
// Join array buffers efficiently
|
|
63
|
+
const stdout = stdoutChunks.join('');
|
|
64
|
+
const stderr = stderrChunks.join('');
|
|
65
|
+
if (code === 0) {
|
|
66
|
+
Logger.commandComplete(startTime, code, stdout.length);
|
|
67
|
+
resolve(stdout.trim());
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
Logger.commandComplete(startTime, code);
|
|
71
|
+
Logger.error(`Failed with exit code ${code}`);
|
|
72
|
+
const errorMessage = stderr.trim() || "Unknown error";
|
|
73
|
+
reject(new Error(`Command failed with exit code ${code}: ${errorMessage}`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=commandExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandExecutor.js","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface GeminiCLIOptions {
|
|
2
|
+
model?: string;
|
|
3
|
+
sandbox?: boolean;
|
|
4
|
+
changeMode?: boolean;
|
|
5
|
+
yolo?: boolean;
|
|
6
|
+
approvalMode?: string;
|
|
7
|
+
outputFormat?: string;
|
|
8
|
+
includeDirectories?: string | string[];
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
promptInteractive?: string;
|
|
11
|
+
extensions?: string | string[];
|
|
12
|
+
resume?: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function executeGeminiCLI(prompt: string, options: GeminiCLIOptions | string, onProgress?: (newOutput: string) => void): Promise<string>;
|
|
16
|
+
export declare function processChangeModeOutput(rawResult: string, chunkIndex?: number, chunkCacheKey?: string, prompt?: string): Promise<string>;
|
|
17
|
+
//# sourceMappingURL=geminiExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geminiExecutor.d.ts","sourceRoot":"","sources":["../../src/utils/geminiExecutor.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAsED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,GAAG,MAAM,EAClC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACvC,OAAO,CAAC,MAAM,CAAC,CAiIjB;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CA8DjB"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { executeCommand } from './commandExecutor.js';
|
|
2
|
+
import { Logger } from './logger.js';
|
|
3
|
+
import { ERROR_MESSAGES, STATUS_MESSAGES, MODELS, CLI } from '../constants.js';
|
|
4
|
+
import { parseChangeModeOutput, validateChangeModeEdits } from './changeModeParser.js';
|
|
5
|
+
import { formatChangeModeResponse, summarizeChangeModeEdits } from './changeModeTranslator.js';
|
|
6
|
+
import { chunkChangeModeEdits } from './changeModeChunker.js';
|
|
7
|
+
import { cacheChunks, getChunks } from './chunkCache.js';
|
|
8
|
+
import { generateCacheKey, getCachedResponse, cacheResponse, isCacheEnabled } from './responseCache.js';
|
|
9
|
+
/**
|
|
10
|
+
* Helper function to build Gemini CLI arguments from options
|
|
11
|
+
* Eliminates code duplication between main execution and fallback
|
|
12
|
+
*/
|
|
13
|
+
function buildGeminiArgs(opts, prompt, forceModel) {
|
|
14
|
+
const args = [];
|
|
15
|
+
const model = forceModel || opts.model;
|
|
16
|
+
// Model selection
|
|
17
|
+
if (model) {
|
|
18
|
+
args.push(CLI.FLAGS.MODEL, model);
|
|
19
|
+
}
|
|
20
|
+
// Boolean flags
|
|
21
|
+
if (opts.sandbox) {
|
|
22
|
+
args.push(CLI.FLAGS.SANDBOX);
|
|
23
|
+
}
|
|
24
|
+
if (opts.yolo) {
|
|
25
|
+
args.push(CLI.FLAGS.YOLO);
|
|
26
|
+
}
|
|
27
|
+
if (opts.debug) {
|
|
28
|
+
args.push(CLI.FLAGS.DEBUG);
|
|
29
|
+
}
|
|
30
|
+
// Approval mode (overrides yolo if both are set)
|
|
31
|
+
if (opts.approvalMode) {
|
|
32
|
+
args.push(CLI.FLAGS.APPROVAL_MODE, opts.approvalMode);
|
|
33
|
+
}
|
|
34
|
+
// Output format
|
|
35
|
+
if (opts.outputFormat) {
|
|
36
|
+
args.push(CLI.FLAGS.OUTPUT_FORMAT, opts.outputFormat);
|
|
37
|
+
}
|
|
38
|
+
// Include directories (array or comma-separated string)
|
|
39
|
+
if (opts.includeDirectories) {
|
|
40
|
+
const dirs = Array.isArray(opts.includeDirectories)
|
|
41
|
+
? opts.includeDirectories.join(',')
|
|
42
|
+
: opts.includeDirectories;
|
|
43
|
+
args.push(CLI.FLAGS.INCLUDE_DIRECTORIES, dirs);
|
|
44
|
+
}
|
|
45
|
+
// Extensions (array or comma-separated string)
|
|
46
|
+
if (opts.extensions) {
|
|
47
|
+
const exts = Array.isArray(opts.extensions)
|
|
48
|
+
? opts.extensions.join(',')
|
|
49
|
+
: opts.extensions;
|
|
50
|
+
args.push(CLI.FLAGS.EXTENSIONS, exts);
|
|
51
|
+
}
|
|
52
|
+
// Resume session
|
|
53
|
+
if (opts.resume) {
|
|
54
|
+
args.push(CLI.FLAGS.RESUME, opts.resume);
|
|
55
|
+
}
|
|
56
|
+
// Prompt interactive
|
|
57
|
+
if (opts.promptInteractive) {
|
|
58
|
+
args.push(CLI.FLAGS.PROMPT_INTERACTIVE, opts.promptInteractive);
|
|
59
|
+
}
|
|
60
|
+
// Use positional prompt (not -p flag which is deprecated in Gemini CLI v0.18+).
|
|
61
|
+
// @ symbols are safe here: with spawn(cmd, argsArray, {shell: true}),
|
|
62
|
+
// Node.js auto-quotes each arg for cmd.exe, and @ is not a cmd.exe metacharacter.
|
|
63
|
+
args.push(prompt);
|
|
64
|
+
return args;
|
|
65
|
+
}
|
|
66
|
+
export async function executeGeminiCLI(prompt, options, onProgress) {
|
|
67
|
+
// Handle backward compatibility - if options is a string, it's the old 'model' parameter
|
|
68
|
+
let opts;
|
|
69
|
+
if (typeof options === 'string') {
|
|
70
|
+
opts = { model: options };
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
opts = options || {};
|
|
74
|
+
}
|
|
75
|
+
// Check cache first for non-changeMode requests (changeMode needs fresh responses)
|
|
76
|
+
if (isCacheEnabled() && !opts.changeMode) {
|
|
77
|
+
const cacheKey = generateCacheKey(prompt, opts);
|
|
78
|
+
const cached = getCachedResponse(cacheKey);
|
|
79
|
+
if (cached) {
|
|
80
|
+
Logger.debug('Returning cached response');
|
|
81
|
+
return cached;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let prompt_processed = prompt;
|
|
85
|
+
if (opts.changeMode) {
|
|
86
|
+
prompt_processed = prompt.replace(/file:(\S+)/g, '@$1');
|
|
87
|
+
const changeModeInstructions = `
|
|
88
|
+
[CHANGEMODE INSTRUCTIONS]
|
|
89
|
+
You are generating code modifications that will be processed by an automated system. The output format is critical because it enables programmatic application of changes without human intervention.
|
|
90
|
+
|
|
91
|
+
INSTRUCTIONS:
|
|
92
|
+
1. Analyze each provided file thoroughly
|
|
93
|
+
2. Identify locations requiring changes based on the user request
|
|
94
|
+
3. For each change, output in the exact format specified
|
|
95
|
+
4. The OLD section must be EXACTLY what appears in the file (copy-paste exact match)
|
|
96
|
+
5. Provide complete, directly replacing code blocks
|
|
97
|
+
6. Verify line numbers are accurate
|
|
98
|
+
|
|
99
|
+
CRITICAL REQUIREMENTS:
|
|
100
|
+
1. Output edits in the EXACT format specified below - no deviations
|
|
101
|
+
2. The OLD string MUST be findable with Ctrl+F - it must be a unique, exact match
|
|
102
|
+
3. Include enough surrounding lines to make the OLD string unique
|
|
103
|
+
4. If a string appears multiple times (like </div>), include enough context lines above and below to make it unique
|
|
104
|
+
5. Copy the OLD content EXACTLY as it appears - including all whitespace, indentation, line breaks
|
|
105
|
+
6. Never use partial lines - always include complete lines from start to finish
|
|
106
|
+
|
|
107
|
+
OUTPUT FORMAT (follow exactly):
|
|
108
|
+
**FILE: [filename]:[line_number]**
|
|
109
|
+
\`\`\`
|
|
110
|
+
OLD:
|
|
111
|
+
[exact code to be replaced - must match file content precisely]
|
|
112
|
+
NEW:
|
|
113
|
+
[new code to insert - complete and functional]
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
EXAMPLE 1 - Simple unique match:
|
|
117
|
+
**FILE: src/utils/helper.js:100**
|
|
118
|
+
\`\`\`
|
|
119
|
+
OLD:
|
|
120
|
+
function getMessage() {
|
|
121
|
+
return "Hello World";
|
|
122
|
+
}
|
|
123
|
+
NEW:
|
|
124
|
+
function getMessage() {
|
|
125
|
+
return "Hello Universe!";
|
|
126
|
+
}
|
|
127
|
+
\`\`\`
|
|
128
|
+
|
|
129
|
+
EXAMPLE 2 - Common tag needing context:
|
|
130
|
+
**FILE: index.html:245**
|
|
131
|
+
\`\`\`
|
|
132
|
+
OLD:
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</section>
|
|
136
|
+
NEW:
|
|
137
|
+
</div>
|
|
138
|
+
</footer>
|
|
139
|
+
</section>
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
IMPORTANT: The OLD section must be an EXACT copy from the file that can be found with Ctrl+F!
|
|
143
|
+
|
|
144
|
+
USER REQUEST:
|
|
145
|
+
${prompt_processed}
|
|
146
|
+
`;
|
|
147
|
+
prompt_processed = changeModeInstructions;
|
|
148
|
+
}
|
|
149
|
+
// Use helper function to build args (eliminates code duplication)
|
|
150
|
+
const args = buildGeminiArgs(opts, prompt_processed);
|
|
151
|
+
try {
|
|
152
|
+
const result = await executeCommand(CLI.COMMANDS.GEMINI, args, onProgress, opts.cwd);
|
|
153
|
+
// Cache successful non-changeMode responses
|
|
154
|
+
if (isCacheEnabled() && !opts.changeMode) {
|
|
155
|
+
const cacheKey = generateCacheKey(prompt, opts);
|
|
156
|
+
cacheResponse(cacheKey, result);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
162
|
+
if (errorMessage.includes(ERROR_MESSAGES.QUOTA_EXCEEDED) && opts.model !== MODELS.FLASH) {
|
|
163
|
+
Logger.warn(`${ERROR_MESSAGES.QUOTA_EXCEEDED}. Falling back to ${MODELS.FLASH}.`);
|
|
164
|
+
await sendStatusMessage(STATUS_MESSAGES.FLASH_RETRY);
|
|
165
|
+
// Use helper function with Flash model override (eliminates code duplication)
|
|
166
|
+
const fallbackArgs = buildGeminiArgs(opts, prompt_processed, MODELS.FLASH);
|
|
167
|
+
try {
|
|
168
|
+
const result = await executeCommand(CLI.COMMANDS.GEMINI, fallbackArgs, onProgress, opts.cwd);
|
|
169
|
+
Logger.warn(`Successfully executed with ${MODELS.FLASH} fallback.`);
|
|
170
|
+
await sendStatusMessage(STATUS_MESSAGES.FLASH_SUCCESS);
|
|
171
|
+
// Cache successful fallback response (non-changeMode only)
|
|
172
|
+
if (isCacheEnabled() && !opts.changeMode) {
|
|
173
|
+
const cacheKey = generateCacheKey(prompt, opts);
|
|
174
|
+
cacheResponse(cacheKey, result);
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
catch (fallbackError) {
|
|
179
|
+
const fallbackErrorMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
180
|
+
throw new Error(`${MODELS.PRO} quota exceeded, ${MODELS.FLASH} fallback also failed: ${fallbackErrorMessage}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export async function processChangeModeOutput(rawResult, chunkIndex, chunkCacheKey, prompt) {
|
|
189
|
+
// Check for cached chunks first
|
|
190
|
+
if (chunkIndex && chunkCacheKey) {
|
|
191
|
+
const cachedChunks = getChunks(chunkCacheKey);
|
|
192
|
+
if (cachedChunks && chunkIndex > 0 && chunkIndex <= cachedChunks.length) {
|
|
193
|
+
Logger.debug(`Using cached chunk ${chunkIndex} of ${cachedChunks.length}`);
|
|
194
|
+
const chunk = cachedChunks[chunkIndex - 1];
|
|
195
|
+
let result = formatChangeModeResponse(chunk.edits, { current: chunkIndex, total: cachedChunks.length, cacheKey: chunkCacheKey });
|
|
196
|
+
// Add summary for first chunk only
|
|
197
|
+
if (chunkIndex === 1 && chunk.edits.length > 5) {
|
|
198
|
+
const allEdits = cachedChunks.flatMap(c => c.edits);
|
|
199
|
+
result = summarizeChangeModeEdits(allEdits) + '\n\n' + result;
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
Logger.debug(`Cache miss or invalid chunk index, processing new result`);
|
|
204
|
+
}
|
|
205
|
+
// Parse OLD/NEW format
|
|
206
|
+
const edits = parseChangeModeOutput(rawResult);
|
|
207
|
+
if (edits.length === 0) {
|
|
208
|
+
return `No edits found in Gemini's response. Please ensure Gemini uses the OLD/NEW format. \n\n+ ${rawResult}`;
|
|
209
|
+
}
|
|
210
|
+
// Validate edits
|
|
211
|
+
const validation = validateChangeModeEdits(edits);
|
|
212
|
+
if (!validation.valid) {
|
|
213
|
+
return `Edit validation failed:\n${validation.errors.join('\n')}`;
|
|
214
|
+
}
|
|
215
|
+
const chunks = chunkChangeModeEdits(edits);
|
|
216
|
+
// Cache if multiple chunks and we have the original prompt
|
|
217
|
+
let cacheKey;
|
|
218
|
+
if (chunks.length > 1 && prompt) {
|
|
219
|
+
cacheKey = cacheChunks(prompt, chunks);
|
|
220
|
+
Logger.debug(`Cached ${chunks.length} chunks with key: ${cacheKey}`);
|
|
221
|
+
}
|
|
222
|
+
// Return requested chunk or first chunk
|
|
223
|
+
const returnChunkIndex = (chunkIndex && chunkIndex > 0 && chunkIndex <= chunks.length) ? chunkIndex : 1;
|
|
224
|
+
const returnChunk = chunks[returnChunkIndex - 1];
|
|
225
|
+
// Format the response
|
|
226
|
+
let result = formatChangeModeResponse(returnChunk.edits, chunks.length > 1 ? { current: returnChunkIndex, total: chunks.length, cacheKey } : undefined);
|
|
227
|
+
// Add summary if helpful (only for first chunk)
|
|
228
|
+
if (returnChunkIndex === 1 && edits.length > 5) {
|
|
229
|
+
result = summarizeChangeModeEdits(edits, chunks.length > 1) + '\n\n' + result;
|
|
230
|
+
}
|
|
231
|
+
Logger.debug(`ChangeMode: Parsed ${edits.length} edits, ${chunks.length} chunks, returning chunk ${returnChunkIndex}`);
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
// Placeholder
|
|
235
|
+
async function sendStatusMessage(message) {
|
|
236
|
+
Logger.debug(`Status: ${message}`);
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=geminiExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geminiExecutor.js","sourceRoot":"","sources":["../../src/utils/geminiExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class Logger {
|
|
2
|
+
private static formatMessage;
|
|
3
|
+
static log(message: string, ...args: any[]): void;
|
|
4
|
+
static warn(message: string, ...args: any[]): void;
|
|
5
|
+
static error(message: string, ...args: any[]): void;
|
|
6
|
+
static debug(message: string, ...args: any[]): void;
|
|
7
|
+
static toolInvocation(toolName: string, args: any): void;
|
|
8
|
+
static toolParsedArgs(prompt: string, model?: string, sandbox?: boolean, changeMode?: boolean): void;
|
|
9
|
+
static commandExecution(command: string, args: string[], startTime: number): void;
|
|
10
|
+
private static _commandStartTimes;
|
|
11
|
+
static commandComplete(startTime: number, exitCode: number | null, outputLength?: number): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAGA,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,aAAa;IAI5B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIjD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIlD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAInD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAInD,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAIxD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI;IAIpG,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQjF,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA6E;IAE9G,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;CAUhG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// WIP
|
|
2
|
+
import { LOG_PREFIX } from "../constants.js";
|
|
3
|
+
export class Logger {
|
|
4
|
+
static formatMessage(message) {
|
|
5
|
+
return `${LOG_PREFIX} ${message}` + "\n";
|
|
6
|
+
}
|
|
7
|
+
static log(message, ...args) {
|
|
8
|
+
console.warn(this.formatMessage(message), ...args);
|
|
9
|
+
}
|
|
10
|
+
static warn(message, ...args) {
|
|
11
|
+
console.warn(this.formatMessage(message), ...args);
|
|
12
|
+
}
|
|
13
|
+
static error(message, ...args) {
|
|
14
|
+
console.error(this.formatMessage(message), ...args);
|
|
15
|
+
}
|
|
16
|
+
static debug(message, ...args) {
|
|
17
|
+
console.warn(this.formatMessage(message), ...args);
|
|
18
|
+
}
|
|
19
|
+
static toolInvocation(toolName, args) {
|
|
20
|
+
this.warn("Raw:", JSON.stringify(args, null, 2));
|
|
21
|
+
}
|
|
22
|
+
static toolParsedArgs(prompt, model, sandbox, changeMode) {
|
|
23
|
+
this.warn(`Parsed prompt: "${prompt}"\nchangeMode: ${changeMode || false}`);
|
|
24
|
+
}
|
|
25
|
+
static commandExecution(command, args, startTime) {
|
|
26
|
+
this.warn(`[${startTime}] Starting: ${command} ${args.map((arg) => `"${arg}"`).join(" ")}`);
|
|
27
|
+
// Store command execution start for timing analysis
|
|
28
|
+
this._commandStartTimes.set(startTime, { command, args, startTime });
|
|
29
|
+
}
|
|
30
|
+
// Track command start times for duration calculation
|
|
31
|
+
static _commandStartTimes = new Map();
|
|
32
|
+
static commandComplete(startTime, exitCode, outputLength) {
|
|
33
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
34
|
+
this.warn(`[${elapsed}s] Process finished with exit code: ${exitCode}`);
|
|
35
|
+
if (outputLength !== undefined) {
|
|
36
|
+
this.warn(`Response: ${outputLength} chars`);
|
|
37
|
+
}
|
|
38
|
+
// Clean up command tracking
|
|
39
|
+
this._commandStartTimes.delete(startTime);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM;AACN,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,OAAO,MAAM;IACT,MAAM,CAAC,aAAa,CAAC,OAAe;QAC1C,OAAO,GAAG,UAAU,IAAI,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,OAAe,EAAE,GAAG,IAAW;QACxC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QACzC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QAC1C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QAC1C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,QAAgB,EAAE,IAAS;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,MAAc,EAAE,KAAc,EAAE,OAAiB,EAAE,UAAoB;QAC3F,IAAI,CAAC,IAAI,CAAC,mBAAmB,MAAM,kBAAkB,UAAU,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,OAAe,EAAE,IAAc,EAAE,SAAiB;QACxE,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,eAAe,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE5F,oDAAoD;QACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,qDAAqD;IAC7C,MAAM,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAkE,CAAC;IAE9G,MAAM,CAAC,eAAe,CAAC,SAAiB,EAAE,QAAuB,EAAE,YAAqB;QACtF,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,uCAAuC,QAAQ,EAAE,CAAC,CAAC;QACxE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,aAAa,YAAY,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC"}
|