Converts files into simple Markdown-fenced blocks for easy use in LLM chats.
The goal is to make prompt setup repeatable. Instead of letting an agent guess context or manually selecting files in a UI, you define the exact context you want in one shell command and rerun it whenever you need a fresh session. It works smoothly with tools like rg -l, fd, and recursive shell globs.
This gives you a stable, controllable workflow:
- You decide exactly what context the model sees.
- If a conversation drifts, you restart instantly with the same context.
- Adjust the command, rerun it, and paste the updated output.
Via go install:
go install github.com/rasros/lx/cmd/lx@latestOr via curl into $HOME/.local/bin/lx:
curl -fsSL https://raw.githubusercontent.com/rasros/lx/main/install.sh | bash
Format a single file as an LLM-ready snippet:
lx cmd/lx/main.goExample output (trimmed):
cmd/lx/main.go (18 rows)
---
```go
package main
... (rest omitted)
```
You can put it directly in your clipboard by piping it to a copy tool:
# Wayland (Ubuntu, Debian)
lx file.py | wl-copy# X11
lx file.py | xclip -selection clipboard
# or
lx file.py | xsel --clipboard --input# macOS
lx file.py | pbcopy# MSYS2
lx file.py | clip- Generates Markdown headers and fenced blocks for one or many files.
- Automatically detects fenced-code language from file extension.
- Supports lightweight, ergonomic slicing (
-h,-t,-n). - Optional line numbers for precise AI instructions.
- Reads filenames from CLI args or stdin (great with
rg,find, etc.). - Customizable delimiters with placeholders.
We can select multiple files in shells that allow recursive glob:
lx **/*.pyIf you need to exclude certain files we rely on standard tools for file selection.
This example uses includes all python files except those with name ending in _test.py. Here fd or find:
# find using stdin-mode
find . -name '*.py' ! -name '*_test.py' | lx
# fd using stdin-mode
fd -e py -E "*_test.py" | lxOr through shell glob syntax:
# zsh glob
lx **/*.py~*_test.py
# bash glob
shopt -s globstar extglob
lx **/!(*_test).py
# fish glob
lx **/*.py ^**/*_test.py
# MSYS2 glob
shopt -s globstar extglob
lx **/!(*_test).pySearching for patterns is easily done through grep -l and pipe matching files to lx.
This example searches for files with a function starting with save under the src folder:
# grep
grep -rl "def save" src | lx
# ripgrep
rg -l "def save" src | lxTOON supports line numbers so we do too 🤷.
This is actually very useful for letting the LLM reference where in a big log dump something is wrong. Or if you specifically include prompting about instructions about line number references.
lx -l server.logWhile iterating on the command it's convenient to slice files so you can more easily see what's included:
# First 40 lines
lx -h40 server.log
# Last 80 lines
lx -t80 server.log
# Both ends (split 60 lines between head & tail)
lx -n60 server.logShort forms like -h5, -t10, -n2 are supported.
Default delimiters:
{filename} ({row_count} rows)
---
```{language}
...file contents...
```
Override them:
lx \
--prefix-delimiter="### {filename}\n```{language}\n" \
--postfix-delimiter="```\n\n" \
file.goPlaceholders:
{filename}{row_count}{byte_size}{last_modified}{language}
Use these to enforce consistent prompt structure and regenerate identical context anytime.