context-gen-cli 1.2.0__tar.gz → 1.2.5__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.
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/PKG-INFO +28 -50
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/README.md +27 -49
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/cli.py +257 -16
- context_gen_cli-1.2.5/context_gen/mcp/__init__.py +3 -0
- context_gen_cli-1.2.5/context_gen/mcp/advanced_tools.py +475 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/scanner.py +1 -1
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/PKG-INFO +28 -50
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/SOURCES.txt +4 -1
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/entry_points.txt +1 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/pyproject.toml +2 -1
- context_gen_cli-1.2.5/tests/test_advanced_tools.py +74 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/__init__.py +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/extractor.py +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/generator.py +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen/graph.py +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/dependency_links.txt +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/requires.txt +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/context_gen_cli.egg-info/top_level.txt +0 -0
- {context_gen_cli-1.2.0 → context_gen_cli-1.2.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: context-gen-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
4
4
|
Summary: A modern CLI tool that scans any project, builds an AST-based dependency graph, and generates structured LLM context (agent.md / agent.json).
|
|
5
5
|
Author: yakkshit
|
|
6
6
|
License-Expression: MIT
|
|
@@ -25,7 +25,7 @@ Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
|
25
25
|
Requires-Dist: build>=1.1.0; extra == "dev"
|
|
26
26
|
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
27
27
|
|
|
28
|
-
# ⚡ context-gen-cli (Python Edition
|
|
28
|
+
# ⚡ context-gen-cli (`ctx`) — Python Edition
|
|
29
29
|
|
|
30
30
|
[](https://pypi.org/project/context-gen-cli/)
|
|
31
31
|
[](https://pypi.org/project/context-gen-cli/)
|
|
@@ -37,13 +37,14 @@ Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
|
37
37
|
|
|
38
38
|
## 🌟 Highlights
|
|
39
39
|
|
|
40
|
-
-
|
|
40
|
+
- **⚡ Short Command Alias (`ctx`)**: Type `ctx` anywhere in your terminal.
|
|
41
|
+
- **100% Accurate Python Dependency Graphs**: Built using Python's native `ast` (Abstract Syntax Tree) module to resolve imports, relative packages, entry points, and utilities.
|
|
42
|
+
- **📁 Clean Workspace Storage**: Everything (`agent.md`, `agent.json`, `agent.yaml`, `.context-gen.json`) is saved neatly inside `context/`.
|
|
41
43
|
- **⚡ All-In-One Default Mode (`-d`)**: Auto-generates triple context formats in `context/` and runs a live auto-sync watcher in the background.
|
|
42
44
|
- **`.gitignore` & Multi-Ignore Respect**: Automatically parses rules from `.gitignore`, `.npmignore`, `.dockerignore`, `.contextignore`, `.ignore`, and filters `.env*` secrets.
|
|
43
45
|
- **Triple Format Output**: Generates Markdown (`agent.md`), MCP-compatible structured JSON (`agent.json`), and clean YAML (`agent.yaml`).
|
|
44
46
|
- **🔄 Auto-Sync Watch Mode (`-w`)**: Monitors workspace changes and updates context files automatically on save.
|
|
45
|
-
- **Configuration Parity**: Seamlessly reads
|
|
46
|
-
- **Modern CLI**: Styled with `typer` and `rich` for rich terminal output and progress reporting.
|
|
47
|
+
- **Configuration Parity**: Seamlessly reads `context/.context-gen.json` to maintain unified project settings with the Node.js edition.
|
|
47
48
|
|
|
48
49
|
---
|
|
49
50
|
|
|
@@ -63,75 +64,52 @@ pip install context-gen-cli
|
|
|
63
64
|
Generates all formats in `context/` and starts the live auto-sync watcher in background:
|
|
64
65
|
|
|
65
66
|
```bash
|
|
66
|
-
|
|
67
|
+
ctx -d
|
|
67
68
|
```
|
|
68
69
|
|
|
69
70
|
### 2. Generate All Formats (Markdown, JSON, YAML)
|
|
70
71
|
Scans the current directory and outputs `agent.md`, `agent.json`, and `agent.yaml` in `context/`:
|
|
71
72
|
|
|
72
73
|
```bash
|
|
73
|
-
|
|
74
|
+
ctx
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
### 3.
|
|
77
|
-
Generate only the format you need:
|
|
78
|
-
|
|
77
|
+
### 3. Quick Refresh / Regenerate
|
|
79
78
|
```bash
|
|
80
|
-
|
|
81
|
-
context-gen . --format json
|
|
82
|
-
|
|
83
|
-
# Generate Markdown
|
|
84
|
-
context-gen . --format md
|
|
85
|
-
|
|
86
|
-
# Generate YAML
|
|
87
|
-
context-gen . --format yaml
|
|
79
|
+
ctx update
|
|
88
80
|
```
|
|
89
81
|
|
|
90
|
-
### 4.
|
|
91
|
-
Keep context files fresh automatically on every file edit:
|
|
92
|
-
|
|
82
|
+
### 4. Custom Format & Output Destination
|
|
93
83
|
```bash
|
|
94
|
-
|
|
84
|
+
ctx update -f json
|
|
85
|
+
ctx -o custom_docs/
|
|
86
|
+
ctx -p /path/to/project
|
|
95
87
|
```
|
|
96
88
|
|
|
97
|
-
### 5.
|
|
89
|
+
### 5. Watch Mode
|
|
90
|
+
Keep context files fresh automatically on every file edit:
|
|
91
|
+
|
|
98
92
|
```bash
|
|
99
|
-
|
|
93
|
+
ctx -w
|
|
100
94
|
```
|
|
101
95
|
|
|
102
96
|
---
|
|
103
97
|
|
|
104
98
|
## 📖 CLI Reference
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-o, --output PATH Custom output file path (e.g. context/agent.md or custom.json)
|
|
116
|
-
-w, --watch Watch directory and auto-regenerate context on file changes
|
|
117
|
-
--max-depth INTEGER Maximum directory depth to scan (1-10) [default: 3]
|
|
118
|
-
--help Show this message and exit
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## 🌐 Node.js & Live MCP Server
|
|
124
|
-
|
|
125
|
-
Looking for the live MCP server with interactive SSE streaming and public tunnels? Check out the [Node.js edition](https://www.npmjs.com/package/context-gen-cli):
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
npx context-gen-cli -d
|
|
129
|
-
# or
|
|
130
|
-
npx context-gen-cli --mcp
|
|
131
|
-
```
|
|
100
|
+
| Flag / Command | Alias | Description |
|
|
101
|
+
| :--- | :--- | :--- |
|
|
102
|
+
| `ctx -d` | `ctx --default` | **⚡ All-in-One**: Generates context files and starts live auto-sync watcher |
|
|
103
|
+
| `ctx -w` | `ctx --watch` | **👀 Watch Mode**: Auto-regenerates context on file changes |
|
|
104
|
+
| `ctx -f <type>` | `ctx --format <type>` | **Format**: `md`, `json`, `yaml`, or `all` |
|
|
105
|
+
| `ctx -o <path>` | `ctx --output <path>` | **Custom Output**: Output file/folder path |
|
|
106
|
+
| `ctx -p <path>` | `ctx --project <path>` | **Target Directory**: Directory to analyze |
|
|
107
|
+
| `ctx update` | — | **Refresh**: Regenerate context files |
|
|
108
|
+
| `ctx --help` | — | View full help options |
|
|
132
109
|
|
|
133
110
|
---
|
|
134
111
|
|
|
135
112
|
## 📄 License
|
|
136
113
|
|
|
137
114
|
MIT © [yakkshit](https://github.com/yakkshit)
|
|
115
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ⚡ context-gen-cli (Python Edition
|
|
1
|
+
# ⚡ context-gen-cli (`ctx`) — Python Edition
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/context-gen-cli/)
|
|
4
4
|
[](https://pypi.org/project/context-gen-cli/)
|
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
## 🌟 Highlights
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- **⚡ Short Command Alias (`ctx`)**: Type `ctx` anywhere in your terminal.
|
|
14
|
+
- **100% Accurate Python Dependency Graphs**: Built using Python's native `ast` (Abstract Syntax Tree) module to resolve imports, relative packages, entry points, and utilities.
|
|
15
|
+
- **📁 Clean Workspace Storage**: Everything (`agent.md`, `agent.json`, `agent.yaml`, `.context-gen.json`) is saved neatly inside `context/`.
|
|
14
16
|
- **⚡ All-In-One Default Mode (`-d`)**: Auto-generates triple context formats in `context/` and runs a live auto-sync watcher in the background.
|
|
15
17
|
- **`.gitignore` & Multi-Ignore Respect**: Automatically parses rules from `.gitignore`, `.npmignore`, `.dockerignore`, `.contextignore`, `.ignore`, and filters `.env*` secrets.
|
|
16
18
|
- **Triple Format Output**: Generates Markdown (`agent.md`), MCP-compatible structured JSON (`agent.json`), and clean YAML (`agent.yaml`).
|
|
17
19
|
- **🔄 Auto-Sync Watch Mode (`-w`)**: Monitors workspace changes and updates context files automatically on save.
|
|
18
|
-
- **Configuration Parity**: Seamlessly reads
|
|
19
|
-
- **Modern CLI**: Styled with `typer` and `rich` for rich terminal output and progress reporting.
|
|
20
|
+
- **Configuration Parity**: Seamlessly reads `context/.context-gen.json` to maintain unified project settings with the Node.js edition.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -36,75 +37,52 @@ pip install context-gen-cli
|
|
|
36
37
|
Generates all formats in `context/` and starts the live auto-sync watcher in background:
|
|
37
38
|
|
|
38
39
|
```bash
|
|
39
|
-
|
|
40
|
+
ctx -d
|
|
40
41
|
```
|
|
41
42
|
|
|
42
43
|
### 2. Generate All Formats (Markdown, JSON, YAML)
|
|
43
44
|
Scans the current directory and outputs `agent.md`, `agent.json`, and `agent.yaml` in `context/`:
|
|
44
45
|
|
|
45
46
|
```bash
|
|
46
|
-
|
|
47
|
+
ctx
|
|
47
48
|
```
|
|
48
49
|
|
|
49
|
-
### 3.
|
|
50
|
-
Generate only the format you need:
|
|
51
|
-
|
|
50
|
+
### 3. Quick Refresh / Regenerate
|
|
52
51
|
```bash
|
|
53
|
-
|
|
54
|
-
context-gen . --format json
|
|
55
|
-
|
|
56
|
-
# Generate Markdown
|
|
57
|
-
context-gen . --format md
|
|
58
|
-
|
|
59
|
-
# Generate YAML
|
|
60
|
-
context-gen . --format yaml
|
|
52
|
+
ctx update
|
|
61
53
|
```
|
|
62
54
|
|
|
63
|
-
### 4.
|
|
64
|
-
Keep context files fresh automatically on every file edit:
|
|
65
|
-
|
|
55
|
+
### 4. Custom Format & Output Destination
|
|
66
56
|
```bash
|
|
67
|
-
|
|
57
|
+
ctx update -f json
|
|
58
|
+
ctx -o custom_docs/
|
|
59
|
+
ctx -p /path/to/project
|
|
68
60
|
```
|
|
69
61
|
|
|
70
|
-
### 5.
|
|
62
|
+
### 5. Watch Mode
|
|
63
|
+
Keep context files fresh automatically on every file edit:
|
|
64
|
+
|
|
71
65
|
```bash
|
|
72
|
-
|
|
66
|
+
ctx -w
|
|
73
67
|
```
|
|
74
68
|
|
|
75
69
|
---
|
|
76
70
|
|
|
77
71
|
## 📖 CLI Reference
|
|
78
72
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-o, --output PATH Custom output file path (e.g. context/agent.md or custom.json)
|
|
89
|
-
-w, --watch Watch directory and auto-regenerate context on file changes
|
|
90
|
-
--max-depth INTEGER Maximum directory depth to scan (1-10) [default: 3]
|
|
91
|
-
--help Show this message and exit
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## 🌐 Node.js & Live MCP Server
|
|
97
|
-
|
|
98
|
-
Looking for the live MCP server with interactive SSE streaming and public tunnels? Check out the [Node.js edition](https://www.npmjs.com/package/context-gen-cli):
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
npx context-gen-cli -d
|
|
102
|
-
# or
|
|
103
|
-
npx context-gen-cli --mcp
|
|
104
|
-
```
|
|
73
|
+
| Flag / Command | Alias | Description |
|
|
74
|
+
| :--- | :--- | :--- |
|
|
75
|
+
| `ctx -d` | `ctx --default` | **⚡ All-in-One**: Generates context files and starts live auto-sync watcher |
|
|
76
|
+
| `ctx -w` | `ctx --watch` | **👀 Watch Mode**: Auto-regenerates context on file changes |
|
|
77
|
+
| `ctx -f <type>` | `ctx --format <type>` | **Format**: `md`, `json`, `yaml`, or `all` |
|
|
78
|
+
| `ctx -o <path>` | `ctx --output <path>` | **Custom Output**: Output file/folder path |
|
|
79
|
+
| `ctx -p <path>` | `ctx --project <path>` | **Target Directory**: Directory to analyze |
|
|
80
|
+
| `ctx update` | — | **Refresh**: Regenerate context files |
|
|
81
|
+
| `ctx --help` | — | View full help options |
|
|
105
82
|
|
|
106
83
|
---
|
|
107
84
|
|
|
108
85
|
## 📄 License
|
|
109
86
|
|
|
110
87
|
MIT © [yakkshit](https://github.com/yakkshit)
|
|
88
|
+
|
|
@@ -12,6 +12,8 @@ import typer
|
|
|
12
12
|
from rich.console import Console
|
|
13
13
|
from rich.panel import Panel
|
|
14
14
|
from rich.table import Table
|
|
15
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TaskProgressColumn, TimeElapsedColumn
|
|
16
|
+
from rich.text import Text
|
|
15
17
|
|
|
16
18
|
from context_gen.scanner import scan_project
|
|
17
19
|
from context_gen.extractor import extract_metadata
|
|
@@ -50,9 +52,12 @@ def execute_generation(
|
|
|
50
52
|
metadata = extract_metadata(str(target_dir), files)
|
|
51
53
|
graph = build_dependency_graph(files, str(target_dir))
|
|
52
54
|
|
|
53
|
-
# Read output directory from
|
|
54
|
-
config_file = target_dir / ".context-gen.json"
|
|
55
|
+
# Read output directory from context/.context-gen.json or legacy .context-gen.json
|
|
55
56
|
output_dir_name = "context"
|
|
57
|
+
config_file = target_dir / "context" / ".context-gen.json"
|
|
58
|
+
if not config_file.is_file():
|
|
59
|
+
config_file = target_dir / ".context-gen.json"
|
|
60
|
+
|
|
56
61
|
if config_file.is_file():
|
|
57
62
|
try:
|
|
58
63
|
with open(config_file, "r", encoding="utf-8") as f:
|
|
@@ -166,7 +171,16 @@ def main(
|
|
|
166
171
|
path: Path = typer.Argument(
|
|
167
172
|
default=Path("."),
|
|
168
173
|
help="Target project directory to analyze.",
|
|
169
|
-
|
|
174
|
+
file_okay=False,
|
|
175
|
+
dir_okay=True,
|
|
176
|
+
readable=True,
|
|
177
|
+
resolve_path=True,
|
|
178
|
+
),
|
|
179
|
+
project: Optional[Path] = typer.Option(
|
|
180
|
+
None,
|
|
181
|
+
"--project",
|
|
182
|
+
"-p",
|
|
183
|
+
help="Target project directory to analyze.",
|
|
170
184
|
file_okay=False,
|
|
171
185
|
dir_okay=True,
|
|
172
186
|
readable=True,
|
|
@@ -185,6 +199,18 @@ def main(
|
|
|
185
199
|
help="Output format: 'all', 'md', 'json', or 'yaml'.",
|
|
186
200
|
case_sensitive=False,
|
|
187
201
|
),
|
|
202
|
+
mcp: bool = typer.Option(
|
|
203
|
+
False,
|
|
204
|
+
"--mcp",
|
|
205
|
+
"-m",
|
|
206
|
+
help="Start MCP server mode.",
|
|
207
|
+
),
|
|
208
|
+
interactive: bool = typer.Option(
|
|
209
|
+
False,
|
|
210
|
+
"--interactive",
|
|
211
|
+
"-i",
|
|
212
|
+
help="Run in interactive mode.",
|
|
213
|
+
),
|
|
188
214
|
output: Optional[Path] = typer.Option(
|
|
189
215
|
None,
|
|
190
216
|
"--output",
|
|
@@ -208,7 +234,190 @@ def main(
|
|
|
208
234
|
"""
|
|
209
235
|
Scan a project, build an AST-powered dependency graph, and generate LLM context.
|
|
210
236
|
"""
|
|
211
|
-
target_dir = path.resolve()
|
|
237
|
+
target_dir = (project or path).resolve()
|
|
238
|
+
|
|
239
|
+
# If -d / --default is supplied, generate all formats and keep watch running
|
|
240
|
+
def print_python_banner():
|
|
241
|
+
"""Renders a stylish ASCII gradient banner in Python CLI."""
|
|
242
|
+
banner = """
|
|
243
|
+
___ _ _ __
|
|
244
|
+
/ __| |_ \ \/ /
|
|
245
|
+
| (__| _| > <
|
|
246
|
+
\___|\__|/_/\_\
|
|
247
|
+
"""
|
|
248
|
+
console.print(f"[bold magenta]{banner}[/bold magenta]")
|
|
249
|
+
console.print(Panel.fit("[bold cyan]⚡ context-gen-cli (ctx)[/bold cyan] — [magenta]AST AI Project Context Generator[/magenta]", border_style="cyan"))
|
|
250
|
+
console.print("")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def execute_generation_with_progress(
|
|
254
|
+
target_dir: Path,
|
|
255
|
+
format_choice: OutputFormat,
|
|
256
|
+
output_override: Optional[Path] = None,
|
|
257
|
+
max_depth: int = 3
|
|
258
|
+
) -> dict:
|
|
259
|
+
"""Executes the pipeline with rich progress bar animation."""
|
|
260
|
+
with Progress(
|
|
261
|
+
SpinnerColumn("dots", style="cyan"),
|
|
262
|
+
TextColumn("[bold blue]{task.description}"),
|
|
263
|
+
BarColumn(bar_width=35, complete_style="magenta", finished_style="green"),
|
|
264
|
+
TaskProgressColumn(),
|
|
265
|
+
TimeElapsedColumn(),
|
|
266
|
+
console=console
|
|
267
|
+
) as progress:
|
|
268
|
+
t1 = progress.add_task("🔍 Scanning workspace files & security ignores...", total=100)
|
|
269
|
+
scan_result = scan_project(str(target_dir), max_depth=max_depth)
|
|
270
|
+
time.sleep(0.08)
|
|
271
|
+
progress.update(t1, completed=100)
|
|
272
|
+
|
|
273
|
+
t2 = progress.add_task("📦 Extracting metadata & tech stack signals...", total=100)
|
|
274
|
+
files = scan_result["files"]
|
|
275
|
+
tree = scan_result["tree"]
|
|
276
|
+
metadata = extract_metadata(str(target_dir), files)
|
|
277
|
+
time.sleep(0.08)
|
|
278
|
+
progress.update(t2, completed=100)
|
|
279
|
+
|
|
280
|
+
t3 = progress.add_task("🕸️ Parsing AST module dependency graph...", total=100)
|
|
281
|
+
graph = build_dependency_graph(files, str(target_dir))
|
|
282
|
+
time.sleep(0.08)
|
|
283
|
+
progress.update(t3, completed=100)
|
|
284
|
+
|
|
285
|
+
t4 = progress.add_task(f"✍️ Generating context artifacts ({format_choice.value})...", total=100)
|
|
286
|
+
|
|
287
|
+
output_dir_name = "context"
|
|
288
|
+
config_file = target_dir / "context" / ".context-gen.json"
|
|
289
|
+
if not config_file.is_file():
|
|
290
|
+
config_file = target_dir / ".context-gen.json"
|
|
291
|
+
|
|
292
|
+
if config_file.is_file():
|
|
293
|
+
try:
|
|
294
|
+
with open(config_file, "r", encoding="utf-8") as f:
|
|
295
|
+
cfg = json.load(f)
|
|
296
|
+
output_dir_name = cfg.get("outputDir", "context")
|
|
297
|
+
except Exception:
|
|
298
|
+
pass
|
|
299
|
+
|
|
300
|
+
dest_dir = target_dir / output_dir_name
|
|
301
|
+
dest_dir.mkdir(parents=True, exist_ok=True)
|
|
302
|
+
generated_files: List[Path] = []
|
|
303
|
+
|
|
304
|
+
if output_override:
|
|
305
|
+
out_file = output_override.resolve()
|
|
306
|
+
out_file.parent.mkdir(parents=True, exist_ok=True)
|
|
307
|
+
if format_choice == OutputFormat.JSON:
|
|
308
|
+
json_data = generate_agent_json(metadata, graph, tree, str(target_dir))
|
|
309
|
+
out_file.write_text(json.dumps(json_data, indent=2), encoding="utf-8")
|
|
310
|
+
elif format_choice == OutputFormat.YAML:
|
|
311
|
+
yaml_text = generate_agent_yaml(metadata, graph, tree, str(target_dir))
|
|
312
|
+
out_file.write_text(yaml_text, encoding="utf-8")
|
|
313
|
+
else:
|
|
314
|
+
md_text = generate_agent_md(metadata, graph, tree)
|
|
315
|
+
out_file.write_text(md_text, encoding="utf-8")
|
|
316
|
+
generated_files.append(out_file)
|
|
317
|
+
else:
|
|
318
|
+
formats_to_build = ["md", "json", "yaml"] if format_choice == OutputFormat.ALL else [format_choice.value]
|
|
319
|
+
|
|
320
|
+
if "md" in formats_to_build:
|
|
321
|
+
md_file = dest_dir / "agent.md"
|
|
322
|
+
md_text = generate_agent_md(metadata, graph, tree)
|
|
323
|
+
md_file.write_text(md_text, encoding="utf-8")
|
|
324
|
+
generated_files.append(md_file)
|
|
325
|
+
|
|
326
|
+
if "json" in formats_to_build:
|
|
327
|
+
json_file = dest_dir / "agent.json"
|
|
328
|
+
json_data = generate_agent_json(metadata, graph, tree, str(target_dir))
|
|
329
|
+
json_file.write_text(json.dumps(json_data, indent=2), encoding="utf-8")
|
|
330
|
+
generated_files.append(json_file)
|
|
331
|
+
|
|
332
|
+
if "yaml" in formats_to_build:
|
|
333
|
+
yaml_file = dest_dir / "agent.yaml"
|
|
334
|
+
yaml_text = generate_agent_yaml(metadata, graph, tree, str(target_dir))
|
|
335
|
+
yaml_file.write_text(yaml_text, encoding="utf-8")
|
|
336
|
+
generated_files.append(yaml_file)
|
|
337
|
+
|
|
338
|
+
time.sleep(0.08)
|
|
339
|
+
progress.update(t4, completed=100)
|
|
340
|
+
|
|
341
|
+
console.print("")
|
|
342
|
+
return {
|
|
343
|
+
"files": files,
|
|
344
|
+
"graph": graph,
|
|
345
|
+
"metadata": metadata,
|
|
346
|
+
"generated_files": generated_files,
|
|
347
|
+
"output_dir": dest_dir
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
@app.command()
|
|
352
|
+
def main(
|
|
353
|
+
path: Path = typer.Argument(
|
|
354
|
+
default=Path("."),
|
|
355
|
+
help="Target project directory to analyze.",
|
|
356
|
+
file_okay=False,
|
|
357
|
+
dir_okay=True,
|
|
358
|
+
readable=True,
|
|
359
|
+
resolve_path=True,
|
|
360
|
+
),
|
|
361
|
+
project: Optional[Path] = typer.Option(
|
|
362
|
+
None,
|
|
363
|
+
"--project",
|
|
364
|
+
"-p",
|
|
365
|
+
help="Target project directory to analyze.",
|
|
366
|
+
file_okay=False,
|
|
367
|
+
dir_okay=True,
|
|
368
|
+
readable=True,
|
|
369
|
+
resolve_path=True,
|
|
370
|
+
),
|
|
371
|
+
default_mode: bool = typer.Option(
|
|
372
|
+
False,
|
|
373
|
+
"--default",
|
|
374
|
+
"-d",
|
|
375
|
+
help="⚡ Zero-config default mode: generate all formats in context/ and run live auto-sync watcher.",
|
|
376
|
+
),
|
|
377
|
+
format: OutputFormat = typer.Option(
|
|
378
|
+
OutputFormat.ALL,
|
|
379
|
+
"--format",
|
|
380
|
+
"-f",
|
|
381
|
+
help="Output format: 'all', 'md', 'json', or 'yaml'.",
|
|
382
|
+
case_sensitive=False,
|
|
383
|
+
),
|
|
384
|
+
mcp: bool = typer.Option(
|
|
385
|
+
False,
|
|
386
|
+
"--mcp",
|
|
387
|
+
"-m",
|
|
388
|
+
help="Start MCP server mode.",
|
|
389
|
+
),
|
|
390
|
+
interactive: bool = typer.Option(
|
|
391
|
+
False,
|
|
392
|
+
"--interactive",
|
|
393
|
+
"-i",
|
|
394
|
+
help="Run in interactive mode.",
|
|
395
|
+
),
|
|
396
|
+
output: Optional[Path] = typer.Option(
|
|
397
|
+
None,
|
|
398
|
+
"--output",
|
|
399
|
+
"-o",
|
|
400
|
+
help="Custom output file path (e.g. context/agent.md or custom.json).",
|
|
401
|
+
),
|
|
402
|
+
watch: bool = typer.Option(
|
|
403
|
+
False,
|
|
404
|
+
"--watch",
|
|
405
|
+
"-w",
|
|
406
|
+
help="Watch directory and auto-regenerate context on file changes.",
|
|
407
|
+
),
|
|
408
|
+
max_depth: int = typer.Option(
|
|
409
|
+
3,
|
|
410
|
+
"--max-depth",
|
|
411
|
+
help="Maximum directory depth to scan.",
|
|
412
|
+
min=1,
|
|
413
|
+
max=10,
|
|
414
|
+
),
|
|
415
|
+
) -> None:
|
|
416
|
+
"""
|
|
417
|
+
Scan a project, build an AST-powered dependency graph, and generate LLM context.
|
|
418
|
+
"""
|
|
419
|
+
target_dir = (project or path).resolve()
|
|
420
|
+
print_python_banner()
|
|
212
421
|
|
|
213
422
|
# If -d / --default is supplied, generate all formats and keep watch running
|
|
214
423
|
if default_mode:
|
|
@@ -220,7 +429,7 @@ def main(
|
|
|
220
429
|
border_style="cyan"
|
|
221
430
|
)
|
|
222
431
|
)
|
|
223
|
-
res =
|
|
432
|
+
res = execute_generation_with_progress(target_dir, OutputFormat.ALL, max_depth=max_depth)
|
|
224
433
|
table = Table(show_header=False, box=None)
|
|
225
434
|
table.add_row("[bold]Scanned Files:[/bold]", f"[cyan]{len(res['files'])}[/cyan]")
|
|
226
435
|
table.add_row("[bold]AST Graph Edges:[/bold]", f"[cyan]{len(res['graph']['edges'])}[/cyan]")
|
|
@@ -230,17 +439,7 @@ def main(
|
|
|
230
439
|
run_watch_loop(target_dir, OutputFormat.ALL, max_depth=max_depth)
|
|
231
440
|
return
|
|
232
441
|
|
|
233
|
-
|
|
234
|
-
Panel.fit(
|
|
235
|
-
f"[bold cyan]⚡ context-gen-cli (Python Edition)[/bold cyan]\n"
|
|
236
|
-
f"[dim]Analyzing target:[/dim] [green]{target_dir}[/green]\n"
|
|
237
|
-
f"[dim]Format:[/dim] [yellow]{format.value.upper()}[/yellow]",
|
|
238
|
-
border_style="cyan"
|
|
239
|
-
)
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
with console.status("[bold green]Scanning directory and parsing AST graph...[/bold green]"):
|
|
243
|
-
res = execute_generation(target_dir, format, output_override=output, max_depth=max_depth)
|
|
442
|
+
res = execute_generation_with_progress(target_dir, format, output_override=output, max_depth=max_depth)
|
|
244
443
|
|
|
245
444
|
# Display completion summary
|
|
246
445
|
table = Table(show_header=False, box=None)
|
|
@@ -258,9 +457,51 @@ def main(
|
|
|
258
457
|
)
|
|
259
458
|
)
|
|
260
459
|
|
|
460
|
+
tips = (
|
|
461
|
+
"[bold cyan]ctx -w[/bold cyan] (or [cyan]ctx --watch[/cyan]) → Keep context fresh (auto-syncs on save)\n"
|
|
462
|
+
"[bold cyan]ctx -d[/bold cyan] (or [cyan]ctx --default[/cyan]) → ⚡ All-in-one (generate + live watcher)\n"
|
|
463
|
+
"[bold cyan]ctx update -f json[/bold cyan] → Quick format change (md, json, yaml, all)\n"
|
|
464
|
+
"[bold cyan]ctx -o <dir>[/bold cyan] → Custom output folder\n"
|
|
465
|
+
f"[dim]Config saved in:[/dim] [yellow]{res['output_dir'] / '.context-gen.json'}[/yellow]"
|
|
466
|
+
)
|
|
467
|
+
console.print(Panel(tips, title="[bold]💡 Pro-Tips & Next Steps[/bold]", border_style="blue"))
|
|
468
|
+
|
|
261
469
|
if watch:
|
|
262
470
|
run_watch_loop(target_dir, format, max_depth=max_depth)
|
|
263
471
|
|
|
264
472
|
|
|
473
|
+
@app.command()
|
|
474
|
+
def update(
|
|
475
|
+
path: Path = typer.Argument(
|
|
476
|
+
default=Path("."),
|
|
477
|
+
help="Target project directory to analyze.",
|
|
478
|
+
file_okay=False,
|
|
479
|
+
dir_okay=True,
|
|
480
|
+
readable=True,
|
|
481
|
+
resolve_path=True,
|
|
482
|
+
),
|
|
483
|
+
format: OutputFormat = typer.Option(
|
|
484
|
+
OutputFormat.ALL,
|
|
485
|
+
"--format",
|
|
486
|
+
"-f",
|
|
487
|
+
help="Output format: 'all', 'md', 'json', or 'yaml'.",
|
|
488
|
+
case_sensitive=False,
|
|
489
|
+
),
|
|
490
|
+
output: Optional[Path] = typer.Option(
|
|
491
|
+
None,
|
|
492
|
+
"--output",
|
|
493
|
+
"-o",
|
|
494
|
+
help="Custom output file path.",
|
|
495
|
+
),
|
|
496
|
+
) -> None:
|
|
497
|
+
"""
|
|
498
|
+
Regenerate and update project context files.
|
|
499
|
+
"""
|
|
500
|
+
target_dir = path.resolve()
|
|
501
|
+
with console.status("[bold green]Updating project context files...[/bold green]"):
|
|
502
|
+
res = execute_generation(target_dir, format, output_override=output)
|
|
503
|
+
console.print(f"[bold green]✓ Context updated in {res['output_dir']}![/bold green]")
|
|
504
|
+
|
|
505
|
+
|
|
265
506
|
if __name__ == "__main__":
|
|
266
507
|
app()
|