Skip to content

feat(output): Add --show-file-offsets option to annotate directory tree with line ranges#1464

Open
nuthalapativarun wants to merge 6 commits intoyamadashy:mainfrom
nuthalapativarun:feat/file-offsets-in-tree
Open

feat(output): Add --show-file-offsets option to annotate directory tree with line ranges#1464
nuthalapativarun wants to merge 6 commits intoyamadashy:mainfrom
nuthalapativarun:feat/file-offsets-in-tree

Conversation

@nuthalapativarun
Copy link
Copy Markdown

@nuthalapativarun nuthalapativarun commented Apr 13, 2026

Summary

Adds a --show-file-offsets CLI flag and output.showFileOffsets config option that annotates each file entry in the directory structure section with its line range in the output file:

<directory_structure>
src/
  components/
    DictCard.tsx [lines 142–219]
    DictManager.tsx [lines 221–283]
    Editor.tsx [lines 285–352]
  index.ts [lines 42–89]
</directory_structure>

This allows AI agents and users to jump directly to a specific file's content in the packed output without scanning the entire file, which is especially valuable for large repositories.

Closes #1367

Changes

  • Add output.showFileOffsets: boolean config option (default: false) to config schema
  • Add --show-file-offsets CLI flag
  • Add src/core/output/fileOffsets.ts — scans rendered output for file block positions (supports XML, Markdown, and plain styles)
  • Add generateTreeStringWithFileOffsets / generateTreeStringWithRootsAndFileOffsets to fileTreeGenerate.ts
  • Implement two-pass rendering in generateOutput(): first pass discovers file line positions, second pass renders with annotations
  • Add 10 unit tests covering offset computation for each style and tree annotation

Implementation Notes

Two-pass rendering: The directory tree is built before the output content is rendered, so file line positions are not available at tree-build time. The solution:

  1. Render the output once (without annotations)
  2. Scan the rendered string for file block start/end markers
  3. Annotate the tree (same line count, only line content changes)
  4. Re-render with the annotated tree

Because the tree section has the same number of lines in both passes (annotations extend line content but add no new lines), all file block positions remain stable between passes.

JSON output: Not annotated since JSON is structured and does not use a directory tree section.

Test Plan

  • npm run lint passes
  • npm run test passes (1125 tests)
  • Unit tests for computeFileLineOffsets for XML, Markdown, plain, and JSON styles
  • Unit tests for generateTreeStringWithFileOffsets with and without multi-root

Open with Devin

Add a new `--show-file-offsets` CLI flag and `output.showFileOffsets` config
option (default: false) that annotates each file entry in the directory
structure section with its line range in the output file (e.g., [lines 42–78]).

This enables AI agents and users to navigate directly to a specific file's
content in the packed output without scanning the entire file.

Implementation uses a two-pass render: first render discovers file block
positions, then the tree is re-rendered with offset annotations. Since the
tree section maintains the same line count between passes, offsets remain
stable.

Supports XML, Markdown, and plain text output styles. JSON output is
structured and does not require tree annotations.

Closes yamadashy#1367
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

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.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bb38796f-cc71-4d48-b85d-70165cce8cca

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added a new --show-file-offsets CLI flag that enables annotating each file in the directory structure output with line ranges indicating its position in the rendered repomix output file. The feature propagates through CLI options, configuration schema, and implements two-pass output rendering to compute file offsets before final tree generation.

Changes

Cohort / File(s) Summary
CLI Option Definition
src/cli/cliRun.ts, src/cli/types.ts, src/cli/actions/defaultAction.ts
Added --show-file-offsets CLI flag, extended CliOptions interface with showFileOffsets property, and propagated flag into cliConfig.output via conditional merge.
Configuration Schema
src/config/configSchema.ts
Extended repomixConfigBaseSchema and repomixConfigDefaultSchema with optional output.showFileOffsets boolean field (defaults to false).
File Offset Utilities
src/core/output/fileOffsets.ts
New module providing FileLineOffset interface, computeFileLineOffsets() to extract per-file line ranges from rendered output (supports xml, markdown, plain formats), and formatFileOffsetAnnotation() to format line-range strings.
File Tree Generation
src/core/file/fileTreeGenerate.ts
Added treeToStringWithFileOffsets(), generateTreeStringWithFileOffsets(), and generateTreeStringWithRootsAndFileOffsets() to render directory trees with file-offset annotations appended to file entries.
Output Generation
src/core/output/outputGenerate.ts
Refactored style selection into renderOutput() helper; added two-pass rendering logic when showFileOffsets is enabled—first pass computes offsets, second pass regenerates tree with annotations and re-renders output.
Test Configuration Updates
tests/config/configSchema.test.ts, tests/core/metrics/calculateGitDiffMetrics.test.ts, tests/core/metrics/calculateGitLogMetrics.test.ts, tests/core/output/flagFullDirectoryStructure.test.ts, tests/core/output/outputStyles/jsonStyle.test.ts
Added showFileOffsets: false to mock configuration objects across multiple test suites.
New Test Suite
tests/core/output/showFileOffsets.test.ts
Comprehensive test coverage for offset computation across output formats (xml, markdown, plain), tree string generation with annotations, and multi-root tree rendering behavior.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI Engine
    participant Config as Config/Output
    participant Gen as Output Generator
    participant Tree as Tree Generator
    participant Offsets as Offset Computer

    User->>CLI: Run with --show-file-offsets
    CLI->>Config: Build config with showFileOffsets=true
    Config-->>Gen: Pass config
    
    Gen->>Gen: First Pass: Render output<br/>(tree without offsets)
    Gen->>Offsets: computeFileLineOffsets(output)
    Offsets-->>Gen: Record{filePath→{start,end}}
    
    Gen->>Tree: generateTreeString...<br/>WithFileOffsets(offsets)
    Tree->>Tree: Format each file entry<br/>with [lines X–Y]
    Tree-->>Gen: Annotated tree string
    
    Gen->>Gen: Second Pass:<br/>Re-render full output<br/>with annotated tree
    Gen-->>User: Output with file offsets<br/>in directory structure
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • yamadashy
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main feature: adding a --show-file-offsets option to annotate the directory tree with line ranges.
Description check ✅ Passed The description comprehensively covers the feature with a clear summary, implementation details, test plan, and the basic template checklist is acknowledged through test execution claims.
Linked Issues check ✅ Passed All coding requirements from issue #1367 are met: the feature adds line offset annotations to directory tree entries, supports multiple output styles (XML, Markdown, plain), and correctly calculates line ranges for each file in the rendered output.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the feature objectives: CLI flag, config schema, offset computation, tree annotation, two-pass rendering, and comprehensive test coverage are all in scope for implementing the requested feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

nuthalapativarun and others added 2 commits April 13, 2026 00:00
…ent tree inputs

Two correctness fixes for --show-file-offsets:

1. Restrict computeFileLineOffsets scanning to the actual files section of the
   output (after <files> for XML, after # Files for Markdown, after the Files
   long-separator block for plain). Previously the scanner could produce false
   offset entries if file content earlier in the output happened to contain
   marker strings matching our patterns (e.g., a file documenting XML format,
   or Markdown headings before the files section).

2. Store filePathsForTree, directoryPathsForTree, and filePathsByRootForTree
   on OutputGeneratorContext so the second-pass tree annotation uses the exact
   same file/directory sets that buildOutputGeneratorContext computed. Previously
   the second pass used allFilePaths / emptyDirPaths arguments directly, which
   could differ from the actual tree inputs when includeFullDirectoryStructure
   adds extra files to the tree.

Adds tests asserting that markers outside the files section are not captured.
- Move --show-file-offsets to Repomix Output Options group (was under Token Count Options)
- Use RepomixOutputStyle type instead of string for style parameter
- Tighten XML file tag regex to use [^"]+ and allow optional whitespace
- Use line.trim() for </file> and </files> tag matching
- Trim extracted paths in Markdown and plain formats
- Add comment documenting plain separator length constant

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

nuthalapativarun and others added 2 commits April 13, 2026 12:23
…sets.ts

fileTreeGenerate.ts exceeded the 250-line limit after adding the three
offset-annotation functions. Move treeToStringWithFileOffsets,
generateTreeStringWithFileOffsets, and generateTreeStringWithRootsAndFileOffsets
into a new src/core/file/fileTreeOffsets.ts. Export generateMultiRootSections
and sortTreeNodes from fileTreeGenerate.ts to support the new module.

Also add --show-file-offsets and output.showFileOffsets to README.md per
CONTRIBUTING.md documentation requirements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace output.split('\n') with an indexOf-based line iterator (iterLines)
so lines are processed one at a time without duplicating the entire output
string as an array of strings, reducing memory overhead for large repos.

Also release the first-pass output string immediately after offsets are
extracted so GC can reclaim it before the second render begins, avoiding
holding two full output strings in memory simultaneously.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Markdown: record sectionEndLine when breaking on the next top-level
heading so the last file's range doesn't bleed into subsequent sections
(git diff, "End of Codebase" footer, etc.).

Plain: detect the long separator (64 '=') after the first file entry
and set sectionEndLine there, mirroring the XML </files> boundary logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 9 additional findings in Devin Review.

Open in Devin Review

Comment on lines +76 to +84
'================================================================================',
'Directory Structure',
'================================================================================',
'src/',
' foo.ts',
'',
'================================================================================',
'Files',
'================================================================================',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Plain-text test uses 80-char separator instead of 64-char, defeating section-isolation testing

The plain-text offset test constructs its mock output with 80-character long separators ('='.repeat(80)) at lines 76, 78, 82, and 84, but the production code uses 64-character separators (PLAIN_LONG_SEPARATOR = '='.repeat(64) at src/core/output/outputStyles/plainStyle.ts:1 and LONG_SEPARATOR = '='.repeat(64) at src/core/output/fileOffsets.ts:46,123). Because findFilesSectionStartLine compares prevLine === LONG_SEPARATOR (64 chars) against the test's 80-char string, the match fails and the function falls back to returning 1 (scan entire output). Similarly, the end-of-section detection (line === LONG_SEPARATOR) also never triggers, falling back to the last line. The test still passes because the file markers are found regardless, but it completely fails to validate the section-isolation logic that prevents false matches from file content containing marker strings.

Suggested change
'================================================================================',
'Directory Structure',
'================================================================================',
'src/',
' foo.ts',
'',
'================================================================================',
'Files',
'================================================================================',
'================================================================',
'Directory Structure',
'================================================================',
'src/',
' foo.ts',
'',
'================================================================',
'Files',
'================================================================',
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

in file tree section, include precise offsets to lines in repomix-output.xml

1 participant