| 227 | } |
| 228 | |
| 229 | function renderClusterTree(node: ClusterNode, indent: number = 0): string { |
| 230 | const pad = " ".repeat(indent); |
| 231 | let result = ""; |
| 232 | |
| 233 | if (node.label) { |
| 234 | result += `${pad}[${node.label}]\n`; |
| 235 | } |
| 236 | |
| 237 | if (node.children.length > 0) { |
| 238 | for (const child of node.children) { |
| 239 | result += renderClusterTree(child, indent + 1); |
| 240 | } |
| 241 | } else { |
| 242 | for (const file of node.files) { |
| 243 | const label = file.header ? ` - ${file.header}` : ""; |
| 244 | const symbols = file.symbolPreview.length > 0 ? ` | symbols: ${file.symbolPreview.join(", ")}` : ""; |
| 245 | result += `${pad} ${file.relativePath}${label}${symbols}\n`; |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | return result; |
| 250 | } |
| 251 | |
| 252 | export async function semanticNavigate(options: SemanticNavigateOptions): Promise<string> { |
| 253 | const maxClusters = options.maxClusters ?? 20; |