(content: string, options: IndentationReadOptions)
| 286 | * @returns The extracted content with metadata |
| 287 | */ |
| 288 | export function readWithIndentation(content: string, options: IndentationReadOptions): IndentationReadResult { |
| 289 | const { |
| 290 | anchorLine, |
| 291 | maxLevels = DEFAULT_MAX_LEVELS, |
| 292 | includeSiblings = false, |
| 293 | includeHeader = true, |
| 294 | limit = DEFAULT_LINE_LIMIT, |
| 295 | maxLines, |
| 296 | } = options |
| 297 | |
| 298 | const lines = parseLines(content) |
| 299 | const totalLines = lines.length |
| 300 | |
| 301 | // Validate anchor line |
| 302 | if (anchorLine < 1 || anchorLine > totalLines) { |
| 303 | return { |
| 304 | content: `Error: anchor_line ${anchorLine} is out of range (1-${totalLines})`, |
| 305 | includedRanges: [], |
| 306 | totalLines, |
| 307 | returnedLines: 0, |
| 308 | wasTruncated: false, |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | const anchorIdx = anchorLine - 1 // Convert to 0-based |
| 313 | const effectiveIndents = computeEffectiveIndents(lines) |
| 314 | const anchorIndent = effectiveIndents[anchorIdx] |
| 315 | |
| 316 | // Calculate minimum indent threshold |
| 317 | // maxLevels = 0 means unlimited (minIndent = 0) |
| 318 | // maxLevels > 0 means limit to that many levels above anchor |
| 319 | let minIndent: number |
| 320 | if (maxLevels === 0) { |
| 321 | minIndent = 0 |
| 322 | } else { |
| 323 | // Each "level" is INDENT_SIZE spaces worth of indentation |
| 324 | // We subtract maxLevels from the anchor's indent level |
| 325 | minIndent = Math.max(0, anchorIndent - maxLevels) |
| 326 | } |
| 327 | |
| 328 | // Calculate final limit (use maxLines as hard cap if provided) |
| 329 | const guardLimit = maxLines ?? limit |
| 330 | const finalLimit = Math.min(limit, guardLimit, totalLines) |
| 331 | |
| 332 | // Edge case: if limit is 1, just return the anchor line |
| 333 | if (finalLimit === 1) { |
| 334 | const singleLine = [lines[anchorIdx]] |
| 335 | return { |
| 336 | content: formatWithLineNumbers(singleLine), |
| 337 | includedRanges: [[anchorLine, anchorLine]], |
| 338 | totalLines, |
| 339 | returnedLines: 1, |
| 340 | wasTruncated: totalLines > 1, |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | // Bidirectional expansion from anchor (Codex algorithm) |
| 345 | const result: LineRecord[] = [lines[anchorIdx]] |
no test coverage detected