( filePaths: string[], options: FoldedFileContextOptions, )
| 74 | * ``` |
| 75 | */ |
| 76 | export async function generateFoldedFileContext( |
| 77 | filePaths: string[], |
| 78 | options: FoldedFileContextOptions, |
| 79 | ): Promise<FoldedFileContextResult> { |
| 80 | const { maxCharacters = 50000, cwd, rooIgnoreController } = options |
| 81 | |
| 82 | const result: FoldedFileContextResult = { |
| 83 | content: "", |
| 84 | sections: [], |
| 85 | filesProcessed: 0, |
| 86 | filesSkipped: 0, |
| 87 | characterCount: 0, |
| 88 | } |
| 89 | |
| 90 | if (filePaths.length === 0) { |
| 91 | return result |
| 92 | } |
| 93 | |
| 94 | const foldedSections: string[] = [] |
| 95 | let currentCharCount = 0 |
| 96 | const failedFiles: string[] = [] |
| 97 | |
| 98 | for (let i = 0; i < filePaths.length; i++) { |
| 99 | const filePath = filePaths[i] |
| 100 | // Resolve to absolute path for tree-sitter |
| 101 | const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath) |
| 102 | |
| 103 | try { |
| 104 | // Get the folded definitions using tree-sitter |
| 105 | const definitions = await parseSourceCodeDefinitionsForFile(absolutePath, rooIgnoreController) |
| 106 | |
| 107 | if (!definitions || isTreeSitterErrorString(definitions)) { |
| 108 | // File type not supported, no definitions found, or error accessing file |
| 109 | result.filesSkipped++ |
| 110 | continue |
| 111 | } |
| 112 | |
| 113 | // Wrap each file in its own <system-reminder> block |
| 114 | const sectionContent = `<system-reminder> |
| 115 | ## File Context: ${filePath} |
| 116 | ${definitions} |
| 117 | </system-reminder>` |
| 118 | |
| 119 | // Check if adding this file would exceed the character limit |
| 120 | if (currentCharCount + sectionContent.length > maxCharacters) { |
| 121 | // Would exceed limit - check if we can fit at least a truncated version |
| 122 | const remainingChars = maxCharacters - currentCharCount |
| 123 | if (remainingChars < 200) { |
| 124 | // Not enough room for meaningful content, stop processing all remaining files |
| 125 | result.filesSkipped += filePaths.length - i |
| 126 | break |
| 127 | } |
| 128 | |
| 129 | // Truncate the definitions to fit within the system-reminder block |
| 130 | const truncatedDefinitions = definitions.substring(0, remainingChars - 100) + "\n... (truncated)" |
| 131 | const truncatedContent = `<system-reminder> |
| 132 | ## File Context: ${filePath} |
| 133 | ${truncatedDefinitions} |
no test coverage detected