Metadata-Version: 2.4
Name: ctxstash
Version: 0.1.0
Summary: Pack a codebase into one LLM-ready Markdown file with a file tree and token estimate. Zero dependencies, no server.
Author: yyfjj
License: MIT
Project-URL: Homepage, https://github.com/jjdoor/ctxstash-py
Project-URL: Repository, https://github.com/jjdoor/ctxstash-py
Project-URL: Issues, https://github.com/jjdoor/ctxstash-py/issues
Keywords: llm,ai,context,prompt,chatgpt,claude,tokens,codebase,cli,developer-tools
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# ctxstash

**Pack a codebase into one LLM-ready Markdown file — with a file tree and a token estimate. Zero dependencies, no server, no telemetry.**

You're feeding code to ChatGPT / Claude / Cursor and you keep doing the same dance: open file, copy, paste, label it, repeat — then guess whether it'll blow the context window. `ctxstash` does it in one command: walk a directory, skip the junk (`.venv`, `__pycache__`, lockfiles, binaries), and emit a single tidy Markdown document with every file fenced and language-tagged, prefixed by a tree overview and an approximate token count.

```bash
ctxstash src > context.md
```

```
✓ packed 23 files · 142.3 KB · ~38,210 tokens
```

This is the Python build. There's a matching, behavior-identical Node version: [`npx ctxstash`](https://github.com/jjdoor/ctxstash).

## Install

```bash
pip install ctxstash
```

Requires Python ≥ 3.8. No dependencies. (You can also run it without installing the script: `python -m ctxstash .`)

## Usage

```bash
ctxstash [paths...] [options]
```

```bash
ctxstash .                          # pack the current dir to stdout
ctxstash src tests > context.md     # pack two dirs, redirect to a file
ctxstash . -o context.md            # ...or write the file directly
ctxstash . -i "*.py,*.pyi"          # only Python
ctxstash . -e "*_test.py"           # drop tests
ctxstash . --estimate               # just tell me the token cost
ctxstash src --tree                 # just the file tree
```

### Options

| Option | Description |
| --- | --- |
| `-o, --out <file>` | Write to a file instead of stdout |
| `-i, --include <globs>` | Only include matching files (comma-separated, e.g. `"*.py,*.pyi"`) |
| `-e, --exclude <globs>` | Exclude matching files (comma-separated) |
| `--tree` | Print only the file tree (no contents) |
| `--no-tree` | Omit the file-tree overview from the packed output |
| `--estimate` | Print only stats (files, size, ~tokens) — pack nothing |
| `--max-size <size>` | Skip files larger than this (e.g. `256kb`, `1mb`; default: no limit) |
| `--no-default-ignore` | Don't auto-skip `node_modules` / `.git` / `dist` / lockfiles / etc. |
| `--no-color` | Disable colored stderr |
| `-h, --help` · `-v, --version` | |

Globs support `*` (within a path segment), `**` (across segments), and `?`. A
slash-less pattern like `*.py` matches at any depth.

## What you get

```markdown
# Repository context

> Packed by ctxstash — 3 files, 4.1 KB, ~1,040 tokens (estimate).

## File tree

​```
src/
  core.py
  cli.py
README.md
​```

## Files

### src/core.py

​```python
...file contents...
​```
```

The summary line always goes to **stderr**, so `ctxstash > context.md` keeps the
file clean while you still see the count in your terminal.

## Notes & limits

- **Binary files are skipped** automatically (NUL-byte / control-byte sniff), so
  images and compiled artifacts never end up in your context.
- **Token counts are an estimate** (~4 characters per token, OpenAI's rule of
  thumb) — tokenizer-agnostic and good enough for "will this fit?", not exact
  billing. For precise counts, run the output through a real tokenizer.
- **Fences are collision-safe**: if a file contains a ```` ``` ```` run, ctxstash
  wraps it in a longer fence so the Markdown stays valid.
- **Symlinks are not followed** (avoids loops).

## License

MIT
