@eldrforge/kodrdriv 1.2.134 → 1.2.135

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 (72) hide show
  1. package/.cursor/rules/no-local-dependencies.md +6 -0
  2. package/dist/application.js +32 -42
  3. package/dist/application.js.map +1 -1
  4. package/dist/arguments.js +3 -3
  5. package/dist/arguments.js.map +1 -1
  6. package/dist/constants.js +5 -7
  7. package/dist/constants.js.map +1 -1
  8. package/dist/logging.js +4 -32
  9. package/dist/logging.js.map +1 -1
  10. package/dist/types.js +1 -0
  11. package/dist/types.js.map +1 -1
  12. package/package.json +13 -8
  13. package/dist/commands/audio-commit.js +0 -152
  14. package/dist/commands/audio-commit.js.map +0 -1
  15. package/dist/commands/audio-review.js +0 -274
  16. package/dist/commands/audio-review.js.map +0 -1
  17. package/dist/commands/clean.js +0 -49
  18. package/dist/commands/clean.js.map +0 -1
  19. package/dist/commands/commit.js +0 -680
  20. package/dist/commands/commit.js.map +0 -1
  21. package/dist/commands/development.js +0 -467
  22. package/dist/commands/development.js.map +0 -1
  23. package/dist/commands/link.js +0 -646
  24. package/dist/commands/link.js.map +0 -1
  25. package/dist/commands/precommit.js +0 -99
  26. package/dist/commands/precommit.js.map +0 -1
  27. package/dist/commands/publish.js +0 -1432
  28. package/dist/commands/publish.js.map +0 -1
  29. package/dist/commands/release.js +0 -376
  30. package/dist/commands/release.js.map +0 -1
  31. package/dist/commands/review.js +0 -733
  32. package/dist/commands/review.js.map +0 -1
  33. package/dist/commands/select-audio.js +0 -46
  34. package/dist/commands/select-audio.js.map +0 -1
  35. package/dist/commands/tree.js +0 -2363
  36. package/dist/commands/tree.js.map +0 -1
  37. package/dist/commands/unlink.js +0 -537
  38. package/dist/commands/unlink.js.map +0 -1
  39. package/dist/commands/updates.js +0 -211
  40. package/dist/commands/updates.js.map +0 -1
  41. package/dist/commands/versions.js +0 -221
  42. package/dist/commands/versions.js.map +0 -1
  43. package/dist/content/diff.js +0 -346
  44. package/dist/content/diff.js.map +0 -1
  45. package/dist/content/files.js +0 -190
  46. package/dist/content/files.js.map +0 -1
  47. package/dist/content/log.js +0 -72
  48. package/dist/content/log.js.map +0 -1
  49. package/dist/util/aiAdapter.js +0 -28
  50. package/dist/util/aiAdapter.js.map +0 -1
  51. package/dist/util/fileLock.js +0 -241
  52. package/dist/util/fileLock.js.map +0 -1
  53. package/dist/util/general.js +0 -379
  54. package/dist/util/general.js.map +0 -1
  55. package/dist/util/gitMutex.js +0 -161
  56. package/dist/util/gitMutex.js.map +0 -1
  57. package/dist/util/interactive.js +0 -32
  58. package/dist/util/interactive.js.map +0 -1
  59. package/dist/util/loggerAdapter.js +0 -41
  60. package/dist/util/loggerAdapter.js.map +0 -1
  61. package/dist/util/performance.js +0 -134
  62. package/dist/util/performance.js.map +0 -1
  63. package/dist/util/precommitOptimizations.js +0 -310
  64. package/dist/util/precommitOptimizations.js.map +0 -1
  65. package/dist/util/stopContext.js +0 -146
  66. package/dist/util/stopContext.js.map +0 -1
  67. package/dist/util/storageAdapter.js +0 -31
  68. package/dist/util/storageAdapter.js.map +0 -1
  69. package/dist/util/validation.js +0 -45
  70. package/dist/util/validation.js.map +0 -1
  71. package/dist/utils/branchState.js +0 -700
  72. package/dist/utils/branchState.js.map +0 -1
@@ -1,310 +0,0 @@
1
- import path__default from 'path';
2
- import fs from 'fs/promises';
3
- import { getLogger } from '../logging.js';
4
- import { runSecure } from '@eldrforge/git-tools';
5
- import { createStorage } from '@eldrforge/shared';
6
-
7
- const logger = getLogger();
8
- // Cache file to store test run timestamps per package
9
- const TEST_CACHE_FILE = '.kodrdriv-test-cache.json';
10
- /**
11
- * Load test cache from disk
12
- */ async function loadTestCache(packageDir) {
13
- const cachePath = path__default.join(packageDir, TEST_CACHE_FILE);
14
- try {
15
- const content = await fs.readFile(cachePath, 'utf-8');
16
- return JSON.parse(content);
17
- } catch {
18
- return {};
19
- }
20
- }
21
- /**
22
- * Save test cache to disk
23
- */ async function saveTestCache(packageDir, cache) {
24
- const cachePath = path__default.join(packageDir, TEST_CACHE_FILE);
25
- try {
26
- await fs.writeFile(cachePath, JSON.stringify(cache, null, 2), 'utf-8');
27
- } catch (error) {
28
- logger.debug(`Failed to save test cache: ${error.message}`);
29
- }
30
- }
31
- /**
32
- * Get the current git commit hash
33
- */ async function getCurrentCommitHash(packageDir) {
34
- try {
35
- const { stdout } = await runSecure('git', [
36
- 'rev-parse',
37
- 'HEAD'
38
- ], {
39
- cwd: packageDir
40
- });
41
- return stdout.trim();
42
- } catch {
43
- return null;
44
- }
45
- }
46
- /**
47
- * Check if source files have changed since the last test run
48
- */ async function hasSourceFilesChanged(packageDir, lastCommitHash) {
49
- if (!lastCommitHash) {
50
- return {
51
- changed: true,
52
- reason: 'No previous test run recorded'
53
- };
54
- }
55
- try {
56
- // Get current commit hash
57
- const currentCommitHash = await getCurrentCommitHash(packageDir);
58
- if (!currentCommitHash) {
59
- return {
60
- changed: true,
61
- reason: 'Not in a git repository'
62
- };
63
- }
64
- // If commit hash changed, files definitely changed
65
- if (currentCommitHash !== lastCommitHash) {
66
- return {
67
- changed: true,
68
- reason: `Commit hash changed: ${lastCommitHash.substring(0, 7)} -> ${currentCommitHash.substring(0, 7)}`
69
- };
70
- }
71
- // Check if there are any uncommitted changes to source files
72
- const { stdout } = await runSecure('git', [
73
- 'status',
74
- '--porcelain'
75
- ], {
76
- cwd: packageDir
77
- });
78
- const changedFiles = stdout.split('\n').filter((line)=>line.trim()).map((line)=>line.substring(3).trim()).filter((file)=>{
79
- // Only consider source files, not build artifacts or config files
80
- const ext = path__default.extname(file);
81
- return(// TypeScript/JavaScript source files
82
- [
83
- '.ts',
84
- '.tsx',
85
- '.js',
86
- '.jsx'
87
- ].includes(ext) || // Test files
88
- file.includes('.test.') || file.includes('.spec.') || // Config files that affect build/test
89
- [
90
- 'tsconfig.json',
91
- 'vite.config.ts',
92
- 'vitest.config.ts',
93
- 'package.json'
94
- ].includes(path__default.basename(file)));
95
- });
96
- if (changedFiles.length > 0) {
97
- return {
98
- changed: true,
99
- reason: `Uncommitted changes in: ${changedFiles.slice(0, 3).join(', ')}${changedFiles.length > 3 ? '...' : ''}`
100
- };
101
- }
102
- return {
103
- changed: false,
104
- reason: 'No source file changes detected'
105
- };
106
- } catch (error) {
107
- logger.debug(`Error checking for source file changes: ${error.message}`);
108
- // Conservative: assume changed if we can't verify
109
- return {
110
- changed: true,
111
- reason: `Could not verify changes: ${error.message}`
112
- };
113
- }
114
- }
115
- /**
116
- * Check if dist directory needs to be cleaned (is outdated compared to source files)
117
- */ async function isCleanNeeded(packageDir) {
118
- const storage = createStorage();
119
- const distPath = path__default.join(packageDir, 'dist');
120
- try {
121
- // Check if dist directory exists
122
- const distExists = await storage.exists('dist');
123
- if (!distExists) {
124
- return {
125
- needed: false,
126
- reason: 'dist directory does not exist'
127
- };
128
- }
129
- // Get dist directory modification time
130
- const distStats = await fs.stat(distPath);
131
- const distMtime = distStats.mtimeMs;
132
- // Use git to find source files that are newer than dist
133
- try {
134
- // Get all tracked source files
135
- const { stdout: trackedFiles } = await runSecure('git', [
136
- 'ls-files'
137
- ], {
138
- cwd: packageDir
139
- });
140
- const files = trackedFiles.split('\n').filter(Boolean);
141
- // Check if any source files are newer than dist
142
- for (const file of files){
143
- const ext = path__default.extname(file);
144
- if (![
145
- '.ts',
146
- '.tsx',
147
- '.js',
148
- '.jsx',
149
- '.json'
150
- ].includes(ext)) {
151
- continue;
152
- }
153
- // Skip dist files
154
- if (file.startsWith('dist/')) {
155
- continue;
156
- }
157
- try {
158
- const filePath = path__default.join(packageDir, file);
159
- const fileStats = await fs.stat(filePath);
160
- if (fileStats.mtimeMs > distMtime) {
161
- return {
162
- needed: true,
163
- reason: `${file} is newer than dist directory`
164
- };
165
- }
166
- } catch {
167
- continue;
168
- }
169
- }
170
- return {
171
- needed: false,
172
- reason: 'dist directory is up to date with source files'
173
- };
174
- } catch (error) {
175
- // If git check fails, fall back to checking common source directories
176
- logger.debug(`Git-based check failed, using fallback: ${error.message}`);
177
- const sourceDirs = [
178
- 'src',
179
- 'tests'
180
- ];
181
- for (const dir of sourceDirs){
182
- const dirPath = path__default.join(packageDir, dir);
183
- try {
184
- const dirStats = await fs.stat(dirPath);
185
- if (dirStats.mtimeMs > distMtime) {
186
- return {
187
- needed: true,
188
- reason: `${dir} directory is newer than dist`
189
- };
190
- }
191
- } catch {
192
- continue;
193
- }
194
- }
195
- // Conservative: if we can't verify, assume clean is needed
196
- return {
197
- needed: true,
198
- reason: 'Could not verify dist freshness, cleaning to be safe'
199
- };
200
- }
201
- } catch (error) {
202
- logger.debug(`Error checking if clean is needed: ${error.message}`);
203
- // Conservative: assume clean is needed if we can't check
204
- return {
205
- needed: true,
206
- reason: `Could not verify: ${error.message}`
207
- };
208
- }
209
- }
210
- /**
211
- * Check if tests need to be run (source files changed since last test run)
212
- */ async function isTestNeeded(packageDir) {
213
- try {
214
- // Load test cache
215
- const cache = await loadTestCache(packageDir);
216
- const cacheKey = packageDir;
217
- // Check if we have a cached test run for this package
218
- const cached = cache[cacheKey];
219
- if (!cached) {
220
- return {
221
- needed: true,
222
- reason: 'No previous test run recorded'
223
- };
224
- }
225
- // Check if source files have changed since last test run
226
- const changeCheck = await hasSourceFilesChanged(packageDir, cached.lastCommitHash);
227
- if (changeCheck.changed) {
228
- return {
229
- needed: true,
230
- reason: changeCheck.reason
231
- };
232
- }
233
- return {
234
- needed: false,
235
- reason: 'No source file changes since last test run'
236
- };
237
- } catch (error) {
238
- logger.debug(`Error checking if test is needed: ${error.message}`);
239
- // Conservative: assume test is needed if we can't check
240
- return {
241
- needed: true,
242
- reason: `Could not verify: ${error.message}`
243
- };
244
- }
245
- }
246
- /**
247
- * Record that tests were run for this package
248
- */ async function recordTestRun(packageDir) {
249
- try {
250
- const cache = await loadTestCache(packageDir);
251
- const cacheKey = packageDir;
252
- const commitHash = await getCurrentCommitHash(packageDir);
253
- cache[cacheKey] = {
254
- lastTestRun: Date.now(),
255
- lastCommitHash: commitHash || 'unknown'
256
- };
257
- await saveTestCache(packageDir, cache);
258
- } catch (error) {
259
- logger.debug(`Failed to record test run: ${error.message}`);
260
- }
261
- }
262
- /**
263
- * Optimize a precommit command by skipping unnecessary steps
264
- * Returns the optimized command and information about what was skipped
265
- */ async function optimizePrecommitCommand(packageDir, originalCommand, options = {}) {
266
- const { skipClean = true, skipTest = true } = options;
267
- // Parse the original command to extract individual scripts
268
- // Common patterns: "npm run precommit", "npm run clean && npm run build && npm run lint && npm run test"
269
- const isPrecommitScript = originalCommand.includes('precommit') || originalCommand.includes('pre-commit');
270
- let optimizedCommand = originalCommand;
271
- const skipped = {
272
- clean: false,
273
- test: false
274
- };
275
- const reasons = {};
276
- // If it's a precommit script, we need to check what it actually runs
277
- // For now, we'll optimize the common pattern: clean && build && lint && test
278
- if (isPrecommitScript || originalCommand.includes('clean')) {
279
- if (skipClean) {
280
- const cleanCheck = await isCleanNeeded(packageDir);
281
- if (!cleanCheck.needed) {
282
- // Remove clean from the command
283
- optimizedCommand = optimizedCommand.replace(/npm\s+run\s+clean\s+&&\s*/g, '').replace(/npm\s+run\s+clean\s+/g, '').replace(/\s*&&\s*npm\s+run\s+clean/g, '').trim();
284
- skipped.clean = true;
285
- reasons.clean = cleanCheck.reason;
286
- }
287
- }
288
- }
289
- if (isPrecommitScript || originalCommand.includes('test')) {
290
- if (skipTest) {
291
- const testCheck = await isTestNeeded(packageDir);
292
- if (!testCheck.needed) {
293
- // Remove test from the command
294
- optimizedCommand = optimizedCommand.replace(/\s*&&\s*npm\s+run\s+test\s*/g, '').replace(/\s*&&\s*npm\s+run\s+test$/g, '').replace(/npm\s+run\s+test\s+&&\s*/g, '').trim();
295
- skipped.test = true;
296
- reasons.test = testCheck.reason;
297
- }
298
- }
299
- }
300
- // Clean up any double && or trailing &&
301
- optimizedCommand = optimizedCommand.replace(/\s*&&\s*&&/g, ' && ').replace(/&&\s*$/, '').trim();
302
- return {
303
- optimizedCommand,
304
- skipped,
305
- reasons
306
- };
307
- }
308
-
309
- export { isCleanNeeded, isTestNeeded, optimizePrecommitCommand, recordTestRun };
310
- //# sourceMappingURL=precommitOptimizations.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"precommitOptimizations.js","sources":["../../src/util/precommitOptimizations.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs/promises';\nimport { getLogger } from '../logging';\nimport { runSecure } from '@eldrforge/git-tools';\nimport { createStorage } from '@eldrforge/shared';\n\nconst logger = getLogger();\n\n// Cache file to store test run timestamps per package\nconst TEST_CACHE_FILE = '.kodrdriv-test-cache.json';\n\ninterface TestCache {\n [packagePath: string]: {\n lastTestRun: number; // timestamp\n lastCommitHash: string; // git commit hash when tests last ran\n };\n}\n\n/**\n * Load test cache from disk\n */\nasync function loadTestCache(packageDir: string): Promise<TestCache> {\n const cachePath = path.join(packageDir, TEST_CACHE_FILE);\n try {\n const content = await fs.readFile(cachePath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return {};\n }\n}\n\n/**\n * Save test cache to disk\n */\nasync function saveTestCache(packageDir: string, cache: TestCache): Promise<void> {\n const cachePath = path.join(packageDir, TEST_CACHE_FILE);\n try {\n await fs.writeFile(cachePath, JSON.stringify(cache, null, 2), 'utf-8');\n } catch (error: any) {\n logger.debug(`Failed to save test cache: ${error.message}`);\n }\n}\n\n/**\n * Get the current git commit hash\n */\nasync function getCurrentCommitHash(packageDir: string): Promise<string | null> {\n try {\n const { stdout } = await runSecure('git', ['rev-parse', 'HEAD'], { cwd: packageDir });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Check if source files have changed since the last test run\n */\nasync function hasSourceFilesChanged(\n packageDir: string,\n lastCommitHash: string | null\n): Promise<{ changed: boolean; reason: string }> {\n if (!lastCommitHash) {\n return { changed: true, reason: 'No previous test run recorded' };\n }\n\n try {\n // Get current commit hash\n const currentCommitHash = await getCurrentCommitHash(packageDir);\n if (!currentCommitHash) {\n return { changed: true, reason: 'Not in a git repository' };\n }\n\n // If commit hash changed, files definitely changed\n if (currentCommitHash !== lastCommitHash) {\n return { changed: true, reason: `Commit hash changed: ${lastCommitHash.substring(0, 7)} -> ${currentCommitHash.substring(0, 7)}` };\n }\n\n // Check if there are any uncommitted changes to source files\n const { stdout } = await runSecure('git', ['status', '--porcelain'], { cwd: packageDir });\n const changedFiles = stdout.split('\\n')\n .filter(line => line.trim())\n .map(line => line.substring(3).trim())\n .filter(file => {\n // Only consider source files, not build artifacts or config files\n const ext = path.extname(file);\n return (\n // TypeScript/JavaScript source files\n ['.ts', '.tsx', '.js', '.jsx'].includes(ext) ||\n // Test files\n file.includes('.test.') || file.includes('.spec.') ||\n // Config files that affect build/test\n ['tsconfig.json', 'vite.config.ts', 'vitest.config.ts', 'package.json'].includes(path.basename(file))\n );\n });\n\n if (changedFiles.length > 0) {\n return { changed: true, reason: `Uncommitted changes in: ${changedFiles.slice(0, 3).join(', ')}${changedFiles.length > 3 ? '...' : ''}` };\n }\n\n return { changed: false, reason: 'No source file changes detected' };\n } catch (error: any) {\n logger.debug(`Error checking for source file changes: ${error.message}`);\n // Conservative: assume changed if we can't verify\n return { changed: true, reason: `Could not verify changes: ${error.message}` };\n }\n}\n\n/**\n * Check if dist directory needs to be cleaned (is outdated compared to source files)\n */\nexport async function isCleanNeeded(packageDir: string): Promise<{ needed: boolean; reason: string }> {\n const storage = createStorage();\n const distPath = path.join(packageDir, 'dist');\n\n try {\n // Check if dist directory exists\n const distExists = await storage.exists('dist');\n if (!distExists) {\n return { needed: false, reason: 'dist directory does not exist' };\n }\n\n // Get dist directory modification time\n const distStats = await fs.stat(distPath);\n const distMtime = distStats.mtimeMs;\n\n // Use git to find source files that are newer than dist\n try {\n // Get all tracked source files\n const { stdout: trackedFiles } = await runSecure('git', ['ls-files'], { cwd: packageDir });\n const files = trackedFiles.split('\\n').filter(Boolean);\n\n // Check if any source files are newer than dist\n for (const file of files) {\n const ext = path.extname(file);\n if (!['.ts', '.tsx', '.js', '.jsx', '.json'].includes(ext)) {\n continue;\n }\n\n // Skip dist files\n if (file.startsWith('dist/')) {\n continue;\n }\n\n try {\n const filePath = path.join(packageDir, file);\n const fileStats = await fs.stat(filePath);\n if (fileStats.mtimeMs > distMtime) {\n return { needed: true, reason: `${file} is newer than dist directory` };\n }\n } catch {\n // File might not exist or be inaccessible, skip it\n continue;\n }\n }\n\n return { needed: false, reason: 'dist directory is up to date with source files' };\n } catch (error: any) {\n // If git check fails, fall back to checking common source directories\n logger.debug(`Git-based check failed, using fallback: ${error.message}`);\n\n const sourceDirs = ['src', 'tests'];\n for (const dir of sourceDirs) {\n const dirPath = path.join(packageDir, dir);\n try {\n const dirStats = await fs.stat(dirPath);\n if (dirStats.mtimeMs > distMtime) {\n return { needed: true, reason: `${dir} directory is newer than dist` };\n }\n } catch {\n // Directory doesn't exist, skip it\n continue;\n }\n }\n\n // Conservative: if we can't verify, assume clean is needed\n return { needed: true, reason: 'Could not verify dist freshness, cleaning to be safe' };\n }\n } catch (error: any) {\n logger.debug(`Error checking if clean is needed: ${error.message}`);\n // Conservative: assume clean is needed if we can't check\n return { needed: true, reason: `Could not verify: ${error.message}` };\n }\n}\n\n/**\n * Check if tests need to be run (source files changed since last test run)\n */\nexport async function isTestNeeded(packageDir: string): Promise<{ needed: boolean; reason: string }> {\n try {\n // Load test cache\n const cache = await loadTestCache(packageDir);\n const cacheKey = packageDir;\n\n // Check if we have a cached test run for this package\n const cached = cache[cacheKey];\n if (!cached) {\n return { needed: true, reason: 'No previous test run recorded' };\n }\n\n // Check if source files have changed since last test run\n const changeCheck = await hasSourceFilesChanged(packageDir, cached.lastCommitHash);\n if (changeCheck.changed) {\n return { needed: true, reason: changeCheck.reason };\n }\n\n return { needed: false, reason: 'No source file changes since last test run' };\n } catch (error: any) {\n logger.debug(`Error checking if test is needed: ${error.message}`);\n // Conservative: assume test is needed if we can't check\n return { needed: true, reason: `Could not verify: ${error.message}` };\n }\n}\n\n/**\n * Record that tests were run for this package\n */\nexport async function recordTestRun(packageDir: string): Promise<void> {\n try {\n const cache = await loadTestCache(packageDir);\n const cacheKey = packageDir;\n const commitHash = await getCurrentCommitHash(packageDir);\n\n cache[cacheKey] = {\n lastTestRun: Date.now(),\n lastCommitHash: commitHash || 'unknown'\n };\n\n await saveTestCache(packageDir, cache);\n } catch (error: any) {\n logger.debug(`Failed to record test run: ${error.message}`);\n }\n}\n\n/**\n * Optimize a precommit command by skipping unnecessary steps\n * Returns the optimized command and information about what was skipped\n */\nexport async function optimizePrecommitCommand(\n packageDir: string,\n originalCommand: string,\n options: { skipClean?: boolean; skipTest?: boolean } = {}\n): Promise<{\n optimizedCommand: string;\n skipped: {\n clean: boolean;\n test: boolean;\n };\n reasons: {\n clean?: string;\n test?: string;\n };\n}> {\n const { skipClean = true, skipTest = true } = options;\n\n // Parse the original command to extract individual scripts\n // Common patterns: \"npm run precommit\", \"npm run clean && npm run build && npm run lint && npm run test\"\n const isPrecommitScript = originalCommand.includes('precommit') || originalCommand.includes('pre-commit');\n\n let optimizedCommand = originalCommand;\n const skipped = { clean: false, test: false };\n const reasons: { clean?: string; test?: string } = {};\n\n // If it's a precommit script, we need to check what it actually runs\n // For now, we'll optimize the common pattern: clean && build && lint && test\n if (isPrecommitScript || originalCommand.includes('clean')) {\n if (skipClean) {\n const cleanCheck = await isCleanNeeded(packageDir);\n if (!cleanCheck.needed) {\n // Remove clean from the command\n optimizedCommand = optimizedCommand\n .replace(/npm\\s+run\\s+clean\\s+&&\\s*/g, '')\n .replace(/npm\\s+run\\s+clean\\s+/g, '')\n .replace(/\\s*&&\\s*npm\\s+run\\s+clean/g, '')\n .trim();\n skipped.clean = true;\n reasons.clean = cleanCheck.reason;\n }\n }\n }\n\n if (isPrecommitScript || originalCommand.includes('test')) {\n if (skipTest) {\n const testCheck = await isTestNeeded(packageDir);\n if (!testCheck.needed) {\n // Remove test from the command\n optimizedCommand = optimizedCommand\n .replace(/\\s*&&\\s*npm\\s+run\\s+test\\s*/g, '')\n .replace(/\\s*&&\\s*npm\\s+run\\s+test$/g, '')\n .replace(/npm\\s+run\\s+test\\s+&&\\s*/g, '')\n .trim();\n skipped.test = true;\n reasons.test = testCheck.reason;\n }\n }\n }\n\n // Clean up any double && or trailing &&\n optimizedCommand = optimizedCommand.replace(/\\s*&&\\s*&&/g, ' && ').replace(/&&\\s*$/, '').trim();\n\n return { optimizedCommand, skipped, reasons };\n}\n\n"],"names":["logger","getLogger","TEST_CACHE_FILE","loadTestCache","packageDir","cachePath","path","join","content","fs","readFile","JSON","parse","saveTestCache","cache","writeFile","stringify","error","debug","message","getCurrentCommitHash","stdout","runSecure","cwd","trim","hasSourceFilesChanged","lastCommitHash","changed","reason","currentCommitHash","substring","changedFiles","split","filter","line","map","file","ext","extname","includes","basename","length","slice","isCleanNeeded","storage","createStorage","distPath","distExists","exists","needed","distStats","stat","distMtime","mtimeMs","trackedFiles","files","Boolean","startsWith","filePath","fileStats","sourceDirs","dir","dirPath","dirStats","isTestNeeded","cacheKey","cached","changeCheck","recordTestRun","commitHash","lastTestRun","Date","now","optimizePrecommitCommand","originalCommand","options","skipClean","skipTest","isPrecommitScript","optimizedCommand","skipped","clean","test","reasons","cleanCheck","replace","testCheck"],"mappings":"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"}
@@ -1,146 +0,0 @@
1
- import { getLogger } from '../logging.js';
2
-
3
- /**
4
- * Compile stop-context configuration into efficient filter rules
5
- */ function compileFilters(config) {
6
- const filters = [];
7
- const replacement = config.replacement || '[REDACTED]';
8
- var _config_caseSensitive;
9
- const caseSensitive = (_config_caseSensitive = config.caseSensitive) !== null && _config_caseSensitive !== void 0 ? _config_caseSensitive : false;
10
- // Compile literal string filters
11
- if (config.strings && config.strings.length > 0) {
12
- for (const str of config.strings){
13
- filters.push({
14
- type: 'string',
15
- value: str,
16
- replacement,
17
- caseSensitive
18
- });
19
- }
20
- }
21
- // Compile regex pattern filters
22
- if (config.patterns && config.patterns.length > 0) {
23
- for (const pattern of config.patterns){
24
- try {
25
- const flags = pattern.flags || (caseSensitive ? 'g' : 'gi');
26
- const regex = new RegExp(pattern.regex, flags);
27
- filters.push({
28
- type: 'pattern',
29
- value: regex,
30
- replacement,
31
- caseSensitive
32
- });
33
- } catch (error) {
34
- const logger = getLogger();
35
- logger.warn(`STOP_CONTEXT_INVALID_PATTERN: Failed to compile regex pattern | Pattern: ${pattern.regex} | Error: ${error instanceof Error ? error.message : String(error)} | Action: Skipping pattern`);
36
- }
37
- }
38
- }
39
- return filters;
40
- }
41
- /**
42
- * Apply a single filter to text and track matches
43
- */ function applyFilter(text, filter, matches) {
44
- if (filter.type === 'string') {
45
- const searchStr = filter.value;
46
- const flags = filter.caseSensitive ? 'g' : 'gi';
47
- const regex = new RegExp(escapeRegExp(searchStr), flags);
48
- let match;
49
- while((match = regex.exec(text)) !== null){
50
- matches.push({
51
- type: 'string',
52
- matched: match[0],
53
- position: match.index,
54
- replacement: filter.replacement
55
- });
56
- }
57
- return text.replace(regex, filter.replacement);
58
- } else {
59
- // Pattern filter
60
- const regex = filter.value;
61
- let match;
62
- // Reset regex lastIndex to ensure we start from beginning
63
- regex.lastIndex = 0;
64
- while((match = regex.exec(text)) !== null){
65
- matches.push({
66
- type: 'pattern',
67
- matched: match[0],
68
- position: match.index,
69
- replacement: filter.replacement
70
- });
71
- }
72
- // Reset regex lastIndex again before replace
73
- regex.lastIndex = 0;
74
- return text.replace(regex, filter.replacement);
75
- }
76
- }
77
- /**
78
- * Escape special regex characters in a string
79
- */ function escapeRegExp(str) {
80
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
81
- }
82
- /**
83
- * Filter content based on stop-context configuration
84
- *
85
- * @param text - The text to filter
86
- * @param config - The stop-context configuration
87
- * @returns FilterResult with filtered text and metadata
88
- */ function filterContent(text, config) {
89
- const logger = getLogger();
90
- // If no config or disabled, return original text
91
- if (!config || config.enabled === false) {
92
- return {
93
- filtered: text,
94
- originalLength: text.length,
95
- filteredLength: text.length,
96
- matchCount: 0,
97
- matches: []
98
- };
99
- }
100
- const filters = compileFilters(config);
101
- // If no filters configured, return original text
102
- if (filters.length === 0) {
103
- return {
104
- filtered: text,
105
- originalLength: text.length,
106
- filteredLength: text.length,
107
- matchCount: 0,
108
- matches: []
109
- };
110
- }
111
- let filtered = text;
112
- const allMatches = [];
113
- // Apply each filter in sequence
114
- for (const filter of filters){
115
- filtered = applyFilter(filtered, filter, allMatches);
116
- }
117
- const result = {
118
- filtered,
119
- originalLength: text.length,
120
- filteredLength: filtered.length,
121
- matchCount: allMatches.length,
122
- matches: allMatches
123
- };
124
- // Log warning if filters were applied and warnOnFilter is enabled
125
- if (config.warnOnFilter !== false && allMatches.length > 0) {
126
- logger.warn(`STOP_CONTEXT_FILTERED: Sensitive content filtered from generated text | Matches: ${allMatches.length} | Original Length: ${text.length} | Filtered Length: ${filtered.length} | Action: Review filtered content`);
127
- // Log verbose details if logger level is verbose or debug
128
- if (logger.level === 'verbose' || logger.level === 'debug') {
129
- logger.verbose('STOP_CONTEXT_DETAILS: Filter details:');
130
- const stringMatches = allMatches.filter((m)=>m.type === 'string').length;
131
- const patternMatches = allMatches.filter((m)=>m.type === 'pattern').length;
132
- logger.verbose(` - String matches: ${stringMatches}`);
133
- logger.verbose(` - Pattern matches: ${patternMatches}`);
134
- logger.verbose(` - Character change: ${text.length - filtered.length} characters removed`);
135
- }
136
- }
137
- // Warn if too much content was filtered
138
- const percentFiltered = (text.length - filtered.length) / text.length * 100;
139
- if (percentFiltered > 50) {
140
- logger.warn(`STOP_CONTEXT_HIGH_FILTER: High percentage of content filtered | Percentage: ${percentFiltered.toFixed(1)}% | Impact: Generated content may be incomplete | Action: Review stop-context configuration`);
141
- }
142
- return result;
143
- }
144
-
145
- export { filterContent };
146
- //# sourceMappingURL=stopContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stopContext.js","sources":["../../src/util/stopContext.ts"],"sourcesContent":["import { StopContextConfig } from '../types';\nimport { getLogger } from '../logging';\n\nexport interface FilterResult {\n filtered: string;\n originalLength: number;\n filteredLength: number;\n matchCount: number;\n matches: FilterMatch[];\n}\n\nexport interface FilterMatch {\n type: 'string' | 'pattern';\n matched: string;\n position: number;\n replacement: string;\n}\n\ninterface CompiledFilter {\n type: 'string' | 'pattern';\n value: string | RegExp;\n replacement: string;\n caseSensitive: boolean;\n}\n\n/**\n * Compile stop-context configuration into efficient filter rules\n */\nfunction compileFilters(config: StopContextConfig): CompiledFilter[] {\n const filters: CompiledFilter[] = [];\n const replacement = config.replacement || '[REDACTED]';\n const caseSensitive = config.caseSensitive ?? false;\n\n // Compile literal string filters\n if (config.strings && config.strings.length > 0) {\n for (const str of config.strings) {\n filters.push({\n type: 'string',\n value: str,\n replacement,\n caseSensitive,\n });\n }\n }\n\n // Compile regex pattern filters\n if (config.patterns && config.patterns.length > 0) {\n for (const pattern of config.patterns) {\n try {\n const flags = pattern.flags || (caseSensitive ? 'g' : 'gi');\n const regex = new RegExp(pattern.regex, flags);\n filters.push({\n type: 'pattern',\n value: regex,\n replacement,\n caseSensitive,\n });\n } catch (error) {\n const logger = getLogger();\n logger.warn(`STOP_CONTEXT_INVALID_PATTERN: Failed to compile regex pattern | Pattern: ${pattern.regex} | Error: ${error instanceof Error ? error.message : String(error)} | Action: Skipping pattern`);\n }\n }\n }\n\n return filters;\n}\n\n/**\n * Apply a single filter to text and track matches\n */\nfunction applyFilter(\n text: string,\n filter: CompiledFilter,\n matches: FilterMatch[]\n): string {\n if (filter.type === 'string') {\n const searchStr = filter.value as string;\n const flags = filter.caseSensitive ? 'g' : 'gi';\n const regex = new RegExp(escapeRegExp(searchStr), flags);\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n matches.push({\n type: 'string',\n matched: match[0],\n position: match.index,\n replacement: filter.replacement,\n });\n }\n\n return text.replace(regex, filter.replacement);\n } else {\n // Pattern filter\n const regex = filter.value as RegExp;\n let match: RegExpExecArray | null;\n\n // Reset regex lastIndex to ensure we start from beginning\n regex.lastIndex = 0;\n\n while ((match = regex.exec(text)) !== null) {\n matches.push({\n type: 'pattern',\n matched: match[0],\n position: match.index,\n replacement: filter.replacement,\n });\n }\n\n // Reset regex lastIndex again before replace\n regex.lastIndex = 0;\n return text.replace(regex, filter.replacement);\n }\n}\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Filter content based on stop-context configuration\n *\n * @param text - The text to filter\n * @param config - The stop-context configuration\n * @returns FilterResult with filtered text and metadata\n */\nexport function filterContent(text: string, config: StopContextConfig | undefined): FilterResult {\n const logger = getLogger();\n\n // If no config or disabled, return original text\n if (!config || config.enabled === false) {\n return {\n filtered: text,\n originalLength: text.length,\n filteredLength: text.length,\n matchCount: 0,\n matches: [],\n };\n }\n\n const filters = compileFilters(config);\n\n // If no filters configured, return original text\n if (filters.length === 0) {\n return {\n filtered: text,\n originalLength: text.length,\n filteredLength: text.length,\n matchCount: 0,\n matches: [],\n };\n }\n\n let filtered = text;\n const allMatches: FilterMatch[] = [];\n\n // Apply each filter in sequence\n for (const filter of filters) {\n filtered = applyFilter(filtered, filter, allMatches);\n }\n\n const result: FilterResult = {\n filtered,\n originalLength: text.length,\n filteredLength: filtered.length,\n matchCount: allMatches.length,\n matches: allMatches,\n };\n\n // Log warning if filters were applied and warnOnFilter is enabled\n if (config.warnOnFilter !== false && allMatches.length > 0) {\n logger.warn(`STOP_CONTEXT_FILTERED: Sensitive content filtered from generated text | Matches: ${allMatches.length} | Original Length: ${text.length} | Filtered Length: ${filtered.length} | Action: Review filtered content`);\n\n // Log verbose details if logger level is verbose or debug\n if (logger.level === 'verbose' || logger.level === 'debug') {\n logger.verbose('STOP_CONTEXT_DETAILS: Filter details:');\n const stringMatches = allMatches.filter(m => m.type === 'string').length;\n const patternMatches = allMatches.filter(m => m.type === 'pattern').length;\n logger.verbose(` - String matches: ${stringMatches}`);\n logger.verbose(` - Pattern matches: ${patternMatches}`);\n logger.verbose(` - Character change: ${text.length - filtered.length} characters removed`);\n }\n }\n\n // Warn if too much content was filtered\n const percentFiltered = ((text.length - filtered.length) / text.length) * 100;\n if (percentFiltered > 50) {\n logger.warn(`STOP_CONTEXT_HIGH_FILTER: High percentage of content filtered | Percentage: ${percentFiltered.toFixed(1)}% | Impact: Generated content may be incomplete | Action: Review stop-context configuration`);\n }\n\n return result;\n}\n\n/**\n * Check if stop-context filtering is enabled in config\n */\nexport function isStopContextEnabled(config: StopContextConfig | undefined): boolean {\n if (!config) {\n return false;\n }\n\n const hasFilters = (config.strings && config.strings.length > 0) ||\n (config.patterns && config.patterns.length > 0);\n\n return Boolean(config.enabled !== false && hasFilters);\n}\n\n"],"names":["compileFilters","config","filters","replacement","caseSensitive","strings","length","str","push","type","value","patterns","pattern","flags","regex","RegExp","error","logger","getLogger","warn","Error","message","String","applyFilter","text","filter","matches","searchStr","escapeRegExp","match","exec","matched","position","index","replace","lastIndex","filterContent","enabled","filtered","originalLength","filteredLength","matchCount","allMatches","result","warnOnFilter","level","verbose","stringMatches","m","patternMatches","percentFiltered","toFixed"],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import { createStorage } from '@eldrforge/shared';
2
- import path__default from 'path';
3
-
4
- /**
5
- * Create a StorageAdapter implementation using kodrdriv Storage
6
- *
7
- * @param outputDirectory - Directory where output files should be written (default: 'output')
8
- */ function createStorageAdapter(outputDirectory = 'output') {
9
- const storage = createStorage();
10
- return {
11
- async writeOutput (fileName, content) {
12
- // Ensure output directory exists
13
- await storage.ensureDirectory(outputDirectory);
14
- // Write file to output directory
15
- const filePath = path__default.join(outputDirectory, fileName);
16
- await storage.writeFile(filePath, content, 'utf8');
17
- },
18
- async readTemp (fileName) {
19
- return await storage.readFile(fileName, 'utf8');
20
- },
21
- async writeTemp (fileName, content) {
22
- await storage.writeFile(fileName, content, 'utf8');
23
- },
24
- async readFile (fileName, encoding = 'utf8') {
25
- return await storage.readFile(fileName, encoding);
26
- }
27
- };
28
- }
29
-
30
- export { createStorageAdapter };
31
- //# sourceMappingURL=storageAdapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storageAdapter.js","sources":["../../src/util/storageAdapter.ts"],"sourcesContent":["/**\n * Adapter for ai-service StorageAdapter using kodrdriv Storage\n */\n\nimport type { StorageAdapter } from '@eldrforge/ai-service';\nimport { createStorage } from '@eldrforge/shared';\nimport path from 'path';\n\n/**\n * Create a StorageAdapter implementation using kodrdriv Storage\n *\n * @param outputDirectory - Directory where output files should be written (default: 'output')\n */\nexport function createStorageAdapter(outputDirectory: string = 'output'): StorageAdapter {\n const storage = createStorage();\n\n return {\n async writeOutput(fileName: string, content: string): Promise<void> {\n // Ensure output directory exists\n await storage.ensureDirectory(outputDirectory);\n\n // Write file to output directory\n const filePath = path.join(outputDirectory, fileName);\n await storage.writeFile(filePath, content, 'utf8');\n },\n\n async readTemp(fileName: string): Promise<string> {\n return await storage.readFile(fileName, 'utf8');\n },\n\n async writeTemp(fileName: string, content: string): Promise<void> {\n await storage.writeFile(fileName, content, 'utf8');\n },\n\n async readFile(fileName: string, encoding: string = 'utf8'): Promise<string> {\n return await storage.readFile(fileName, encoding);\n },\n };\n}\n\n"],"names":["createStorageAdapter","outputDirectory","storage","createStorage","writeOutput","fileName","content","ensureDirectory","filePath","path","join","writeFile","readTemp","readFile","writeTemp","encoding"],"mappings":";;;AAQA;;;;AAIC,IACM,SAASA,oBAAAA,CAAqBC,eAAAA,GAA0B,QAAQ,EAAA;AACnE,IAAA,MAAMC,OAAAA,GAAUC,aAAAA,EAAAA;IAEhB,OAAO;QACH,MAAMC,WAAAA,CAAAA,CAAYC,QAAgB,EAAEC,OAAe,EAAA;;YAE/C,MAAMJ,OAAAA,CAAQK,eAAe,CAACN,eAAAA,CAAAA;;AAG9B,YAAA,MAAMO,QAAAA,GAAWC,aAAAA,CAAKC,IAAI,CAACT,eAAAA,EAAiBI,QAAAA,CAAAA;AAC5C,YAAA,MAAMH,OAAAA,CAAQS,SAAS,CAACH,QAAAA,EAAUF,OAAAA,EAAS,MAAA,CAAA;AAC/C,QAAA,CAAA;AAEA,QAAA,MAAMM,UAASP,QAAgB,EAAA;AAC3B,YAAA,OAAO,MAAMH,OAAAA,CAAQW,QAAQ,CAACR,QAAAA,EAAU,MAAA,CAAA;AAC5C,QAAA,CAAA;QAEA,MAAMS,SAAAA,CAAAA,CAAUT,QAAgB,EAAEC,OAAe,EAAA;AAC7C,YAAA,MAAMJ,OAAAA,CAAQS,SAAS,CAACN,QAAAA,EAAUC,OAAAA,EAAS,MAAA,CAAA;AAC/C,QAAA,CAAA;AAEA,QAAA,MAAMO,QAAAA,CAAAA,CAASR,QAAgB,EAAEU,QAAAA,GAAmB,MAAM,EAAA;AACtD,YAAA,OAAO,MAAMb,OAAAA,CAAQW,QAAQ,CAACR,QAAAA,EAAUU,QAAAA,CAAAA;AAC5C,QAAA;AACJ,KAAA;AACJ;;;;"}
@@ -1,45 +0,0 @@
1
- /**
2
- * Kodrdriv-specific validation utilities
3
- *
4
- * Note: Generic validation functions (validateString, validateNumber, etc.)
5
- * are in @eldrforge/shared
6
- */ /**
7
- * Validates and safely casts data to ReleaseSummary type
8
- */ const validateReleaseSummary = (data)=>{
9
- if (!data || typeof data !== 'object') {
10
- throw new Error('Invalid release summary: not an object');
11
- }
12
- if (typeof data.title !== 'string') {
13
- throw new Error('Invalid release summary: title must be a string');
14
- }
15
- if (typeof data.body !== 'string') {
16
- throw new Error('Invalid release summary: body must be a string');
17
- }
18
- return data;
19
- };
20
- /**
21
- * Sanitizes and truncates direction parameter for safe use in prompts
22
- * @param direction The direction string to sanitize
23
- * @param maxLength Maximum length before truncation (default: 2000)
24
- * @returns Sanitized and truncated direction string
25
- */ const sanitizeDirection = (direction, maxLength = 2000)=>{
26
- if (!direction) {
27
- return undefined;
28
- }
29
- // Remove newlines and excessive whitespace to prevent template breakage
30
- const sanitized = direction.replace(/\r?\n/g, ' ') // Replace newlines with spaces
31
- .replace(/\s+/g, ' ') // Replace multiple whitespace with single space
32
- .trim();
33
- // Truncate if too long
34
- if (sanitized.length > maxLength) {
35
- const truncated = sanitized.substring(0, maxLength - 3) + '...';
36
- // Log truncation for debugging
37
- // eslint-disable-next-line no-console
38
- console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);
39
- return truncated;
40
- }
41
- return sanitized;
42
- };
43
-
44
- export { sanitizeDirection, validateReleaseSummary };
45
- //# sourceMappingURL=validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.js","sources":["../../src/util/validation.ts"],"sourcesContent":["/**\n * Kodrdriv-specific validation utilities\n *\n * Note: Generic validation functions (validateString, validateNumber, etc.)\n * are in @eldrforge/shared\n */\n\nexport interface ReleaseSummary {\n title: string;\n body: string;\n}\n\nexport interface TranscriptionResult {\n text: string;\n [key: string]: any;\n}\n\n/**\n * Validates and safely casts data to ReleaseSummary type\n */\nexport const validateReleaseSummary = (data: any): ReleaseSummary => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid release summary: not an object');\n }\n if (typeof data.title !== 'string') {\n throw new Error('Invalid release summary: title must be a string');\n }\n if (typeof data.body !== 'string') {\n throw new Error('Invalid release summary: body must be a string');\n }\n return data as ReleaseSummary;\n};\n\n/**\n * Validates transcription result has required text property\n */\nexport const validateTranscriptionResult = (data: any): TranscriptionResult => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid transcription result: not an object');\n }\n if (typeof data.text !== 'string') {\n throw new Error('Invalid transcription result: text property must be a string');\n }\n return data as TranscriptionResult;\n};\n\n/**\n * Sanitizes and truncates direction parameter for safe use in prompts\n * @param direction The direction string to sanitize\n * @param maxLength Maximum length before truncation (default: 2000)\n * @returns Sanitized and truncated direction string\n */\nexport const sanitizeDirection = (direction: string | undefined, maxLength: number = 2000): string | undefined => {\n if (!direction) {\n return undefined;\n }\n\n // Remove newlines and excessive whitespace to prevent template breakage\n const sanitized = direction\n .replace(/\\r?\\n/g, ' ') // Replace newlines with spaces\n .replace(/\\s+/g, ' ') // Replace multiple whitespace with single space\n .trim();\n\n // Truncate if too long\n if (sanitized.length > maxLength) {\n const truncated = sanitized.substring(0, maxLength - 3) + '...';\n // Log truncation for debugging\n // eslint-disable-next-line no-console\n console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);\n return truncated;\n }\n\n return sanitized;\n};\n\n"],"names":["validateReleaseSummary","data","Error","title","body","sanitizeDirection","direction","maxLength","undefined","sanitized","replace","trim","length","truncated","substring","console","warn"],"mappings":"AAAA;;;;;;;IAoBO,MAAMA,sBAAAA,GAAyB,CAACC,IAAAA,GAAAA;AACnC,IAAA,IAAI,CAACA,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;AACnC,QAAA,MAAM,IAAIC,KAAAA,CAAM,wCAAA,CAAA;AACpB,IAAA;AACA,IAAA,IAAI,OAAOD,IAAAA,CAAKE,KAAK,KAAK,QAAA,EAAU;AAChC,QAAA,MAAM,IAAID,KAAAA,CAAM,iDAAA,CAAA;AACpB,IAAA;AACA,IAAA,IAAI,OAAOD,IAAAA,CAAKG,IAAI,KAAK,QAAA,EAAU;AAC/B,QAAA,MAAM,IAAIF,KAAAA,CAAM,gDAAA,CAAA;AACpB,IAAA;IACA,OAAOD,IAAAA;AACX;AAeA;;;;;AAKC,IACM,MAAMI,iBAAAA,GAAoB,CAACC,SAAAA,EAA+BC,YAAoB,IAAI,GAAA;AACrF,IAAA,IAAI,CAACD,SAAAA,EAAW;QACZ,OAAOE,SAAAA;AACX,IAAA;;AAGA,IAAA,MAAMC,YAAYH,SAAAA,CACbI,OAAO,CAAC,QAAA,EAAU;KAClBA,OAAO,CAAC,MAAA,EAAQ,GAAA,CAAA;KAChBC,IAAI,EAAA;;IAGT,IAAIF,SAAAA,CAAUG,MAAM,GAAGL,SAAAA,EAAW;AAC9B,QAAA,MAAMM,YAAYJ,SAAAA,CAAUK,SAAS,CAAC,CAAA,EAAGP,YAAY,CAAA,CAAA,GAAK,KAAA;;;AAG1DQ,QAAAA,OAAAA,CAAQC,IAAI,CAAC,CAAC,yBAAyB,EAAEP,SAAAA,CAAUG,MAAM,CAAC,IAAI,EAAEC,SAAAA,CAAUD,MAAM,CAAC,WAAW,CAAC,CAAA;QAC7F,OAAOC,SAAAA;AACX,IAAA;IAEA,OAAOJ,SAAAA;AACX;;;;"}