ctx-ray
v1.0.0
Published
A surgical CLI tool that bundles your codebase into an LLM-friendly XML context file
Maintainers
Readme
Why ctx-ray?
Most tools dump your entire codebase and hope the AI figures it out. ctx-ray is surgical — it traces your import graph and packs only the files that actually matter for your task, wrapped in structured XML that modern LLMs (Claude, Gemini, GPT-4) navigate far better than raw Markdown dumps.
| Feature | ctx-ray | repomix / codefetch |
|---|---|---|
| Import-graph tracing | ✅ Surgical mode | ❌ Always dumps everything |
| XML-first output | ✅ With CDATA + metadata | ❌ Markdown only |
| .aiignore support | ✅ | ❌ |
| Token budget warnings | ✅ | ❌ |
| --diff / --since | ✅ | ❌ |
| Clipboard-only mode | ✅ | ❌ |
| Minified file detection | ✅ Auto-skipped | ❌ |
| Per-file complexity | ✅ H/M/L rating | ❌ |
Installation
npm install -g ctx-ray
# or use directly without installing
npx ctx-ray initQuick Start
# 1. Initialise in your project (creates .ctx-ray.json, .aiignore, updates .gitignore)
ctx-ray init
# 2. Bundle the entire project
ctx-ray pack
# 3. SURGICAL MODE — trace imports from a single entry file
ctx-ray pack ./src/components/UserDashboard.tsx
# 4. Only files changed since your last commit
ctx-ray pack --diff
# 5. Only files changed in the last hour
ctx-ray pack --since "1 hour ago"
# 6. Copy straight to clipboard — zero files written
ctx-ray pack --clipCommands
ctx-ray pack [entry]
The core command. Bundles files into .ctx/ai-context.xml.
| Flag | Description | Default |
|---|---|---|
| [entry] | Entry file — activates surgical mode | (full scan) |
| -d, --depth <n> | Max directory depth | unlimited |
| -o, --output <file> | Output filename | ai-context.xml |
| --output-dir <dir> | Output directory | .ctx/ |
| -l, --limit <n> | Token limit for budget warning | 50000 |
| --no-tree | Omit directory blueprint | tree included |
| --no-metadata | Omit per-file metadata blocks | metadata included |
| --no-gitignore | Ignore .gitignore rules | respected |
| --no-aiignore | Ignore .aiignore rules | respected |
| --exclude <patterns...> | Extra glob patterns to exclude | — |
| --diff | Include only files changed vs HEAD | — |
| --since <ref> | Include files changed since git ref/time | — |
| --append | Append to existing bundle (incremental) | — |
| --clip | Copy XML to clipboard instead of writing | — |
| --name <name> | Named snapshot (<name>.ctx.xml) | — |
| --tmp | Auto-delete output after 5 minutes | — |
ctx-ray init
Sets up ctx-ray in the current project:
- Creates
.ctx-ray.jsonconfig - Creates
.aiignoretemplate - Adds
.ctx/and*.ctx.xmlto.gitignore - Creates the
.ctx/directory
ctx-ray ls
Lists all XML bundles in the .ctx/ directory.
ctx-ray clean
Deletes all XML bundles in .ctx/. Prompts for confirmation unless --force is passed.
Surgical Mode — How It Works
ctx-ray pack ./src/auth/login-handler.ts --depth 3Instead of scanning everything, ctx-ray:
- Parses the AST of
login-handler.tsusingts-morph - Traces all local imports — static
import, dynamicimport(), andrequire() - Follows transitive imports up to
--depthlevels - Skips node_modules — only local project files are included
The result is a bundle that is typically 90% smaller but 100% relevant.
Output Format
<?xml version="1.0" encoding="UTF-8"?>
<repository name="my-project" generated="2026-04-25T10:00:00.000Z" fileCount="12">
<directory_blueprint><![CDATA[
my-project/
├── src/
│ ├── auth/
│ │ └── login-handler.ts
│ └── utils/
│ └── token.ts
]]></directory_blueprint>
<files>
<file path="src/auth/login-handler.ts">
<metadata>
<language>typescript</language>
<last_modified>2026-04-25</last_modified>
<size_bytes>3421</size_bytes>
<complexity>Medium</complexity>
<truncated>false</truncated>
</metadata>
<content><![CDATA[
// Your code here
]]></content>
</file>
</files>
</repository>Why XML? Claude 3.5/3.7, Gemini 1.5/2.0, and GPT-4 all handle XML tags better than raw Markdown for large codebases. Tag pairing makes file boundaries explicit, eliminating the "Lost in the Middle" syndrome.
Smart Filtering
.aiignore
Like .gitignore, but for AI context. Files here are excluded from bundles but still tracked by Git. ctx-ray creates a sensible template on init:
# .aiignore
package-lock.json
yarn.lock
*.png
*.svg
dist/
coverage/
*.min.js
*.mapSmart Defaults (always applied)
Even without .aiignore, ctx-ray auto-skips:
- Lock files (
package-lock.json,yarn.lock, etc.) - Binary/media assets (images, fonts, videos, PDFs)
- Build outputs (
dist/,build/,.next/) - Minified files (auto-detected by line-length heuristic)
- Source maps (
*.map)
Token Budget
ctx-ray pack --limit 30000 ⚠ Token budget exceeded: 87.3K / 30.0K
Largest files by token count:
● src/generated/schema.ts (41.2K tokens)
● src/data/fixtures.json (18.9K tokens)
Tip: Add these to .aiignore or use --exclude to reduce context size.Config File — .ctx-ray.json
{
"excludes": ["**/*.test.ts", "docs/**"],
"tokenLimit": 50000,
"outputDir": ".ctx",
"outputFile": "ai-context.xml"
}Typical Workflow
1. ctx-ray init # One-time setup
2. ctx-ray pack ./src/feature/entry.ts # Surgical bundle
3. Upload .ctx/ai-context.xml to AI # Feed the model
4. Make changes...
5. ctx-ray pack --since "30 min ago" # Refresh changed files only
6. ctx-ray pack --append # Add to existing bundle
7. ctx-ray clean # Purge when doneContributing
We welcome contributions! To get started:
- Install Dependencies:
This project uses
pnpm. Make sure it is installed, then run:pnpm install - Build and Test:
- To build the project:
pnpm run build - To run tests:
pnpm test
- To build the project:
- Commits:
This project enforces the Conventional Commits specification using
commitlint. Husky hooks andlint-stagedare configured to automatically format your code with Prettier and lint your commit messages. Example commit messages:feat: add surgical modefix: correct token count estimationdocs: update readme instructions
License
MIT
