Skip to content

feat(tree): add multi-root directory labels#1024

Merged
yamadashy merged 3 commits intoyamadashy:mainfrom
spandan-kumar:feat/multi-root-directory-tree-labels-1023
Jan 7, 2026
Merged

feat(tree): add multi-root directory labels#1024
yamadashy merged 3 commits intoyamadashy:mainfrom
spandan-kumar:feat/multi-root-directory-tree-labels-1023

Conversation

@spandan-kumar
Copy link
Contributor

When packing multiple directories, the directory tree output now shows labeled sections like [cli]/, [config]/ to clarify which files belong to which root directory.

  • Add FilesByRoot interface and generateTreeStringWithRoots function
  • Update output pipeline to pass file-to-root mapping
  • Add unit tests for new tree generation functions
  • Update existing tests for new function signatures

Closes #1023

Files Changed

  • src/core/file/fileTreeGenerate.ts - Added FilesByRoot interface and generateTreeStringWithRoots() function
  • src/core/packager.ts - Creates file-to-root mapping, passes to output pipeline
  • src/core/packager/produceOutput.ts - Threads filePathsByRoot through
  • src/core/output/outputGenerate.ts - Uses labeled tree for multiple roots
  • src/core/output/outputSplit.ts - Passes mapping for split output mode
  • tests/core/file/fileTreeGenerate.test.ts - New: 6 tests for multi-root tree
  • tests/core/output/*.test.ts - Updated 3 test files for new signatures

Summary

Added automatic root directory labels to the directory tree output when packing multiple directories. This provides clear visual grouping showing which files belong to which root directory.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This PR introduces multi-root repository support by adding file grouping and root-aware tree generation. It threads an optional FilesByRoot[] parameter through the output generation pipeline to enable labeled, folder-level distinction in tree representations when repomixing multiple directories.

Changes

Cohort / File(s) Summary
Core tree generation
src/core/file/fileTreeGenerate.ts
Adds FilesByRoot interface, generateTreeStringWithRoots(), and generateTreeStringWithRootsAndLineCounts() functions to support multi-root tree rendering with root labels and empty-root skipping.
Output generation API
src/core/output/outputGenerate.ts
Updates generateOutput() and buildOutputGeneratorContext() signatures to accept optional filePathsByRoot parameter; adds conditional tree-generation logic that uses generateTreeStringWithRoots() when multiple roots provided.
Output splitting
src/core/output/outputSplit.ts
Adds filePathsByRoot parameter to renderGroups() and generateSplitOutputParts(), threading it through nested generateOutput() calls.
Packager coordination
src/core/packager.ts, src/core/packager/produceOutput.ts
Builds filePathsByRoot structure from sorted file paths (using directory basename as root label) and propagates through produceOutput() to output generation.
Test updates
tests/core/file/fileTreeGenerate.test.ts
Adds comprehensive unit tests for new tree generation functions, validating multi-root labeling, single-root parity, nested directory handling, and empty-root skipping.
Test parameter adjustments
tests/core/output/{flagFullDirectoryStructure,outputGenerate,outputGenerateDiffs}.test.ts
Updates call sites to pass additional undefined parameter matching expanded function signatures.

Sequence Diagram(s)

sequenceDiagram
    participant Packager as src/core/packager.ts
    participant ProduceOutput as src/core/packager/produceOutput.ts
    participant OutputSplit as src/core/output/outputSplit.ts
    participant OutputGen as src/core/output/outputGenerate.ts
    participant TreeGen as src/core/file/fileTreeGenerate.ts

    Packager->>Packager: Build FilesByRoot from sortedFilePathsByDir
    Packager->>ProduceOutput: produceOutput(filePathsByRoot)
    ProduceOutput->>OutputSplit: generateSplitOutputParts(filePathsByRoot)
    OutputSplit->>OutputSplit: renderGroups(filePathsByRoot)
    OutputSplit->>OutputGen: generateOutput(filePathsByRoot)
    
    alt Multiple roots provided
        OutputGen->>TreeGen: generateTreeStringWithRoots(filePathsByRoot)
        TreeGen->>TreeGen: Group files by root, skip empty
        TreeGen-->>OutputGen: Root-labeled tree string
    else Single root or undefined
        OutputGen->>TreeGen: generateTreeString(filePathsForTree)
        TreeGen-->>OutputGen: Flat tree string
    end
    
    OutputGen-->>OutputSplit: Output with labeled tree
    OutputSplit-->>ProduceOutput: Split output parts
    ProduceOutput-->>Packager: Final output generated
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #896: Modifies the same core output generation entry points (generateOutput and buildOutputGeneratorContext), introducing new optional inputs and changing tree-generation behavior in parallel.
  • PR #1013: Updates the same output-splitting functions (generateSplitOutputParts and renderGroups) with similar parameter threading patterns.
  • PR #338: Also addresses multi-root repository support through the packager path, adding directory distinction at the output generation layer.

Suggested reviewers

  • yamadashy

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(tree): add multi-root directory labels' clearly and concisely summarizes the main feature addition—adding labeled sections for multiple root directories in tree output.
Description check ✅ Passed The description provides a comprehensive summary of changes, references the closed issue (#1023), lists all modified files with their purposes, includes implementation details, and acknowledges test updates; fulfills the repository template requirements.
Linked Issues check ✅ Passed All code changes directly address issue #1023 requirements: the PR adds multi-root tree labeling via FilesByRoot interface and generateTreeStringWithRoots functions, threads mapping through the output pipeline, and includes test coverage for the new functionality.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing multi-root directory labels: new tree generation functions, pipeline integration for mapping propagation, and corresponding test updates; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @spandan-kumar, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the clarity of the directory tree output when the system processes files from multiple distinct root directories. By introducing automatic labeling for each root, users can now easily discern which files belong to which source directory, enhancing the overall readability and organization of the generated output. This change is particularly beneficial for projects with complex, multi-component structures.

Highlights

  • Multi-Root Tree Generation: Introduced new functions (generateTreeStringWithRoots, generateTreeStringWithRootsAndLineCounts) and an interface (FilesByRoot) to support labeled directory tree output when processing multiple root directories.
  • Output Pipeline Integration: The core packager now constructs a mapping of files to their respective root directories, which is then threaded through the output generation (produceOutput, outputGenerate, outputSplit) to enable the new labeled tree display.
  • Enhanced Clarity: When multiple directories are packed, the output tree now clearly labels each section (e.g., [cli]/, [config]/) to visually group files by their original root, improving readability and understanding.
  • Comprehensive Testing: New unit tests have been added for the multi-root tree generation logic, and existing tests in the output modules were updated to accommodate the new function signatures.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a great feature for labeling directory trees when multiple root directories are provided. The implementation is solid and includes good test coverage. I've identified a couple of opportunities to refactor the code for better maintainability by reducing code duplication and simplifying logic. My suggestions focus on consolidating the new tree generation functions in fileTreeGenerate.ts and simplifying the conditional logic in outputGenerate.ts.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/core/file/fileTreeGenerate.test.ts (1)

2-8: Unused imports.

generateFileTree and treeToString are imported but not used in the tests. Consider removing them to keep imports clean, or add tests that exercise these functions directly.

🔎 Proposed fix
 import {
-    type FilesByRoot,
-    generateFileTree,
     generateTreeString,
     generateTreeStringWithRoots,
-    treeToString,
+    type FilesByRoot,
 } from '../../../src/core/file/fileTreeGenerate.js';
src/core/output/outputGenerate.ts (1)

377-385: Simplify the condition to improve consistency.

The current logic checks filePathsByRoot.length > 1, which means when exactly one root is provided, it falls back to using filePathsForTree instead of filePathsByRoot[0].files. Since generateTreeStringWithRoots already handles the single-root case internally, this creates an inconsistency where single-root and multi-root scenarios use different data sources.

Consider simplifying to check only for the presence of filePathsByRoot, letting generateTreeStringWithRoots handle both single and multiple roots uniformly.

🔎 Proposed simplification
 // Generate tree string - use multi-root format if multiple roots are provided
 let treeString: string;
-if (filePathsByRoot && filePathsByRoot.length > 1) {
+if (filePathsByRoot) {
   // Multiple roots: generate labeled tree sections
   treeString = generateTreeStringWithRoots(filePathsByRoot, directoryPathsForTree);
 } else {
   // Single root or no root info: use standard flat tree
   treeString = generateTreeString(filePathsForTree, directoryPathsForTree);
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3e7fd and 614985b.

📒 Files selected for processing (9)
  • src/core/file/fileTreeGenerate.ts
  • src/core/output/outputGenerate.ts
  • src/core/output/outputSplit.ts
  • src/core/packager.ts
  • src/core/packager/produceOutput.ts
  • tests/core/file/fileTreeGenerate.test.ts
  • tests/core/output/flagFullDirectoryStructure.test.ts
  • tests/core/output/outputGenerate.test.ts
  • tests/core/output/outputGenerateDiffs.test.ts
🧰 Additional context used
🧬 Code graph analysis (4)
src/core/packager/produceOutput.ts (2)
src/core/file/fileTreeGenerate.ts (1)
  • FilesByRoot (120-123)
src/shared/memoryUtils.ts (1)
  • withMemoryLogging (71-87)
src/core/output/outputSplit.ts (2)
src/core/file/fileTreeGenerate.ts (1)
  • FilesByRoot (120-123)
src/shared/errorHandle.ts (1)
  • RepomixError (6-11)
src/core/packager.ts (1)
src/core/file/fileTreeGenerate.ts (1)
  • FilesByRoot (120-123)
src/core/output/outputGenerate.ts (2)
src/core/file/fileTreeGenerate.ts (3)
  • FilesByRoot (120-123)
  • generateTreeStringWithRoots (133-153)
  • generateTreeString (103-106)
src/index.ts (1)
  • generateTreeString (13-13)
🔇 Additional comments (18)
tests/core/output/outputGenerate.test.ts (1)

44-65: LGTM!

The test correctly threads the new undefined argument for filePathsByRoot through both generateOutput and buildOutputGeneratorContext calls when using mock dependencies. The assertions remain valid and properly verify the expected behavior.

tests/core/output/flagFullDirectoryStructure.test.ts (2)

67-76: LGTM!

The additional undefined argument for filePathsByRoot is correctly positioned before the deps parameter, maintaining proper alignment with the updated buildOutputGeneratorContext signature.


100-109: LGTM!

Consistent with the first test case - the undefined argument is correctly threaded through.

tests/core/output/outputGenerateDiffs.test.ts (1)

83-92: LGTM!

The additional undefined argument for filePathsByRoot is correctly added before mockDeps across all test cases in this file. The pattern is consistent and aligns with the updated generateOutput signature.

src/core/packager.ts (1)

1-9: LGTM!

The new imports are correctly added for node:path and FilesByRoot type, supporting the multi-root tree generation feature.

tests/core/file/fileTreeGenerate.test.ts (1)

1-96: Good test coverage for multi-root tree generation.

The tests comprehensively cover the key behaviors:

  • Single root fallback (no labels)
  • Multiple roots with labeled sections
  • Nested directory handling
  • Empty root section skipping
  • Parity verification between single-root and standard generation
src/core/packager/produceOutput.ts (3)

24-65: LGTM!

The filePathsByRoot parameter is cleanly threaded through the public produceOutput function and correctly passed to both generateAndWriteSplitOutput and generateAndWriteSingleOutput internal helpers. The optional parameter positioning before overrideDeps is consistent and appropriate.


67-94: LGTM!

The generateAndWriteSplitOutput function correctly receives and forwards filePathsByRoot to generateSplitOutputParts.


118-131: LGTM!

The generateAndWriteSingleOutput function correctly passes filePathsByRoot to deps.generateOutput.

src/core/file/fileTreeGenerate.ts (2)

117-123: LGTM!

The FilesByRoot interface is clean and well-documented, providing a simple structure for grouping files by their root directory label.


164-188: LGTM with same caveat.

The generateTreeStringWithRootsAndLineCounts function follows the same pattern as generateTreeStringWithRoots, which is good for consistency. The same consideration about emptyDirPaths handling applies here.

src/core/output/outputSplit.ts (4)

96-119: LGTM!

The renderGroups function correctly accepts and forwards filePathsByRoot to the generateOutput call. The parameter is appropriately placed and the threading is consistent.


121-145: LGTM!

The generateSplitOutputParts function signature is correctly updated to include the optional filePathsByRoot parameter in both the function parameters and the destructured type definition.


169-182: LGTM!

The first renderGroups call in the group iteration loop correctly passes filePathsByRoot.


210-219: LGTM!

The second renderGroups call (for single group content) also correctly passes filePathsByRoot, maintaining consistency in the split output path.

src/core/output/outputGenerate.ts (3)

8-8: LGTM!

The imports correctly bring in the new FilesByRoot type and generateTreeStringWithRoots function needed for multi-root support, while preserving the existing generateTreeString import for backward compatibility.


253-296: LGTM!

The optional filePathsByRoot parameter is properly threaded through to buildOutputGeneratorContext, maintaining backward compatibility while enabling multi-root support.


298-311: LGTM!

The optional filePathsByRoot parameter is correctly added to the function signature with proper typing.

When packing multiple directories, the directory tree output now shows
labeled sections like [cli]/, [config]/ to clarify which files belong
to which root directory.

- Add FilesByRoot interface and generateTreeStringWithRoots function
- Update output pipeline to pass file-to-root mapping
- Add unit tests for new tree generation functions
- Update existing tests for new function signatures

Closes yamadashy#1023
@yamadashy yamadashy force-pushed the feat/multi-root-directory-tree-labels-1023 branch from 614985b to 3f2680e Compare January 4, 2026 13:57
…Root

- Remove unused imports (generateFileTree, treeToString) in fileTreeGenerate.test.ts
- Add filePathsByRoot parameter to generateOutput and produceOutput calls in tests
- Update expect assertions to include filePathsByRoot argument
@codecov
Copy link

codecov bot commented Jan 4, 2026

Codecov Report

❌ Patch coverage is 81.48148% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.15%. Comparing base (f7c68b5) to head (f3f1277).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/core/file/fileTreeGenerate.ts 75.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1024      +/-   ##
==========================================
- Coverage   87.19%   87.15%   -0.04%     
==========================================
  Files         116      116              
  Lines        4350     4376      +26     
  Branches     1011     1019       +8     
==========================================
+ Hits         3793     3814      +21     
- Misses        557      562       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Extract common multi-root logic into generateMultiRootSections helper
- Simplify conditional in outputGenerate.ts (generateTreeStringWithRoots handles single root internally)
- Add fallback for empty path.basename (e.g., filesystem root "/")
- Document limitation: empty directories not included in multi-root output
@yamadashy
Copy link
Owner

Hi @spandan-kumar!

Thank you for the suggestion and this PR!

This is a great idea as a feature, and the implementation looks good.
I haven't had much time to review it thoroughly yet, so I'll take a closer look later.

@yamadashy
Copy link
Owner

@spandan-kumar
Everything looks good, merging this now.
Thanks for your contribution! 🎉

@yamadashy yamadashy merged commit 8cb110c into yamadashy:main Jan 7, 2026
55 checks passed
@spandan-kumar spandan-kumar deleted the feat/multi-root-directory-tree-labels-1023 branch January 13, 2026 08:24
yamadashy added a commit that referenced this pull request Jan 18, 2026
Add release notes for v1.11.1 covering:
- Multi-root directory labels (#1024)
- Non-interactive skill generation options (#1022)
- Remote git command timeout fix (#1078)
- CLI output visibility fix for light themes (#1088)
- Library bundling documentation (#1075)

Improve release note generation guidelines:
- Clarify "What's New" vs "Improvements" usage
- Add rule to include related issue numbers with PRs
- Add rule to include links in documentation sections
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Folder level distinction in tree when repomixing multiple folders.

2 participants