text_dedent()

def text_dedent(content) -> string

Remove common leading whitespace from all non-empty lines.

Similar to Python’s textwrap.dedent. Finds the longest common leading whitespace and removes it from all lines.

Args

  • content: string: String to dedent

Returns

str: Dedented string

text_dedup_diagnostics()

def text_dedup_diagnostics(diagnostics) -> list

Remove duplicate diagnostics.

Deduplicates based on the JSON representation of each diagnostic, preserving the first occurrence of each unique diagnostic.

Args

  • diagnostics: list: List of diagnostic dicts

Returns

list: Deduplicated diagnostics

text_diagnostic()

def text_diagnostic(file, severity, message, line, column, end_line, end_column, code, source, related)

Create a diagnostic dictionary.

Creates a structured diagnostic record suitable for rendering in various formats (GitHub Actions, SARIF, etc.).

Args

  • file: string: Source file path
  • severity: string: “error”, “warning”, “info”, “hint”, or “note”
  • message: string: Diagnostic message
  • line: Line number (1-based, optional)
  • column: Column number (1-based, optional)
  • end_line: End line number (1-based, optional)
  • end_column: End column number (1-based, optional)
  • code: Error/warning code (optional)
  • source: Source tool name (optional)
  • related: List of related diagnostics (optional)

Returns

dict: Diagnostic record

text_grep()

def text_grep(path, pattern, ignore_case, invert, max)

Search for lines matching a regex pattern.

Args

  • path: string: Path to the file
  • pattern: string: Regular expression pattern
  • ignore_case: bool: Case-insensitive matching
  • invert: bool: Return non-matching lines instead
  • max: Maximum number of matches (None for unlimited)

Returns

list[dict]: Matches with keys: line, text, match, named

text_head()

def text_head(path, n) -> list

Get the first n lines of a file.

Args

  • path: string: Path to the file
  • n: int: Number of lines to read (must be non-negative)

Returns

list[str]: First n lines

text_line_count()

def text_line_count(path) -> int

Count the number of lines in a file.

Efficiently counts lines by scanning for newline characters without UTF-8 validation, making it very fast even for large files.

Args

  • path: string: Path to the file

Returns

int: Number of lines in the file

text_match_to_diagnostic()

def text_match_to_diagnostic(match, severity, default_message, default_file, source, related)

Convert a regex match result to a diagnostic.

Takes a regex match result (from text_regex_scan_tagged or similar) and converts it to a diagnostic by extracting named capture groups. This is more efficient than manually extracting fields in Starlark code.

Named Capture Groups: The function looks for these named groups in the match: - file: File path - line: Line number (1-based) - column: Column number (1-based) - end_line: End line number (1-based) - end_column: End column number (1-based) - code: Error/warning code - message: Diagnostic message

Args

  • match: Regex match result from text_regex_scan_tagged or similar
  • severity: string: Severity level (“error”, “warning”, “info”, “hint”, or “note”)
  • default_message: string: Message to use if no “message” capture group exists
  • default_file: string: File to use if no “file” capture group exists
  • source: Source identifier for the diagnostic (e.g., “eslint”, “rustc”)
  • related: List of related diagnostics (optional)

Returns

dict: Diagnostic record that can be rendered with text_render_diagnostics

text_read_line_range()

def text_read_line_range(path, start, end) -> list

Read a range of lines from a file (1-based, inclusive).

Args

  • path: string: Path to the file
  • start: int: First line number (1-based)
  • end: int: Last line number (1-based, inclusive)

Returns

list[str]: Lines in the specified range

text_regex_scan()

def text_regex_scan(content, patterns) -> list

Scan content for multiple regex patterns simultaneously.

Uses an efficient regex set to quickly determine if any pattern matches, then runs captures only on matching patterns.

Args

  • content: string: String content to scan
  • patterns: list: List of regex pattern strings

Returns

list[dict]: Matches with keys: pattern_index, line, column, match, named

text_regex_scan_file()

def text_regex_scan_file(path, patterns) -> list

Scan a file for multiple regex patterns, streaming from disk.

Args

  • path: string: Path to the file
  • patterns: list: List of regex pattern strings

Returns

list[dict]: Matches with keys: pattern_index, line, column, match, named

text_regex_scan_tagged()

def text_regex_scan_tagged(content, patterns, first_match_only) -> list

Scan content for tagged regex patterns.

Each pattern is a dict with “tag” and “pattern” keys. Results include the tag instead of pattern_index.

Args

  • content: string: String content to scan
  • patterns: list: List of dicts with “tag” (str) and “pattern” (str) keys
  • first_match_only: bool: If True, stop after finding the first match (default: False)

Returns

list[dict]: Matches with keys: tag, line, column, match, named

text_regex_scan_tagged_file()

def text_regex_scan_tagged_file(path, patterns, first_match_only) -> list

Scan a file for tagged regex patterns, streaming from disk.

Args

  • path: string: Path to the file
  • patterns: list: List of dicts with “tag” (str) and “pattern” (str) keys
  • first_match_only: bool: If True, stop after finding the first match (default: False)

Returns

list[dict]: Matches with keys: tag, line, column, match, named

text_render_diagnostics()

def text_render_diagnostics(diagnostics, format) -> string

Render diagnostics in a specified format.

Formats: - “human”: One line per diagnostic: “file:line:col: severity: message” - “github”: GitHub Actions workflow commands (::error, ::warning, etc.) - “json”: Pretty-printed JSON array - “sarif”: SARIF 2.1.0 format for static analysis tools

Args

  • diagnostics: list: List of diagnostic dicts
  • format: string: Output format - “human”, “github”, “json”, or “sarif”

Returns

str: Formatted diagnostics

text_scan_file()

def text_scan_file(path, callback, encoding, strip_newline)

Stream a file line-by-line and invoke a callback for each line.

Reads the file efficiently without loading it entirely into memory, making it suitable for large files. The callback is invoked for each line with the line content and line number.

Args

  • path: string: Path to the file to scan
  • callback: Function with signature (line: str, line_num: int) -> value Return None to skip, any other value to collect
  • encoding: string: “utf-8” (strict) or “lossy” (replacement chars for invalid UTF-8)
  • strip_newline: bool: Whether to remove trailing newline characters

Returns

list: All non-None values returned by the callback

text_scan_lines()

def text_scan_lines(content, callback)

Scan a string line-by-line with a callback.

Similar to scan_file but operates on an already-loaded string. Splits on newlines and invokes the callback for each line.

Args

  • content: string: String content to scan
  • callback: Function with signature (line: str, line_num: int) -> value

Returns

list: All non-None values returned by the callback

text_scan_windows()

def text_scan_windows(content, n, callback)

Scan content with a sliding window of n consecutive lines.

Invokes callback(window, start_line_num) for each window position, where window is a list of up to n lines.

Args

  • content: string: String content to scan
  • n: int: Window size (must be >= 1)
  • callback: Function with signature (window: list[str], start_line: int) -> value

Returns

list: All non-None values returned by the callback

text_scan_windows_file()

def text_scan_windows_file(path, n, callback)

Scan a file with a sliding window, streaming from disk.

Like scan_windows but reads from a file efficiently without loading the entire file into memory.

Args

  • path: string: Path to the file
  • n: int: Window size (must be >= 1)
  • callback: Function with signature (window: list[str], start_line: int) -> value

Returns

list: All non-None values returned by the callback

text_tail()

def text_tail(path, n) -> list

Get the last n lines of a file.

Efficiently reads the file in a single pass using a circular buffer, making it suitable for large files.

Args

  • path: string: Path to the file
  • n: int: Number of lines to read (must be non-negative)

Returns

list[str]: Last n lines