ctxl-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ctxl_cli-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Prashanth Reddy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: ctxl-cli
3
+ Version: 0.1.0
4
+ Summary: Context Engineering CLI — Reduce AI agent token waste with compressed codebase skeletons, task-focused instructions, and session checkpoints. Zero AI, pure parsing.
5
+ Author: Prashanth Reddy
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/prashanthreddy/ctxl
8
+ Project-URL: Repository, https://github.com/prashanthreddy/ctxl
9
+ Project-URL: Issues, https://github.com/prashanthreddy/ctxl/issues
10
+ Keywords: context-engineering,llm,ai-agents,token-optimization,copilot,tree-sitter,codebase-map,developer-tools
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: click>=8.1
26
+ Requires-Dist: tree-sitter>=0.24
27
+ Requires-Dist: tree-sitter-python>=0.23
28
+ Requires-Dist: tree-sitter-javascript>=0.23
29
+ Requires-Dist: tree-sitter-java>=0.23
30
+ Requires-Dist: tree-sitter-typescript>=0.23
31
+ Requires-Dist: rich>=13.0
32
+ Provides-Extra: clipboard
33
+ Requires-Dist: pyperclip>=1.8; extra == "clipboard"
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=7.0; extra == "dev"
36
+ Requires-Dist: build; extra == "dev"
37
+ Requires-Dist: twine; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # ctxl — Context Engineering CLI for AI Agents
41
+
42
+ **Reduce token waste. Prevent hallucination. Zero AI used.**
43
+
44
+ `ctxl` (pronounced "contextual") is a developer CLI tool that helps you manage the context window of AI coding agents (GitHub Copilot, Cursor, Claude, etc.) by generating compressed codebase skeletons, task-focused instructions, and session checkpoints — all using deterministic parsing, not AI.
45
+
46
+ ## The Problem
47
+
48
+ AI coding agents (Copilot, Cursor, etc.) read your entire codebase to build context. A 3,000-line PySpark file burns ~750 tokens every time the agent references it. Over a session, your context window fills with noise, leading to:
49
+
50
+ - 🔴 **Hallucination** — the model starts making things up
51
+ - 🔴 **Token waste** — you pay for irrelevant context
52
+ - 🔴 **Lost focus** — the agent forgets your actual task
53
+
54
+ ## The Solution
55
+
56
+ `ctxl` gives you three commands that prepare your environment *before* the AI agent reads it:
57
+
58
+ ```bash
59
+ ctxl map # Generate a compressed codebase skeleton (~95% token reduction)
60
+ ctxl init # Generate task-focused Copilot instructions
61
+ ctxl checkpoint # Save session state for safe /clear workflows
62
+ ```
63
+
64
+ **Zero AI models. Zero API calls. Zero tokens burned by this tool.**
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install ctxl-cli
70
+ ```
71
+
72
+ ## Quick Start
73
+
74
+ ### `ctxl map` — Codebase Skeleton
75
+
76
+ Generate a compressed structural map of your codebase with line numbers:
77
+
78
+ ```bash
79
+ ctxl map # Map current directory
80
+ ctxl map ./src # Map a specific directory
81
+ ctxl map -e .py # Only Python files
82
+ ctxl map -o codebase.md # Save to file
83
+ ctxl map --clipboard # Copy to clipboard for pasting into AI chat
84
+ ```
85
+
86
+ **Before (raw file, ~750 tokens):**
87
+ ```python
88
+ class DataPipeline:
89
+ def __init__(self, spark, config):
90
+ self.spark = spark
91
+ self.config = config
92
+ self.source_path = config.get("source_path", "/data/raw")
93
+ # ... 60 more lines of implementation
94
+
95
+ def clean_data(self, df, drop_nulls=True):
96
+ string_cols = [f.name for f in df.schema.fields ...]
97
+ # ... 20 more lines
98
+ ```
99
+
100
+ **After (`ctxl map` output, ~50 tokens):**
101
+ ```
102
+ L22: class DataPipeline:
103
+ L25: def __init__(self, spark: SparkSession, config: Dict)
104
+ L33: def load_data(self, table_name: str, filters: Optional[Dict] = None) -> DataFrame
105
+ L42: def clean_data(self, df: DataFrame, drop_nulls: bool = True) -> DataFrame
106
+ L52: def transform(self, df: DataFrame, rules: List[Dict]) -> DataFrame
107
+ L66: def validate(self, df: DataFrame) -> bool
108
+ L75: def save(self, df: DataFrame, partition_cols: List[str] = None) -> str
109
+ ```
110
+
111
+ Line numbers (`L22:`, `L42:`) let the AI agent navigate directly to the right location.
112
+
113
+ ### `ctxl init` — Copilot Instructions
114
+
115
+ Generate a `.github/copilot-instructions.md` file that GitHub Copilot reads natively:
116
+
117
+ ```bash
118
+ ctxl init "Fix the data pipeline ETL bug"
119
+ ctxl init "Add authentication" -f auth.py -f models.py
120
+ ctxl init "Refactor tests" --no-map
121
+ ```
122
+
123
+ ### `ctxl checkpoint` — Session State
124
+
125
+ Save your progress before running `/clear` in Copilot Chat:
126
+
127
+ ```bash
128
+ ctxl checkpoint save \
129
+ -t "Fix ETL pipeline" \
130
+ --done "Found the bug in clean_data()" \
131
+ --state "Pipeline runs but output has wrong column order" \
132
+ --next "Fix column ordering in transform()" \
133
+ --file "data_pipeline.py"
134
+
135
+ ctxl checkpoint list # List all checkpoints
136
+ ctxl checkpoint show # Show latest checkpoint
137
+ ```
138
+
139
+ ## Supported Languages
140
+
141
+ `ctxl map` uses [Tree-sitter](https://tree-sitter.github.io/) for parsing and supports:
142
+
143
+ | Language | Extensions |
144
+ |----------|-----------|
145
+ | Python | `.py` |
146
+ | JavaScript | `.js`, `.jsx` |
147
+ | TypeScript | `.ts`, `.tsx` |
148
+ | Java | `.java` |
149
+
150
+ More languages can be added easily via Tree-sitter grammars.
151
+
152
+ ## How It Works
153
+
154
+ ```
155
+ Your Codebase (10,000+ tokens)
156
+
157
+
158
+ Tree-sitter Parser (deterministic, local, free)
159
+
160
+
161
+ AST → Extract signatures + line numbers
162
+
163
+
164
+ Compressed Skeleton (~500 tokens)
165
+
166
+
167
+ AI Agent reads skeleton instead of raw code
168
+
169
+
170
+ 90-95% fewer tokens burned 🎉
171
+ ```
172
+
173
+ ## License
174
+
175
+ MIT
@@ -0,0 +1,136 @@
1
+ # ctxl — Context Engineering CLI for AI Agents
2
+
3
+ **Reduce token waste. Prevent hallucination. Zero AI used.**
4
+
5
+ `ctxl` (pronounced "contextual") is a developer CLI tool that helps you manage the context window of AI coding agents (GitHub Copilot, Cursor, Claude, etc.) by generating compressed codebase skeletons, task-focused instructions, and session checkpoints — all using deterministic parsing, not AI.
6
+
7
+ ## The Problem
8
+
9
+ AI coding agents (Copilot, Cursor, etc.) read your entire codebase to build context. A 3,000-line PySpark file burns ~750 tokens every time the agent references it. Over a session, your context window fills with noise, leading to:
10
+
11
+ - 🔴 **Hallucination** — the model starts making things up
12
+ - 🔴 **Token waste** — you pay for irrelevant context
13
+ - 🔴 **Lost focus** — the agent forgets your actual task
14
+
15
+ ## The Solution
16
+
17
+ `ctxl` gives you three commands that prepare your environment *before* the AI agent reads it:
18
+
19
+ ```bash
20
+ ctxl map # Generate a compressed codebase skeleton (~95% token reduction)
21
+ ctxl init # Generate task-focused Copilot instructions
22
+ ctxl checkpoint # Save session state for safe /clear workflows
23
+ ```
24
+
25
+ **Zero AI models. Zero API calls. Zero tokens burned by this tool.**
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install ctxl-cli
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ### `ctxl map` — Codebase Skeleton
36
+
37
+ Generate a compressed structural map of your codebase with line numbers:
38
+
39
+ ```bash
40
+ ctxl map # Map current directory
41
+ ctxl map ./src # Map a specific directory
42
+ ctxl map -e .py # Only Python files
43
+ ctxl map -o codebase.md # Save to file
44
+ ctxl map --clipboard # Copy to clipboard for pasting into AI chat
45
+ ```
46
+
47
+ **Before (raw file, ~750 tokens):**
48
+ ```python
49
+ class DataPipeline:
50
+ def __init__(self, spark, config):
51
+ self.spark = spark
52
+ self.config = config
53
+ self.source_path = config.get("source_path", "/data/raw")
54
+ # ... 60 more lines of implementation
55
+
56
+ def clean_data(self, df, drop_nulls=True):
57
+ string_cols = [f.name for f in df.schema.fields ...]
58
+ # ... 20 more lines
59
+ ```
60
+
61
+ **After (`ctxl map` output, ~50 tokens):**
62
+ ```
63
+ L22: class DataPipeline:
64
+ L25: def __init__(self, spark: SparkSession, config: Dict)
65
+ L33: def load_data(self, table_name: str, filters: Optional[Dict] = None) -> DataFrame
66
+ L42: def clean_data(self, df: DataFrame, drop_nulls: bool = True) -> DataFrame
67
+ L52: def transform(self, df: DataFrame, rules: List[Dict]) -> DataFrame
68
+ L66: def validate(self, df: DataFrame) -> bool
69
+ L75: def save(self, df: DataFrame, partition_cols: List[str] = None) -> str
70
+ ```
71
+
72
+ Line numbers (`L22:`, `L42:`) let the AI agent navigate directly to the right location.
73
+
74
+ ### `ctxl init` — Copilot Instructions
75
+
76
+ Generate a `.github/copilot-instructions.md` file that GitHub Copilot reads natively:
77
+
78
+ ```bash
79
+ ctxl init "Fix the data pipeline ETL bug"
80
+ ctxl init "Add authentication" -f auth.py -f models.py
81
+ ctxl init "Refactor tests" --no-map
82
+ ```
83
+
84
+ ### `ctxl checkpoint` — Session State
85
+
86
+ Save your progress before running `/clear` in Copilot Chat:
87
+
88
+ ```bash
89
+ ctxl checkpoint save \
90
+ -t "Fix ETL pipeline" \
91
+ --done "Found the bug in clean_data()" \
92
+ --state "Pipeline runs but output has wrong column order" \
93
+ --next "Fix column ordering in transform()" \
94
+ --file "data_pipeline.py"
95
+
96
+ ctxl checkpoint list # List all checkpoints
97
+ ctxl checkpoint show # Show latest checkpoint
98
+ ```
99
+
100
+ ## Supported Languages
101
+
102
+ `ctxl map` uses [Tree-sitter](https://tree-sitter.github.io/) for parsing and supports:
103
+
104
+ | Language | Extensions |
105
+ |----------|-----------|
106
+ | Python | `.py` |
107
+ | JavaScript | `.js`, `.jsx` |
108
+ | TypeScript | `.ts`, `.tsx` |
109
+ | Java | `.java` |
110
+
111
+ More languages can be added easily via Tree-sitter grammars.
112
+
113
+ ## How It Works
114
+
115
+ ```
116
+ Your Codebase (10,000+ tokens)
117
+
118
+
119
+ Tree-sitter Parser (deterministic, local, free)
120
+
121
+
122
+ AST → Extract signatures + line numbers
123
+
124
+
125
+ Compressed Skeleton (~500 tokens)
126
+
127
+
128
+ AI Agent reads skeleton instead of raw code
129
+
130
+
131
+ 90-95% fewer tokens burned 🎉
132
+ ```
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,3 @@
1
+ """ctxl — Context Engineering CLI for AI agents."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,130 @@
1
+ """
2
+ ctx checkpoint — Session state manager.
3
+
4
+ Tracks what the AI agent has learned during a session (files edited,
5
+ schemas discovered, errors resolved) and saves a compressed checkpoint.
6
+ This allows you to safely run /clear in Copilot Chat without losing context.
7
+ """
8
+
9
+ import json
10
+ from datetime import datetime
11
+ from pathlib import Path
12
+ from typing import Dict, List, Optional
13
+
14
+
15
+ CHECKPOINT_DIR = ".ctx_checkpoints"
16
+
17
+
18
+ def _ensure_dir(project_root: str) -> Path:
19
+ """Ensure the checkpoint directory exists."""
20
+ path = Path(project_root).resolve() / CHECKPOINT_DIR
21
+ path.mkdir(parents=True, exist_ok=True)
22
+ return path
23
+
24
+
25
+ def create_checkpoint(
26
+ project_root: str,
27
+ task: str,
28
+ completed_steps: List[str],
29
+ current_state: str,
30
+ next_steps: List[str],
31
+ files_modified: Optional[List[str]] = None,
32
+ key_discoveries: Optional[List[str]] = None,
33
+ errors_resolved: Optional[List[str]] = None,
34
+ ) -> str:
35
+ """
36
+ Create a checkpoint file capturing the current session state.
37
+
38
+ Args:
39
+ project_root: Path to the project root directory.
40
+ task: The high-level task description.
41
+ completed_steps: List of steps already completed.
42
+ current_state: Brief description of where things stand right now.
43
+ next_steps: List of planned next steps.
44
+ files_modified: List of files that were modified.
45
+ key_discoveries: Key things learned (schemas, configs, etc.).
46
+ errors_resolved: Errors that were encountered and resolved.
47
+
48
+ Returns:
49
+ Path to the created checkpoint file.
50
+ """
51
+ checkpoint_dir = _ensure_dir(project_root)
52
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
53
+ filename = f"checkpoint_{timestamp}.md"
54
+ filepath = checkpoint_dir / filename
55
+
56
+ lines = []
57
+ lines.append(f"# Session Checkpoint")
58
+ lines.append(f"_Saved at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}_\n")
59
+
60
+ lines.append(f"## Task")
61
+ lines.append(f"{task}\n")
62
+
63
+ lines.append(f"## Current State")
64
+ lines.append(f"{current_state}\n")
65
+
66
+ if completed_steps:
67
+ lines.append("## Completed Steps")
68
+ for step in completed_steps:
69
+ lines.append(f"- [x] {step}")
70
+ lines.append("")
71
+
72
+ if next_steps:
73
+ lines.append("## Next Steps")
74
+ for step in next_steps:
75
+ lines.append(f"- [ ] {step}")
76
+ lines.append("")
77
+
78
+ if files_modified:
79
+ lines.append("## Files Modified")
80
+ for f in files_modified:
81
+ lines.append(f"- `{f}`")
82
+ lines.append("")
83
+
84
+ if key_discoveries:
85
+ lines.append("## Key Discoveries")
86
+ for d in key_discoveries:
87
+ lines.append(f"- {d}")
88
+ lines.append("")
89
+
90
+ if errors_resolved:
91
+ lines.append("## Errors Resolved")
92
+ for e in errors_resolved:
93
+ lines.append(f"- {e}")
94
+ lines.append("")
95
+
96
+ lines.append("---")
97
+ lines.append("_Paste this into your active file or Copilot Chat after running `/clear`._")
98
+
99
+ content = "\n".join(lines)
100
+ filepath.write_text(content, encoding="utf-8")
101
+
102
+ return str(filepath)
103
+
104
+
105
+ def list_checkpoints(project_root: str) -> List[Dict]:
106
+ """List all checkpoints in the project, newest first."""
107
+ checkpoint_dir = Path(project_root).resolve() / CHECKPOINT_DIR
108
+ if not checkpoint_dir.exists():
109
+ return []
110
+
111
+ checkpoints = []
112
+ for f in sorted(checkpoint_dir.glob("checkpoint_*.md"), reverse=True):
113
+ stat = f.stat()
114
+ checkpoints.append({
115
+ "filename": f.name,
116
+ "path": str(f),
117
+ "created": datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M:%S"),
118
+ "size_bytes": stat.st_size,
119
+ })
120
+
121
+ return checkpoints
122
+
123
+
124
+ def get_latest_checkpoint(project_root: str) -> Optional[str]:
125
+ """Read the content of the most recent checkpoint."""
126
+ checkpoints = list_checkpoints(project_root)
127
+ if not checkpoints:
128
+ return None
129
+ latest_path = checkpoints[0]["path"]
130
+ return Path(latest_path).read_text(encoding="utf-8")