Metadata-Version: 2.4
Name: ecat
Version: 1.0.0
Summary: Embedded cat. The simplest way to context engineer.
Author-email: Rodolfo Villaruz <rodolfo@yes.ph>
License-Expression: MIT
Project-URL: Homepage, https://github.com/rodolfovillaruz/ecat
Project-URL: Bug Tracker, https://github.com/rodolfovillaruz/ecat/issues
Project-URL: Repository, https://github.com/rodolfovillaruz/ecat.git
Keywords: llm,claude,gemini,cli,streaming,context-engineering,prompt-engineering,cat
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: anthropic>=0.25.0
Requires-Dist: google-genai>=1.0.0
Requires-Dist: markdownify>=0.11.0
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: isort>=5.12.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: pytest>=7.3.0; extra == "dev"
Requires-Dist: build>=0.10.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"

# ecat — Embedded Cat

**Embedded concatenation for context engineering.**

`ecat` works like `cat`, but wraps every source — files, shell commands, and
URLs — in a labelled Markdown code fence before writing it to stdout. The
result is ready to pipe directly into an LLM CLI or any tool that reads a
prompt from stdin.

```text
ecat [OPTIONS] [SOURCE ...]
```

A **source** is one of:

| Pattern | Treated as |
|---|---|
| `-` | stdin |
| existing file path | file contents |
| `https?://…` | fetched URL, HTML → Markdown |
| anything else | shell command output |

All blocks are joined with a blank line and written to stdout.

---

## Install

```bash
pip install ecat
```

---

## Quick Start

```bash
# Embed a file
ecat src/ecat/ecat.py

# Embed command output
ecat "git log --oneline -20"

# Embed a web page
ecat https://docs.python.org/3/library/pathlib.html

# Read a question from stdin and pipe everything to Claude
ecat schema.sql "SELECT * FROM orders LIMIT 5" \
  | claude "$(cat question.txt)"
```

---

## Usage

### Options

| Flag | Default | Description |
|---|---|---|
| `-s`, `--shell` | `bash` | Shell used to run command sources |

### Sources

**Files** are fenced with their path as the language tag:

````text
```src/ecat/ecat.py
… file contents …
```
````

**Commands** are fenced as `bash` with a `$` prompt line:

````text
```bash
$ git log --oneline -20
abc1234 fix typo
…
```
````

**URLs** are fetched, converted from HTML to Markdown, and fenced as `bash`
with the equivalent `curl` invocation shown:

````text
```bash
$ curl -s https://example.com | html2markdown
… page content in Markdown …
```
````

**Stdin** (`-`) is embedded as plain text — no fence is added so you can
supply free-form prose or a question directly.

---

## Context Engineering Patterns

`ecat` is designed to be composed with other tools via pipes. The idea is
simple: **build a rich context block, then ask a question**.

### Explain a bug

```bash
ecat src/app.py "pytest tests/ 2>&1 | tail -30" \
  | llm "Why is the test suite failing and how do I fix it?"
```

### Review a diff

```bash
git diff main | ecat - \
  | llm "Review this diff. Call out logic errors and security issues."
```

### Summarise a web page

```bash
ecat https://news.ycombinator.com \
  | llm "Give me the five most interesting links and a one-line summary of each."
```

### Generate code from a schema

```bash
ecat schema.sql \
  | llm "Generate a SQLAlchemy model file for every table in this schema."
```

### Combine multiple sources

```bash
ecat \
  README.md \
  src/ecat/ecat.py \
  "pip show ecat" \
  | llm "Write a CHANGELOG entry for the next release."
```

### Use a different shell

```bash
ecat --shell fish "status" "functions --all"
```

---

## How It Works

```
argv tokens
    │
    ├── "-"          → read stdin            ┐
    ├── file path    → read file             ├─→ Markdown code fence
    ├── https?://…   → fetch + html2md       │
    └── other        → run in shell          ┘
                                             │
                                    join with "\n\n"
                                             │
                                          stdout
```

Each source becomes one self-contained block. The LLM always knows where each
piece of context came from because the fence label carries the origin (file
path, URL, or the literal command that was run).

---

## Development

```bash
git clone https://github.com/rodolfovillaruz/ecat
cd ecat
pip install -e ".[dev]"

make check      # format-check + lint + typecheck + test
make format     # auto-format with black + isort
make test       # pytest only
```

---

## License

MIT © Rodolfo Villaruz
