Metadata-Version: 2.5
Name: ctx-packr
Version: 0.1.1
Summary: A stdlib-only CLI that packs the most relevant files of a codebase into a token-budgeted markdown bundle
Project-URL: Homepage, https://github.com/shaheersaifi07-prog/ctxpack
Project-URL: Repository, https://github.com/shaheersaifi07-prog/ctxpack
Project-URL: Issues, https://github.com/shaheersaifi07-prog/ctxpack/issues
Author: shaheersaifi07-prog
License-Expression: MIT
License-File: LICENSE
Keywords: cli,codebase,context,llm,packing,tokens
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Pre-processors
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# `ctx-packr`

A stdlib-only Python CLI that selects the most relevant files from a codebase for a given task and packs them into a token-budgeted markdown bundle.

## Why `ctx-packr`?

Several tools occupy nearby space. The difference is not quality — it is which part of
the problem each one solves.

| Tool | Approach | What it lacks vs `ctx-packr` |
|---|---|---|
| `ctxpack` | Config-driven file selection, with `init` and `watch` commands | No relevance ranking against a stated task |
| `context-packer` | Smart filtering of build artifacts and binaries, plus a visual project tree | No relevance ranking against a stated task |
| `llm-ctxpack` | Priority-based packing into a token budget | Does not walk a codebase; the caller supplies the chunks |
| `contextcram` | Priority-based packing into a token budget | Does not walk a codebase; the caller supplies the chunks |
| `ctx-pack` (Rust) | Versioned bidirectional patch/replace | Solves a different problem — not context packing |

`ctx-packr` combines four things that otherwise appear separately: it walks a real
codebase, ranks what it finds against a specific stated task, enforces a hard token
budget, and has zero runtime dependencies. Ranking uses camelCase-aware keyword
scoring, with bonuses for entry-point filenames and for files whose `def`/`class` names
match the task, offset by a penalty for directory depth. When the budget is too small
for the full bundle, the output degrades step by step — dropping the contents table,
then the summary header — rather than failing.

*Comparison reflects these projects as of September 2026.*

## Requirements

- Python 3.10+
- No third-party packages — `ctx-packr` has zero runtime dependencies

## Install

```bash
pip install ctx-packr
```

That puts a `ctx-packr` command on your PATH:

```bash
ctx-packr --path sample --task "understand the auth flow" --budget 2000 --out bundle.md --manifest manifest.json
```

> **Note on naming.** You install `ctx-packr`, but the importable module is `ctxpack`:
>
> ```python
> import ctxpack
> ```
>
> The two differ because a hyphen is not legal in a Python identifier. This is the
> same split used by `beautifulsoup4` → `bs4` and `python-dateutil` → `dateutil`.

## Quick Start (from a clone, no install)

```bash
git clone https://github.com/shaheersaifi07-prog/ctxpack.git
cd ctxpack

# Run straight from the source tree
python -m ctxpack --path sample --task "understand the auth flow" --budget 2000 --out bundle.md --manifest manifest.json

# View results
cat bundle.md
cat manifest.json
```

The source lives in `src/`, so running from a clone needs that directory importable — either `pip install -e .` once, or prefix the command with `PYTHONPATH=src` (`$env:PYTHONPATH="src"` in PowerShell).

If `--out` is omitted, the bundle prints to stdout. If `--manifest` is omitted, a one-line summary like `used 521/2000 tokens, 5 included, 0 excluded` goes to stderr.

## CLI Usage

```
ctx-packr --path <folder> --task "<desc>" --budget <int> [--out <file>] [--manifest <file>]
```

| Flag | Required | Description |
|---|---|---|
| `--path` | Yes | Target folder (must exist and be readable) |
| `--task` | Yes | Free-text description of what you're looking for |
| `--budget` | Yes | Max tokens for the entire rendered bundle (integer > 0) |
| `--out` | No | Write bundle to this file; omitted = stdout |
| `--manifest` | No | Write JSON manifest; omitted = one-line stderr |

**Exit codes:** `0` success, `1` invalid args, `2` bad path. Errors are a single human-readable line on stderr — no tracebacks.

## Example

```bash
ctx-packr --path sample --task "auth and api" --budget 2000
```

Produces a markdown bundle like this (truncated for display):

````
## src/auth.py
```
def login(username: str, password: str) -> bool:
    if not username or not password:
        return False
    return _verify_credentials(username, password)
```
````

And if `--manifest` is given, a JSON file:

```json
{
  "budget": 2000,
  "used": 521,
  "included": [
    {"path": "tests/test_auth.py", "tokens": 69, "reason": "fits within budget"},
    {"path": "src/auth.py", "tokens": 104, "reason": "fits within budget"},
    {"path": "src/api.py", "tokens": 111, "reason": "fits within budget"}
  ],
  "excluded": [
    {"path": "package-lock.json", "reason": "lockfile shape detected"}
  ]
}
```

Every file under `--path` appears exactly once — included with reason and token count, or excluded with reason.

## How It Works

1. **Walk** — recursive directory walk with 4 structural noise detectors (binary content, lockfile shape, dependency trees, build artifacts). No name blacklists.
2. **Rank** — tokenizes the task (camelCase-aware), scores files by keyword overlap with path and content, applies an entrypoint bonus and a depth penalty.
3. **Pack** — greedily fills the token budget. Files that don't fully fit get a 70/30 head-and-tail truncation with a marker line; files that can't be meaningfully truncated (<200 tokens) are excluded cleanly.
4. **Render** — assembles markdown sections. Optionally includes a project tree overview for folders with 15+ relevant files (capped at 5% of budget).
5. **Manifest** — JSON accounting for every file. `used` is the exact token count of the rendered bundle, verified by re-tokenizing before writing.

See [SPEC.md](SPEC.md) for the full spec, [CLARIFY.md](.specify/memory/clarify.md) for design decisions, and [PLAN.md](.specify/memory/plan.md) for the implementation plan.

## Known Limitations

- **No semantic understanding.** Matching is keyword-based with camelCase splitting — a task about "authentication" won't match a file about "login" unless the words overlap. This is an accepted tradeoff for an offline, stdlib-only, deterministic tool.
- **No language-aware parsing.** No import graphs, AST analysis, or per-language heuristics. Path and content keyword overlap is the only signal.
- **No incremental runs.** Every invocation does a fresh walk from scratch — no caching between runs.
- **No `.gitignore` support.** Hidden test folders may contain files a developer would typically exclude. The tool treats all readable files equally; structural noise is caught by content-shape detection, not ignore files.

This is a **Spec-Driven Development** project. The spec was written before any code, and all decisions are documented in the spec chain under `.specify/memory/`.
