@@ -189,7 +189,233 @@ export const generateStructure = (tree: TreeItem[]): DirectoryMap => {
189189 return structureMap
190190}
191191
192- export const buildStructureString = ( map : DirectoryMap , prefix = "" , options : TreeCustomizationOptions ) : string => {
192+ // Get description for files and directories
193+ const getDescription = ( name : string , isDirectory : boolean , path ?: string ) : string => {
194+ if ( isDirectory ) {
195+ return getDirectoryDescription ( name , path || "" )
196+ } else {
197+ return getFileDescription ( name )
198+ }
199+ }
200+
201+ // Directory descriptions based on common patterns
202+ const getDirectoryDescription = ( dirName : string , fullPath : string ) : string => {
203+ const lowerName = dirName . toLowerCase ( )
204+ const lowerPath = fullPath . toLowerCase ( )
205+
206+ // Common directory patterns
207+ const directoryDescriptions : { [ key : string ] : string } = {
208+ // Build/Config directories
209+ ".github" : "GitHub workflows and templates" ,
210+ ".vscode" : "VS Code workspace settings" ,
211+ ".next" : "Next.js build output" ,
212+ "dist" : "Distribution/build files" ,
213+ "build" : "Compiled application files" ,
214+ "out" : "Output directory" ,
215+ "public" : "Static assets and public files" ,
216+ "static" : "Static assets" ,
217+ "assets" : "Project assets and resources" ,
218+
219+ // Source directories
220+ "src" : "Source code" ,
221+ "app" : "Application pages and routing" ,
222+ "pages" : "Application pages" ,
223+ "components" : "React components" ,
224+ "lib" : "Utility functions and libraries" ,
225+ "utils" : "Utility functions" ,
226+ "helpers" : "Helper functions" ,
227+ "hooks" : "Custom React hooks" ,
228+ "context" : "React context providers" ,
229+ "store" : "State management" ,
230+ "styles" : "CSS and styling files" ,
231+ "css" : "Stylesheets" ,
232+ "scss" : "Sass stylesheets" ,
233+ "images" : "Image assets" ,
234+ "fonts" : "Font files" ,
235+ "icons" : "Icon assets" ,
236+
237+ // API and backend
238+ "api" : "API routes and endpoints" ,
239+ "server" : "Server-side code" ,
240+ "backend" : "Backend application code" ,
241+ "routes" : "Application routes" ,
242+ "controllers" : "Route controllers" ,
243+ "models" : "Data models" ,
244+ "middleware" : "Express middleware" ,
245+ "database" : "Database files and migrations" ,
246+ "migrations" : "Database migrations" ,
247+ "seeds" : "Database seed files" ,
248+
249+ // Testing
250+ "test" : "Test files" ,
251+ "tests" : "Test files" ,
252+ "__tests__" : "Jest test files" ,
253+ "spec" : "Test specifications" ,
254+ "e2e" : "End-to-end tests" ,
255+ "cypress" : "Cypress test files" ,
256+
257+ // Documentation
258+ "docs" : "Documentation files" ,
259+ "documentation" : "Project documentation" ,
260+
261+ // Configuration
262+ "config" : "Configuration files" ,
263+ "configs" : "Configuration files" ,
264+
265+ // Dependencies
266+ "node_modules" : "NPM dependencies" ,
267+ "vendor" : "Third-party libraries" ,
268+
269+ // UI specific
270+ "ui" : "UI components" ,
271+ "layout" : "Layout components" ,
272+ "layouts" : "Page layouts" ,
273+ "templates" : "Component templates" ,
274+
275+ // Types
276+ "types" : "TypeScript type definitions" ,
277+ "@types" : "TypeScript declarations" ,
278+
279+ // Workflows
280+ "workflows" : "CI/CD workflow files"
281+ }
282+
283+ // Check exact matches first
284+ if ( directoryDescriptions [ lowerName ] ) {
285+ return directoryDescriptions [ lowerName ]
286+ }
287+
288+ // Check for patterns in the full path
289+ if ( lowerPath . includes ( "workflow" ) || lowerPath . includes ( ".github" ) ) {
290+ return "CI/CD workflows"
291+ }
292+ if ( lowerPath . includes ( "component" ) ) {
293+ return "Component files"
294+ }
295+ if ( lowerPath . includes ( "page" ) ) {
296+ return "Page components"
297+ }
298+ if ( lowerPath . includes ( "api" ) ) {
299+ return "API endpoints"
300+ }
301+
302+ return "Directory"
303+ }
304+
305+ // File descriptions based on extensions and names
306+ const getFileDescription = ( fileName : string ) : string => {
307+ const lowerName = fileName . toLowerCase ( )
308+ const extension = fileName . split ( "." ) . pop ( ) ?. toLowerCase ( ) || ""
309+
310+ // Specific file names
311+ const specificFiles : { [ key : string ] : string } = {
312+ "readme.md" : "Project documentation" ,
313+ "license" : "Project license" ,
314+ "license.txt" : "Project license" ,
315+ "license.md" : "Project license" ,
316+ "changelog.md" : "Version history" ,
317+ "contributing.md" : "Contribution guidelines" ,
318+ "package.json" : "NPM package configuration" ,
319+ "package-lock.json" : "Dependency lock file" ,
320+ "yarn.lock" : "Yarn dependency lock file" ,
321+ "tsconfig.json" : "TypeScript configuration" ,
322+ "next.config.js" : "Next.js configuration" ,
323+ "next.config.ts" : "Next.js configuration" ,
324+ "tailwind.config.js" : "Tailwind CSS configuration" ,
325+ "tailwind.config.ts" : "Tailwind CSS configuration" ,
326+ "postcss.config.js" : "PostCSS configuration" ,
327+ "eslint.config.js" : "ESLint configuration" ,
328+ ".eslintrc.json" : "ESLint rules" ,
329+ ".gitignore" : "Git ignore rules" ,
330+ ".env" : "Environment variables" ,
331+ ".env.example" : "Environment variables template" ,
332+ ".env.local" : "Local environment variables" ,
333+ "vercel.json" : "Vercel deployment config" ,
334+ "dockerfile" : "Docker container config" ,
335+ "docker-compose.yml" : "Docker compose config" ,
336+ "makefile" : "Build automation" ,
337+ "components.json" : "Component configuration" ,
338+ "prettier.config.js" : "Code formatting rules"
339+ }
340+
341+ // Check specific file names first
342+ if ( specificFiles [ lowerName ] ) {
343+ return specificFiles [ lowerName ]
344+ }
345+
346+ // Extension-based descriptions
347+ const extensionDescriptions : { [ key : string ] : string } = {
348+ // Web technologies
349+ "js" : "JavaScript file" ,
350+ "jsx" : "React component" ,
351+ "ts" : "TypeScript file" ,
352+ "tsx" : "React TypeScript component" ,
353+ "html" : "HTML page" ,
354+ "css" : "Stylesheet" ,
355+ "scss" : "Sass stylesheet" ,
356+ "sass" : "Sass stylesheet" ,
357+ "less" : "Less stylesheet" ,
358+
359+ // Configuration
360+ "json" : "JSON configuration" ,
361+ "yaml" : "YAML configuration" ,
362+ "yml" : "YAML configuration" ,
363+ "toml" : "TOML configuration" ,
364+ "xml" : "XML file" ,
365+
366+ // Documentation
367+ "md" : "Markdown documentation" ,
368+ "txt" : "Text file" ,
369+ "pdf" : "PDF document" ,
370+
371+ // Images
372+ "png" : "PNG image" ,
373+ "jpg" : "JPEG image" ,
374+ "jpeg" : "JPEG image" ,
375+ "gif" : "GIF image" ,
376+ "svg" : "SVG vector image" ,
377+ "webp" : "WebP image" ,
378+ "ico" : "Icon file" ,
379+
380+ // Video/Audio
381+ "mp4" : "MP4 video" ,
382+ "webm" : "WebM video" ,
383+ "avi" : "AVI video" ,
384+ "mov" : "QuickTime video" ,
385+ "mp3" : "MP3 audio" ,
386+ "wav" : "WAV audio" ,
387+
388+ // Other programming languages
389+ "py" : "Python script" ,
390+ "java" : "Java source file" ,
391+ "cpp" : "C++ source file" ,
392+ "c" : "C source file" ,
393+ "php" : "PHP script" ,
394+ "rb" : "Ruby script" ,
395+ "go" : "Go source file" ,
396+ "rs" : "Rust source file" ,
397+ "swift" : "Swift source file" ,
398+ "kt" : "Kotlin source file" ,
399+
400+ // Database
401+ "sql" : "SQL script" ,
402+ "db" : "Database file" ,
403+
404+ // Archives
405+ "zip" : "ZIP archive" ,
406+ "tar" : "TAR archive" ,
407+ "gz" : "Gzip archive" ,
408+
409+ // Others
410+ "sh" : "Shell script" ,
411+ "bat" : "Batch script" ,
412+ "ps1" : "PowerShell script"
413+ }
414+
415+ return extensionDescriptions [ extension ] || "File"
416+ }
417+
418+ export const buildStructureString = ( map : DirectoryMap , prefix = "" , options : TreeCustomizationOptions , currentPath = "" ) : string => {
193419 let result = ""
194420
195421 // Add root directory indicator if enabled
@@ -198,20 +424,43 @@ export const buildStructureString = (map: DirectoryMap, prefix = "", options: Tr
198424 }
199425
200426 const entries = Array . from ( map . entries ( ) )
201- const lastIndex = entries . length - 1
427+
428+ // Sort entries: directories first, then files
429+ // Within each group, sort alphabetically
430+ const sortedEntries = entries . sort ( ( [ keyA , valueA ] , [ keyB , valueB ] ) => {
431+ const isDirectoryA = valueA instanceof Map
432+ const isDirectoryB = valueB instanceof Map
433+
434+ // If one is directory and other is file, directory comes first
435+ if ( isDirectoryA && ! isDirectoryB ) return - 1
436+ if ( ! isDirectoryA && isDirectoryB ) return 1
437+
438+ // If both are same type (both directories or both files), sort alphabetically
439+ return keyA . localeCompare ( keyB )
440+ } )
441+
442+ const lastIndex = sortedEntries . length - 1
202443
203- entries . forEach ( ( [ key , value ] , index ) => {
444+ sortedEntries . forEach ( ( [ key , value ] , index ) => {
204445 const isLast = index === lastIndex
205446 const connector = getConnector ( isLast , options . asciiStyle )
206447 const childPrefix = getChildPrefix ( isLast , options . asciiStyle )
207448 const icon = options . useIcons ? getIcon ( value instanceof Map ) : ""
449+ const isDirectory = value instanceof Map
450+
451+ // Build current file/directory path
452+ const itemPath = currentPath ? `${ currentPath } /${ key } ` : key
208453
209454 // Add trailing slash for directories if enabled
210- const displayName = ( value instanceof Map && options . showTrailingSlash ) ? `${ key } /` : key
455+ const displayName = ( isDirectory && options . showTrailingSlash ) ? `${ key } /` : key
456+
457+ // Get description for this item
458+ const description = getDescription ( key , isDirectory , itemPath )
459+ const descriptionText = options . showDescriptions && description ? ` # ${ description } ` : ""
211460
212- result += `${ prefix } ${ connector } ${ icon } ${ displayName } \n`
213- if ( value instanceof Map ) {
214- result += buildStructureString ( value , `${ prefix } ${ childPrefix } ` , options )
461+ result += `${ prefix } ${ connector } ${ icon } ${ displayName } ${ descriptionText } \n`
462+ if ( isDirectory ) {
463+ result += buildStructureString ( value , `${ prefix } ${ childPrefix } ` , options , itemPath )
215464 }
216465 } )
217466
0 commit comments