Metadata-Version: 2.4
Name: outliner-cli
Version: 0.4.0
Summary: Print the structural outline of source files for LLM navigation
Author: Per Cederberg
License-Expression: MIT
Project-URL: Homepage, https://github.com/cederberg/incubator/tree/main/outliner
Project-URL: Repository, https://github.com/cederberg/incubator
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# outliner

Print the structural outline of source files — declarations and callable
landmarks with line ranges — so an LLM agent (or human) can navigate a file
without reading it whole.

## Usage

```
outliner-cli [OPTIONS] [FILE...]
```

| Option               | Description                                          |
| -------------------- | ---------------------------------------------------- |
| `-g, --grep EXPR`    | Only show items whose signature matches EXPR         |
| `-s, --syntax LANG`  | Override syntax auto-detection when ambiguous        |
| `-t, --type LANG`    | Only include files of this language (repeatable)     |
| `-w, --width COLS`   | Truncate lines (`0`=off, `auto`=fit, default `120`)  |
| `-x, --exclude GLOB` | Exclude files from directory walks (gitignore-style) |

Pass a file, a directory (walked recursively), or omit arguments to read stdin.
Use `-` to read stdin explicitly. Directory walks honor `.gitignore` and skip
hidden directories; all other files are listed, with binary and unrecognized
files shown as one-line `binary file` / `unsupported file` summaries. `--syntax`
is only needed when content auto-detection cannot identify the language (e.g. an
ambiguous extensionless script piped on stdin).

## Output

```
 3,4   type Driver struct
19,6   func New() *Driver
26,12  func (d *Driver) StartLogging(ctx context.Context, f *os.File) error
```

Each line: `<start>,<count>  <signature>`

- `start` — 1-based line number, right-aligned
- `count` — number of lines covered by the item (including doc-comments above)
- `signature` — first non-comment line of a declaration; multi-line signatures
  are merged into one line; lines longer than the output width are truncated
  with `...`

Nesting is visible in two ways: overlapping ranges (a class range contains its
methods) and native-format indentation in the signature (indented for code,
`#`/`##` heading levels for Markdown).

## Installation

```sh
pip install outliner-cli
```

## Running

```sh
# With the package installed (pip or uvx):
uvx outliner-cli path/to/file.py

# From within the outliner/ directory
uv run outliner-cli path/to/file.py
```

## Running Tests

```sh
# From within the outliner/ directory
uv run pytest
```

## Supported Languages

AsciiDoc, C/C++, C#, Clojure, Go, HTML, Java, JavaScript/TypeScript (incl.
Svelte, Vue, and Astro components), JSON/NDJSON, Markdown, Org-mode, Perl, PHP,
Python, reStructuredText, Ruby, Rust, Scala, Shell, Swift, XML, and Zig.

## Example Use Cases

**Structural overview** — Run on a directory to see declarations across all
files before reading anything:

```
$ uvx outliner-cli src/
==> src/billing.py <==
 12,8   class Invoice
 22,4   def create(customer_id: str, items: list[Item]) -> Invoice
 38,6   def send(invoice: Invoice, method: str) -> bool

==> src/payments.py <==
  8,3   class PaymentMethod
 14,12  def charge(method: PaymentMethod, amount: Decimal) -> Receipt
```

**Find all copies of a pattern** — `--grep serialize` across a source tree
locates every implementation of a repeated function in one command:

```
$ uvx outliner-cli --grep serialize src/
==> src/invoice.py <==
 44,5   def serialize(self) -> dict

==> src/receipt.py <==
 31,3   def serialize(self) -> dict
```

**Find functions whose interface mentions a term** — `--grep` searches
signatures, not bodies. It finds functions whose interface involves a concept,
skipping internal uses, comments, and call sites:

```
$ uvx outliner-cli --grep payment src/
 14,12  def charge(method: PaymentMethod, amount: Decimal) -> Receipt
 61,4   def refund(payment: Payment) -> bool
```

**Find functions accepting a specific type** — `--grep PaymentMethod` locates
every function where the type appears in parameters, return types, or generic
bounds. Multi-line signatures are merged into a single line before matching, so
nothing is missed:

```
$ uvx outliner-cli --grep PaymentMethod src/
 14,12  def charge(method: PaymentMethod, amount: Decimal) -> Receipt
 88,4   def validate(m: PaymentMethod) -> bool
```

**Inspect a dataset without opening it** — JSON/NDJSON files show a schema
overview with file size, record count, data types, optionality, and truncated
sample values:

```
$ uvx outliner-cli titanic.json
$             163.9 KB · json · array[891]
.Age          float|int? -- 22
.Cabin        str? -- "C85"
.Embarked     str? -- "S"
.Fare         float|int -- 7.25
.Name         str -- "Braund, Mr. Owen Harris"
.Survived     int -- 0
```

XML files show an indented structural outline with XML-native node kinds:

```
$ uvx outliner-cli pubmed26n0001.xml
/                                195.5 MB · xml · sampled 204K elems
<PubmedArticleSet>               elem
  <PubmedArticle>                elem+
    <MedlineCitation>            elem
      @Status                    attr -- "MEDLINE"
      <Article>                  elem
        <ArticleTitle>           text -- "Formate assay in body fluids..."
        <Abstract>               elem?
```
