@etheaven/codex-mcp-server 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.claude-plugin/marketplace.json +26 -0
  2. package/.claude-plugin/plugin.json +13 -0
  3. package/.mcp.json +8 -0
  4. package/LICENSE +21 -0
  5. package/README.md +450 -0
  6. package/dist/constants.d.ts +165 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +154 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +195 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/tools/ask-codex.tool.d.ts +3 -0
  15. package/dist/tools/ask-codex.tool.d.ts.map +1 -0
  16. package/dist/tools/ask-codex.tool.js +263 -0
  17. package/dist/tools/ask-codex.tool.js.map +1 -0
  18. package/dist/tools/batch-codex.tool.d.ts +3 -0
  19. package/dist/tools/batch-codex.tool.d.ts.map +1 -0
  20. package/dist/tools/batch-codex.tool.js +140 -0
  21. package/dist/tools/batch-codex.tool.js.map +1 -0
  22. package/dist/tools/brainstorm.tool.d.ts +3 -0
  23. package/dist/tools/brainstorm.tool.d.ts.map +1 -0
  24. package/dist/tools/brainstorm.tool.js +171 -0
  25. package/dist/tools/brainstorm.tool.js.map +1 -0
  26. package/dist/tools/fetch-chunk.tool.d.ts +3 -0
  27. package/dist/tools/fetch-chunk.tool.d.ts.map +1 -0
  28. package/dist/tools/fetch-chunk.tool.js +66 -0
  29. package/dist/tools/fetch-chunk.tool.js.map +1 -0
  30. package/dist/tools/index.d.ts +2 -0
  31. package/dist/tools/index.d.ts.map +1 -0
  32. package/dist/tools/index.js +14 -0
  33. package/dist/tools/index.js.map +1 -0
  34. package/dist/tools/registry.d.ts +25 -0
  35. package/dist/tools/registry.d.ts.map +1 -0
  36. package/dist/tools/registry.js +84 -0
  37. package/dist/tools/registry.js.map +1 -0
  38. package/dist/tools/simple-tools.d.ts +5 -0
  39. package/dist/tools/simple-tools.d.ts.map +1 -0
  40. package/dist/tools/simple-tools.js +64 -0
  41. package/dist/tools/simple-tools.js.map +1 -0
  42. package/dist/tools/test-tool.example.d.ts +13 -0
  43. package/dist/tools/test-tool.example.d.ts.map +1 -0
  44. package/dist/tools/test-tool.example.js +34 -0
  45. package/dist/tools/test-tool.example.js.map +1 -0
  46. package/dist/tools/timeout-test.tool.d.ts +3 -0
  47. package/dist/tools/timeout-test.tool.d.ts.map +1 -0
  48. package/dist/tools/timeout-test.tool.js +32 -0
  49. package/dist/tools/timeout-test.tool.js.map +1 -0
  50. package/dist/utils/changeModeChunker.d.ts +11 -0
  51. package/dist/utils/changeModeChunker.d.ts.map +1 -0
  52. package/dist/utils/changeModeChunker.js +93 -0
  53. package/dist/utils/changeModeChunker.js.map +1 -0
  54. package/dist/utils/changeModeParser.d.ts +15 -0
  55. package/dist/utils/changeModeParser.d.ts.map +1 -0
  56. package/dist/utils/changeModeParser.js +67 -0
  57. package/dist/utils/changeModeParser.js.map +1 -0
  58. package/dist/utils/changeModeRunner.d.ts +11 -0
  59. package/dist/utils/changeModeRunner.d.ts.map +1 -0
  60. package/dist/utils/changeModeRunner.js +133 -0
  61. package/dist/utils/changeModeRunner.js.map +1 -0
  62. package/dist/utils/changeModeTranslator.d.ts +8 -0
  63. package/dist/utils/changeModeTranslator.d.ts.map +1 -0
  64. package/dist/utils/changeModeTranslator.js +69 -0
  65. package/dist/utils/changeModeTranslator.js.map +1 -0
  66. package/dist/utils/chunkCache.d.ts +22 -0
  67. package/dist/utils/chunkCache.d.ts.map +1 -0
  68. package/dist/utils/chunkCache.js +163 -0
  69. package/dist/utils/chunkCache.js.map +1 -0
  70. package/dist/utils/codexExecutor.d.ts +47 -0
  71. package/dist/utils/codexExecutor.d.ts.map +1 -0
  72. package/dist/utils/codexExecutor.js +296 -0
  73. package/dist/utils/codexExecutor.js.map +1 -0
  74. package/dist/utils/commandExecutor.d.ts +29 -0
  75. package/dist/utils/commandExecutor.d.ts.map +1 -0
  76. package/dist/utils/commandExecutor.js +158 -0
  77. package/dist/utils/commandExecutor.js.map +1 -0
  78. package/dist/utils/logger.d.ts +20 -0
  79. package/dist/utils/logger.d.ts.map +1 -0
  80. package/dist/utils/logger.js +83 -0
  81. package/dist/utils/logger.js.map +1 -0
  82. package/dist/utils/outputParser.d.ts +26 -0
  83. package/dist/utils/outputParser.d.ts.map +1 -0
  84. package/dist/utils/outputParser.js +174 -0
  85. package/dist/utils/outputParser.js.map +1 -0
  86. package/dist/utils/reviewParser.d.ts +28 -0
  87. package/dist/utils/reviewParser.d.ts.map +1 -0
  88. package/dist/utils/reviewParser.js +87 -0
  89. package/dist/utils/reviewParser.js.map +1 -0
  90. package/dist/utils/workingDirResolver.d.ts +47 -0
  91. package/dist/utils/workingDirResolver.d.ts.map +1 -0
  92. package/dist/utils/workingDirResolver.js +199 -0
  93. package/dist/utils/workingDirResolver.js.map +1 -0
  94. package/package.json +79 -0
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+ import { executeCommand } from '../utils/commandExecutor.js';
3
+ const pingArgsSchema = z.object({
4
+ prompt: z.string().default('').describe('Message to echo '),
5
+ });
6
+ export const pingTool = {
7
+ name: 'ping',
8
+ description: 'Echo',
9
+ zodSchema: pingArgsSchema,
10
+ prompt: {
11
+ description: 'Echo test message with structured response.',
12
+ },
13
+ category: 'simple',
14
+ execute: async (args, onProgress) => {
15
+ const message = args.prompt || args.message || 'Pong!';
16
+ // Return message directly to avoid cross-platform issues with echo command
17
+ return message;
18
+ },
19
+ };
20
+ const helpArgsSchema = z.object({});
21
+ export const helpTool = {
22
+ name: 'Help',
23
+ description: 'receive help information',
24
+ zodSchema: helpArgsSchema,
25
+ prompt: {
26
+ description: 'receive help information',
27
+ },
28
+ category: 'simple',
29
+ execute: async (args, onProgress) => {
30
+ return executeCommand('codex', ['--help'], onProgress);
31
+ },
32
+ };
33
+ const versionArgsSchema = z.object({});
34
+ export const versionTool = {
35
+ name: 'version',
36
+ description: 'Display version and system information',
37
+ zodSchema: versionArgsSchema,
38
+ prompt: {
39
+ description: 'Get version information for Codex CLI and MCP server',
40
+ },
41
+ category: 'simple',
42
+ execute: async (args, onProgress) => {
43
+ try {
44
+ const codexVersion = await executeCommand('codex', ['--version'], onProgress);
45
+ const nodeVersion = process.version;
46
+ const platform = process.platform;
47
+ return `**System Information:**
48
+ - Codex CLI: ${codexVersion.trim()}
49
+ - Node.js: ${nodeVersion}
50
+ - Platform: ${platform}
51
+ - MCP Server: @etheaven/codex-mcp-server v1.2.5`;
52
+ }
53
+ catch (error) {
54
+ return `**System Information:**
55
+ - Codex CLI: Not installed or not accessible
56
+ - Node.js: ${process.version}
57
+ - Platform: ${process.platform}
58
+ - MCP Server: @etheaven/codex-mcp-server v1.2.4
59
+
60
+ *Note: Install Codex CLI with: npm install -g @openai/codex*`;
61
+ }
62
+ },
63
+ };
64
+ //# sourceMappingURL=simple-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-tools.js","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,MAAM;IACnB,SAAS,EAAE,cAAc;IACzB,MAAM,EAAE;QACN,WAAW,EAAE,6CAA6C;KAC3D;IACD,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;QACvD,2EAA2E;QAC3E,OAAO,OAAiB,CAAC;IAC3B,CAAC;CACF,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEpC,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,0BAA0B;IACvC,SAAS,EAAE,cAAc;IACzB,MAAM,EAAE;QACN,WAAW,EAAE,0BAA0B;KACxC;IACD,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,OAAO,cAAc,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,wCAAwC;IACrD,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE;QACN,WAAW,EAAE,sDAAsD;KACpE;IACD,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC;YAC9E,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;YACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;YAElC,OAAO;eACE,YAAY,CAAC,IAAI,EAAE;aACrB,WAAW;cACV,QAAQ;gDAC0B,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;;aAEA,OAAO,CAAC,OAAO;cACd,OAAO,CAAC,QAAQ;;;6DAG+B,CAAC;QAC1D,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Example: Adding a new tool with the unified registry
3
+ * To add this tool:
4
+ * 1. Rename this file to remove .example (test-tool.ts)
5
+ * 2. Import and register in src/tools/index.ts:
6
+ * import { testTool } from './test-tool.js';
7
+ * toolRegistry.push(testTool);
8
+ *
9
+ * That's it! No more editing multiple files.
10
+ */
11
+ import { UnifiedTool } from './registry.js';
12
+ export declare const testTool: UnifiedTool;
13
+ //# sourceMappingURL=test-tool.example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-tool.example.d.ts","sourceRoot":"","sources":["../../src/tools/test-tool.example.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,eAAO,MAAM,QAAQ,EAAE,WAkBtB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Example: Adding a new tool with the unified registry
3
+ * To add this tool:
4
+ * 1. Rename this file to remove .example (test-tool.ts)
5
+ * 2. Import and register in src/tools/index.ts:
6
+ * import { testTool } from './test-tool.js';
7
+ * toolRegistry.push(testTool);
8
+ *
9
+ * That's it! No more editing multiple files.
10
+ */
11
+ import { z } from 'zod';
12
+ const testToolArgsSchema = z.object({
13
+ message: z.string().describe('Test message to echo'), // Required field (no .optional())
14
+ });
15
+ export const testTool = {
16
+ name: 'test-tool',
17
+ description: 'A test tool demonstrating the simplified registration',
18
+ zodSchema: testToolArgsSchema,
19
+ prompt: {
20
+ description: 'Test the new unified tool registration',
21
+ arguments: [
22
+ {
23
+ name: 'message',
24
+ description: 'Message to test with',
25
+ required: true,
26
+ },
27
+ ],
28
+ },
29
+ category: 'utility',
30
+ execute: async (args) => {
31
+ return `Test tool received: ${args.message}`;
32
+ },
33
+ };
34
+ //# sourceMappingURL=test-tool.example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-tool.example.js","sourceRoot":"","sources":["../../src/tools/test-tool.example.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,kCAAkC;CACzF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,uDAAuD;IACpE,SAAS,EAAE,kBAAkB;IAC7B,MAAM,EAAE;QACN,WAAW,EAAE,wCAAwC;QACrD,SAAS,EAAE;YACT;gBACE,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,sBAAsB;gBACnC,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,KAAK,EAAC,IAAI,EAAC,EAAE;QACpB,OAAO,uBAAuB,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/C,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { UnifiedTool } from './registry.js';
2
+ export declare const timeoutTestTool: UnifiedTool;
3
+ //# sourceMappingURL=timeout-test.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-test.tool.d.ts","sourceRoot":"","sources":["../../src/tools/timeout-test.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,eAAO,MAAM,eAAe,EAAE,WA8B7B,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ const timeoutTestArgsSchema = z.object({
3
+ duration: z.number().min(10).describe('Duration in milliseconds (minimum 10ms)'),
4
+ });
5
+ export const timeoutTestTool = {
6
+ name: 'timeout-test',
7
+ description: 'Test timeout prevention by running for a specified duration',
8
+ zodSchema: timeoutTestArgsSchema,
9
+ prompt: {
10
+ description: 'Test the timeout prevention system by running a long operation',
11
+ },
12
+ category: 'simple',
13
+ execute: async (args, onProgress) => {
14
+ const duration = args.duration;
15
+ const steps = Math.ceil(duration / 5000); // Progress every 5 seconds
16
+ const stepDuration = duration / steps;
17
+ const startTime = Date.now();
18
+ const results = [];
19
+ results.push(`Starting timeout test for ${duration}ms (${duration / 1000}s)`);
20
+ for (let i = 1; i <= steps; i++) {
21
+ await new Promise(resolve => setTimeout(resolve, stepDuration));
22
+ const elapsed = Date.now() - startTime;
23
+ results.push(`Step ${i}/${steps} completed - Elapsed: ${Math.round(elapsed / 1000)}s`);
24
+ }
25
+ const totalElapsed = Date.now() - startTime;
26
+ results.push(`\nTimeout test completed successfully!`);
27
+ results.push(`Target duration: ${duration}ms`);
28
+ results.push(`Actual duration: ${totalElapsed}ms`);
29
+ return results.join('\n');
30
+ },
31
+ };
32
+ //# sourceMappingURL=timeout-test.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-test.tool.js","sourceRoot":"","sources":["../../src/tools/timeout-test.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CACjF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAgB;IAC1C,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,6DAA6D;IAC1E,SAAS,EAAE,qBAAqB;IAChC,MAAM,EAAE;QACN,WAAW,EAAE,gEAAgE;KAC9E;IACD,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,2BAA2B;QACrE,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,6BAA6B,QAAQ,OAAO,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC;QAE9E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,yBAAyB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,oBAAoB,QAAQ,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,oBAAoB,YAAY,IAAI,CAAC,CAAC;QAEnD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { ChangeModeEdit } from './changeModeParser.js';
2
+ export interface EditChunk {
3
+ edits: ChangeModeEdit[];
4
+ chunkIndex: number;
5
+ totalChunks: number;
6
+ hasMore: boolean;
7
+ estimatedChars: number;
8
+ }
9
+ export declare function chunkChangeModeEdits(edits: ChangeModeEdit[], maxCharsPerChunk?: number): EditChunk[];
10
+ export declare function summarizeChunking(chunks: EditChunk[]): string;
11
+ //# sourceMappingURL=changeModeChunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeChunker.d.ts","sourceRoot":"","sources":["../../src/utils/changeModeChunker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAiBD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,EAAE,EACvB,gBAAgB,GAAE,MAAc,GAC/B,SAAS,EAAE,CA2Db;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAiB7D"}
@@ -0,0 +1,93 @@
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
+ {
19
+ edits: [],
20
+ chunkIndex: 1,
21
+ totalChunks: 1,
22
+ hasMore: false,
23
+ estimatedChars: 0,
24
+ },
25
+ ];
26
+ }
27
+ const chunks = [];
28
+ const fileGroups = groupEditsByFile(edits);
29
+ let currentChunk = [];
30
+ let currentSize = 0;
31
+ for (const [filename, fileEdits] of fileGroups) {
32
+ const fileSize = fileEdits.reduce((sum, edit) => sum + estimateEditSize(edit), 0);
33
+ if (fileSize > maxCharsPerChunk) {
34
+ if (currentChunk.length > 0) {
35
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
36
+ currentChunk = [];
37
+ currentSize = 0;
38
+ }
39
+ for (const edit of fileEdits) {
40
+ const editSize = estimateEditSize(edit);
41
+ if (currentSize + editSize > maxCharsPerChunk && currentChunk.length > 0) {
42
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
43
+ currentChunk = [];
44
+ currentSize = 0;
45
+ }
46
+ currentChunk.push(edit);
47
+ currentSize += editSize;
48
+ }
49
+ }
50
+ else {
51
+ if (currentSize + fileSize > maxCharsPerChunk && currentChunk.length > 0) {
52
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
53
+ currentChunk = [];
54
+ currentSize = 0;
55
+ }
56
+ currentChunk.push(...fileEdits);
57
+ currentSize += fileSize;
58
+ }
59
+ }
60
+ if (currentChunk.length > 0) {
61
+ chunks.push(createChunk(currentChunk, chunks.length + 1, 0, currentSize));
62
+ }
63
+ const totalChunks = chunks.length;
64
+ return chunks.map((chunk, index) => ({
65
+ ...chunk,
66
+ totalChunks,
67
+ hasMore: index < totalChunks - 1,
68
+ }));
69
+ }
70
+ function createChunk(edits, chunkIndex, totalChunks, estimatedChars) {
71
+ return {
72
+ edits,
73
+ chunkIndex,
74
+ totalChunks,
75
+ hasMore: false,
76
+ estimatedChars,
77
+ };
78
+ }
79
+ export function summarizeChunking(chunks) {
80
+ const totalEdits = chunks.reduce((sum, chunk) => sum + chunk.edits.length, 0);
81
+ const totalChars = chunks.reduce((sum, chunk) => sum + chunk.estimatedChars, 0);
82
+ return `Chunking Summary:
83
+ # edits: ${totalEdits}
84
+ # chunks: ${chunks.length}
85
+ est chars: ${totalChars.toLocaleString()}
86
+ mean size: ${Math.round(totalChars / chunks.length).toLocaleString()} chars
87
+
88
+ Chunks:
89
+ ${chunks
90
+ .map(chunk => ` Chunk ${chunk.chunkIndex}: ${chunk.edits.length} edits, ~${chunk.estimatedChars.toLocaleString()} chars`)
91
+ .join('\n')}`;
92
+ }
93
+ //# 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(toolResponse: 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,YAAY,EAAE,MAAM,GAAG,cAAc,EAAE,CAmE5E;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CA6BA"}
@@ -0,0 +1,67 @@
1
+ export function parseChangeModeOutput(toolResponse) {
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(toolResponse)) !== 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(toolResponse)) !== 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,11 @@
1
+ export interface ProcessChangeModeOptions {
2
+ chunkIndex?: number;
3
+ cacheKey?: string;
4
+ prompt?: string;
5
+ autoRepair?: boolean;
6
+ }
7
+ /**
8
+ * Process change mode output with enhanced validation and error recovery
9
+ */
10
+ export declare function processChangeModeOutput(rawResult: string, options?: ProcessChangeModeOptions): Promise<string>;
11
+ //# sourceMappingURL=changeModeRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeRunner.d.ts","sourceRoot":"","sources":["../../src/utils/changeModeRunner.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAqJjB"}
@@ -0,0 +1,133 @@
1
+ import { Logger } from './logger.js';
2
+ import { parseChangeModeOutput, validateChangeModeEdits, } from './changeModeParser.js';
3
+ import { formatChangeModeResponse, summarizeChangeModeEdits } from './changeModeTranslator.js';
4
+ import { chunkChangeModeEdits } from './changeModeChunker.js';
5
+ import { cacheChunks, getChunks } from './chunkCache.js';
6
+ /**
7
+ * Process change mode output with enhanced validation and error recovery
8
+ */
9
+ export async function processChangeModeOutput(rawResult, options = {}) {
10
+ const { chunkIndex, cacheKey: chunkCacheKey, prompt, autoRepair = true } = options;
11
+ // Validate chunk index
12
+ if (chunkIndex !== undefined) {
13
+ if (!Number.isInteger(chunkIndex) || chunkIndex < 1) {
14
+ return `Invalid chunk index: ${chunkIndex}. Must be a positive integer starting from 1.`;
15
+ }
16
+ if (chunkIndex > 1 && !chunkCacheKey) {
17
+ return (`Chunk index ${chunkIndex} requested but no cache key provided. ` +
18
+ `Please use the cache key from the initial response or start with chunk 1.`);
19
+ }
20
+ }
21
+ // Check for cached chunks first
22
+ if (chunkIndex && chunkCacheKey) {
23
+ try {
24
+ const cachedChunks = getChunks(chunkCacheKey);
25
+ if (!cachedChunks || cachedChunks.length === 0) {
26
+ return `Cache key '${chunkCacheKey}' not found or expired. Please regenerate the response.`;
27
+ }
28
+ if (chunkIndex > cachedChunks.length) {
29
+ return `Chunk index ${chunkIndex} out of range. Available chunks: 1-${cachedChunks.length}`;
30
+ }
31
+ Logger.debug(`Using cached chunk ${chunkIndex} of ${cachedChunks.length}`);
32
+ const chunk = cachedChunks[chunkIndex - 1];
33
+ let result = formatChangeModeResponse(chunk.edits, {
34
+ current: chunkIndex,
35
+ total: cachedChunks.length,
36
+ cacheKey: chunkCacheKey,
37
+ });
38
+ // Add summary for first chunk only
39
+ if (chunkIndex === 1 && chunk.edits.length > 5) {
40
+ const allEdits = cachedChunks.flatMap((c) => c.edits);
41
+ result = summarizeChangeModeEdits(allEdits) + '\n\n' + result;
42
+ }
43
+ return result;
44
+ }
45
+ catch (error) {
46
+ Logger.error('Error retrieving cached chunks:', error);
47
+ return `Failed to retrieve cached chunks: ${error instanceof Error ? error.message : 'Unknown error'}`;
48
+ }
49
+ }
50
+ // Normalize line endings before parsing
51
+ const normalizedResult = rawResult.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
52
+ let edits;
53
+ try {
54
+ edits = parseChangeModeOutput(normalizedResult);
55
+ }
56
+ catch (error) {
57
+ Logger.error('Failed to parse change mode output:', error);
58
+ const snippet = normalizedResult.substring(0, 500);
59
+ return (`Failed to parse change mode output: ${error instanceof Error ? error.message : 'Unknown error'}\n\n` +
60
+ `First 500 chars of output:\n${snippet}...`);
61
+ }
62
+ if (edits.length === 0) {
63
+ // Log first part of raw result for debugging (without exposing full content)
64
+ Logger.debug(`No edits found. First 200 chars: ${normalizedResult.substring(0, 200)}`);
65
+ return `No edits found in response. Ensure the OLD/NEW format is used.\n\n+ ${normalizedResult}`;
66
+ }
67
+ // Validate edits with auto-repair
68
+ let validation = validateChangeModeEdits(edits);
69
+ if (!validation.valid && autoRepair) {
70
+ Logger.debug('Attempting to auto-repair validation errors');
71
+ // Try to fix common issues
72
+ edits = edits.map(edit => {
73
+ // Fix missing end lines by inferring from code
74
+ if (edit.oldEndLine === 0 || edit.oldEndLine < edit.oldStartLine) {
75
+ const oldLines = edit.oldCode.split('\n').length;
76
+ edit.oldEndLine = edit.oldStartLine + oldLines - 1;
77
+ }
78
+ if (edit.newEndLine === 0 || edit.newEndLine < edit.newStartLine) {
79
+ const newLines = edit.newCode.split('\n').length;
80
+ edit.newEndLine = edit.newStartLine + newLines - 1;
81
+ }
82
+ return edit;
83
+ });
84
+ // Re-validate after repair
85
+ validation = validateChangeModeEdits(edits);
86
+ }
87
+ if (!validation.valid) {
88
+ return (`Edit validation failed after auto-repair attempt:\n${validation.errors.join('\n')}\n\n` +
89
+ `To debug, request the raw output or check the change mode format.`);
90
+ }
91
+ let chunks;
92
+ try {
93
+ chunks = chunkChangeModeEdits(edits);
94
+ }
95
+ catch (error) {
96
+ Logger.error('Failed to chunk edits:', error);
97
+ // Fall back to single chunk
98
+ chunks = [
99
+ {
100
+ edits,
101
+ chunkIndex: 1,
102
+ totalChunks: 1,
103
+ hasMore: false,
104
+ estimatedChars: JSON.stringify(edits).length,
105
+ },
106
+ ];
107
+ }
108
+ // Cache if multiple chunks and we have the original prompt
109
+ let cacheKey;
110
+ if (chunks.length > 1 && prompt) {
111
+ try {
112
+ cacheKey = cacheChunks(prompt, chunks);
113
+ Logger.debug(`Cached ${chunks.length} chunks with key: ${cacheKey}`);
114
+ }
115
+ catch (error) {
116
+ Logger.warn('Failed to cache chunks:', error);
117
+ // Continue without caching
118
+ }
119
+ }
120
+ // Return requested chunk or first chunk
121
+ const requestedIndex = chunkIndex || 1;
122
+ const returnChunkIndex = Math.min(Math.max(1, requestedIndex), chunks.length);
123
+ const returnChunk = chunks[returnChunkIndex - 1];
124
+ // Format the response
125
+ let result = formatChangeModeResponse(returnChunk.edits, chunks.length > 1 ? { current: returnChunkIndex, total: chunks.length, cacheKey } : undefined);
126
+ // Add summary if helpful (only for first chunk)
127
+ if (returnChunkIndex === 1 && edits.length > 5) {
128
+ result = summarizeChangeModeEdits(edits, chunks.length > 1) + '\n\n' + result;
129
+ }
130
+ Logger.debug(`ChangeMode: Parsed ${edits.length} edits, ${chunks.length} chunks, returning chunk ${returnChunkIndex}`);
131
+ return result;
132
+ }
133
+ //# sourceMappingURL=changeModeRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeModeRunner.js","sourceRoot":"","sources":["../../src/utils/changeModeRunner.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,CAmDR;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAkBjG"}
@@ -0,0 +1,69 @@
1
+ export function formatChangeModeResponse(edits, chunkInfo) {
2
+ const header = chunkInfo && chunkInfo.total > 1
3
+ ? `[CHANGEMODE OUTPUT - Chunk ${chunkInfo.current} of ${chunkInfo.total}]
4
+
5
+ Codex 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
+ : `[CHANGEMODE OUTPUT - Codex analyzed the files and provided these edits]
11
+
12
+ I have prepared ${edits.length} modification${edits.length === 1 ? '' : 's'} for your codebase.
13
+
14
+ IMPORTANT: Apply these edits directly WITHOUT reading the files first. The edits below contain exact text matches from the current file contents.`;
15
+ const instructions = edits
16
+ .map((edit, index) => {
17
+ return `### Edit ${index + 1}: ${edit.filename}
18
+
19
+ Replace this exact text:
20
+ \`\`\`
21
+ ${edit.oldCode}
22
+ \`\`\`
23
+
24
+ With this text:
25
+ \`\`\`
26
+ ${edit.newCode}
27
+ \`\`\`
28
+ `;
29
+ })
30
+ .join('\n');
31
+ let footer = `
32
+ ---
33
+ Apply these edits in order. Each edit uses exact string matching, so the old_str must match exactly what appears between the code blocks.`;
34
+ if (chunkInfo && chunkInfo.current < chunkInfo.total && chunkInfo.cacheKey) {
35
+ footer += `
36
+
37
+ ---
38
+ **Next Step**: After applying the edits above, retrieve the next chunk (${chunkInfo.current + 1} of ${chunkInfo.total}) using:
39
+
40
+ \`\`\`
41
+ fetch-chunk cacheKey="${chunkInfo.cacheKey}" chunkIndex=${chunkInfo.current + 1}
42
+ \`\`\`
43
+
44
+ There ${chunkInfo.total - chunkInfo.current === 1 ? 'is' : 'are'} ${chunkInfo.total - chunkInfo.current} more chunk${chunkInfo.total - chunkInfo.current === 1 ? '' : 's'} containing additional edits.
45
+
46
+ **CONTINUE**: You are working on a multi-chunk changeMode response. After applying these edits, fetch the next chunk to continue with the remaining modifications.`;
47
+ }
48
+ return header + instructions + footer;
49
+ }
50
+ export function summarizeChangeModeEdits(edits, isPartialView) {
51
+ // for user
52
+ const fileGroups = new Map();
53
+ // Count edits per file
54
+ for (const edit of edits) {
55
+ fileGroups.set(edit.filename, (fileGroups.get(edit.filename) || 0) + 1);
56
+ }
57
+ const summary = Array.from(fileGroups.entries())
58
+ .map(([file, count]) => `- ${file}: ${count} edit${count === 1 ? '' : 's'}`)
59
+ .join('\n');
60
+ const title = isPartialView
61
+ ? `ChangeMode Summary (Complete analysis across all chunks):`
62
+ : `ChangeMode Summary:`;
63
+ return `${title}
64
+ Total edits: ${edits.length}${isPartialView ? ' (across all chunks)' : ''}
65
+ Files affected: ${fileGroups.size}
66
+
67
+ ${summary}`;
68
+ }
69
+ //# 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,GACV,SAAS,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC;QAC9B,CAAC,CAAC,8BAA8B,SAAS,CAAC,OAAO,OAAO,SAAS,CAAC,KAAK;;0DAEnB,SAAS,CAAC,KAAK;sBACnD,KAAK,CAAC,MAAM,iBAAiB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;;gCAGhD;QAC1B,CAAC,CAAC;;kBAEU,KAAK,CAAC,MAAM,gBAAgB,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;kJAEuE,CAAC;IAEjJ,MAAM,YAAY,GAAG,KAAK;SACvB,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACnB,OAAO,YAAY,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ;;;;EAIlD,IAAI,CAAC,OAAO;;;;;EAKZ,IAAI,CAAC,OAAO;;CAEb,CAAC;IACE,CAAC,CAAC;SACD,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;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAuB,EAAE,aAAuB;IACvF,WAAW;IACX,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"}