claude-dev-cli 0.8.1__tar.gz → 0.8.3__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.
Potentially problematic release.
This version of claude-dev-cli might be problematic. Click here for more details.
- {claude_dev_cli-0.8.1/src/claude_dev_cli.egg-info → claude_dev_cli-0.8.3}/PKG-INFO +70 -9
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/README.md +69 -8
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/pyproject.toml +1 -1
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/__init__.py +1 -1
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/cli.py +232 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/config.py +15 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/context.py +179 -5
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/history.py +90 -4
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3/src/claude_dev_cli.egg-info}/PKG-INFO +70 -9
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli.egg-info/SOURCES.txt +1 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_context.py +136 -0
- claude_dev_cli-0.8.3/tests/test_history.py +488 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/LICENSE +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/MANIFEST.in +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/setup.cfg +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/commands.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/core.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/plugins/__init__.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/plugins/base.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/plugins/diff_editor/__init__.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/plugins/diff_editor/plugin.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/plugins/diff_editor/viewer.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/secure_storage.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/template_manager.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/templates.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/toon_utils.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/usage.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/warp_integration.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli/workflows.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli.egg-info/dependency_links.txt +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli.egg-info/entry_points.txt +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli.egg-info/requires.txt +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/src/claude_dev_cli.egg-info/top_level.txt +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_cli.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_commands.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_config.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_core.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_diff_editor.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_secure_storage.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_template_manager.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_toon_utils.py +0 -0
- {claude_dev_cli-0.8.1 → claude_dev_cli-0.8.3}/tests/test_usage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-dev-cli
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
4
4
|
Summary: A powerful CLI tool for developers using Claude AI with multi-API routing, test generation, code review, and usage tracking
|
|
5
5
|
Author-email: Julio <thinmanj@users.noreply.github.com>
|
|
6
6
|
License: MIT
|
|
@@ -44,6 +44,13 @@ Dynamic: license-file
|
|
|
44
44
|
|
|
45
45
|
# Claude Dev CLI
|
|
46
46
|
|
|
47
|
+
[](https://badge.fury.io/py/claude-dev-cli)
|
|
48
|
+
[](https://www.python.org/downloads/)
|
|
49
|
+
[](https://github.com/thinmanj/claude-dev-cli)
|
|
50
|
+
[](https://opensource.org/licenses/MIT)
|
|
51
|
+
[](https://github.com/thinmanj/homebrew-tap)
|
|
52
|
+
[](https://github.com/psf/black)
|
|
53
|
+
|
|
47
54
|
A powerful command-line tool for developers using Claude AI with multi-API routing, test generation, code review, and comprehensive usage tracking.
|
|
48
55
|
|
|
49
56
|
## Features
|
|
@@ -85,7 +92,8 @@ A powerful command-line tool for developers using Claude AI with multi-API routi
|
|
|
85
92
|
- `git commit`, `generate tests`, `generate docs` (v0.8.1)
|
|
86
93
|
- **Git Integration**: Automatically include branch, commits, modified files
|
|
87
94
|
- **Dependency Analysis**: Parse imports and include related files
|
|
88
|
-
- **Error Parsing
|
|
95
|
+
- **Multi-Language Error Parsing** (v0.8.2): Python, JavaScript/TypeScript, Go, Rust, Java
|
|
96
|
+
- **Context Summary** (v0.8.2): Preview context before API calls with `cdc context summary`
|
|
89
97
|
- **Smart Truncation**: Prevent token limits with configurable file size limits
|
|
90
98
|
- **Project Memory**: Remember preferences per project
|
|
91
99
|
- **Global Config**: Set context defaults in `~/.claude-dev-cli/config.json`
|
|
@@ -98,19 +106,39 @@ A powerful command-line tool for developers using Claude AI with multi-API routi
|
|
|
98
106
|
|
|
99
107
|
## Installation
|
|
100
108
|
|
|
101
|
-
###
|
|
109
|
+
### Via Homebrew (macOS/Linux)
|
|
102
110
|
|
|
103
111
|
```bash
|
|
104
|
-
|
|
112
|
+
# Add the tap
|
|
113
|
+
brew tap thinmanj/tap
|
|
114
|
+
|
|
115
|
+
# Install
|
|
116
|
+
brew install claude-dev-cli
|
|
117
|
+
|
|
118
|
+
# Or in one command
|
|
119
|
+
brew install thinmanj/tap/claude-dev-cli
|
|
105
120
|
```
|
|
106
121
|
|
|
107
|
-
###
|
|
122
|
+
### Via pip
|
|
108
123
|
|
|
109
124
|
```bash
|
|
110
|
-
#
|
|
125
|
+
# Basic installation
|
|
126
|
+
pip install claude-dev-cli
|
|
127
|
+
|
|
128
|
+
# With TOON support (30-60% token reduction)
|
|
111
129
|
pip install claude-dev-cli[toon]
|
|
112
130
|
```
|
|
113
131
|
|
|
132
|
+
### Via pipx (Recommended for CLI tools)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Isolated installation
|
|
136
|
+
pipx install claude-dev-cli
|
|
137
|
+
|
|
138
|
+
# With TOON support
|
|
139
|
+
pipx install claude-dev-cli[toon]
|
|
140
|
+
```
|
|
141
|
+
|
|
114
142
|
## Quick Start
|
|
115
143
|
|
|
116
144
|
### 1. Set Up API Keys
|
|
@@ -199,7 +227,7 @@ git add .
|
|
|
199
227
|
cdc git commit --auto-context
|
|
200
228
|
```
|
|
201
229
|
|
|
202
|
-
### 4. Context-Aware Operations (
|
|
230
|
+
### 4. Context-Aware Operations (v0.8.0+)
|
|
203
231
|
|
|
204
232
|
```bash
|
|
205
233
|
# Auto-context includes: git info, dependencies, related files
|
|
@@ -208,9 +236,16 @@ cdc git commit --auto-context
|
|
|
208
236
|
cdc review mymodule.py --auto-context
|
|
209
237
|
# ✓ Context gathered (git, dependencies, tests)
|
|
210
238
|
|
|
211
|
-
# Debug with parsed error details
|
|
239
|
+
# Debug with parsed error details (multi-language support)
|
|
212
240
|
python broken.py 2>&1 | cdc debug -f broken.py --auto-context
|
|
241
|
+
node app.js 2>&1 | cdc debug --auto-context # JavaScript/TypeScript
|
|
242
|
+
go run main.go 2>&1 | cdc debug --auto-context # Go
|
|
213
243
|
# ✓ Context gathered (error details, git context)
|
|
244
|
+
# Supports: Python, JavaScript, TypeScript, Go, Rust, Java
|
|
245
|
+
|
|
246
|
+
# Preview context before making API calls - NEW in v0.8.2
|
|
247
|
+
cdc context summary mymodule.py
|
|
248
|
+
# Shows: files, sizes, lines, estimated tokens, truncation warnings
|
|
214
249
|
|
|
215
250
|
# Ask questions with file context
|
|
216
251
|
cdc ask -f mycode.py --auto-context "how can I improve this?"
|
|
@@ -258,7 +293,33 @@ cdc template list --user
|
|
|
258
293
|
- **explain-code**: Detailed code explanation
|
|
259
294
|
- **api-design**: API design assistance
|
|
260
295
|
|
|
261
|
-
### 6.
|
|
296
|
+
### 6. Conversation History & Summarization (NEW in v0.8.3)
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# List recent conversations
|
|
300
|
+
cdc history list
|
|
301
|
+
|
|
302
|
+
# Search conversations
|
|
303
|
+
cdc history list --search "python decorators"
|
|
304
|
+
|
|
305
|
+
# Export conversation
|
|
306
|
+
cdc history export 20240109_143022 -o chat.md
|
|
307
|
+
|
|
308
|
+
# Summarize to reduce token usage
|
|
309
|
+
cdc history summarize --latest
|
|
310
|
+
cdc history summarize 20240109_143022 --keep-recent 6
|
|
311
|
+
|
|
312
|
+
# Delete old conversations
|
|
313
|
+
cdc history delete 20240109_143022
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Auto-Summarization** in interactive mode:
|
|
317
|
+
- Automatically triggers when conversation exceeds 8,000 tokens
|
|
318
|
+
- Keeps recent messages (default: 4 pairs), summarizes older ones
|
|
319
|
+
- Reduces API costs by ~30-50% in long conversations
|
|
320
|
+
- Shows token savings after summarization
|
|
321
|
+
|
|
322
|
+
### 7. Usage Tracking
|
|
262
323
|
|
|
263
324
|
```bash
|
|
264
325
|
# View all usage
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Claude Dev CLI
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/py/claude-dev-cli)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://github.com/thinmanj/claude-dev-cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://github.com/thinmanj/homebrew-tap)
|
|
8
|
+
[](https://github.com/psf/black)
|
|
9
|
+
|
|
3
10
|
A powerful command-line tool for developers using Claude AI with multi-API routing, test generation, code review, and comprehensive usage tracking.
|
|
4
11
|
|
|
5
12
|
## Features
|
|
@@ -41,7 +48,8 @@ A powerful command-line tool for developers using Claude AI with multi-API routi
|
|
|
41
48
|
- `git commit`, `generate tests`, `generate docs` (v0.8.1)
|
|
42
49
|
- **Git Integration**: Automatically include branch, commits, modified files
|
|
43
50
|
- **Dependency Analysis**: Parse imports and include related files
|
|
44
|
-
- **Error Parsing
|
|
51
|
+
- **Multi-Language Error Parsing** (v0.8.2): Python, JavaScript/TypeScript, Go, Rust, Java
|
|
52
|
+
- **Context Summary** (v0.8.2): Preview context before API calls with `cdc context summary`
|
|
45
53
|
- **Smart Truncation**: Prevent token limits with configurable file size limits
|
|
46
54
|
- **Project Memory**: Remember preferences per project
|
|
47
55
|
- **Global Config**: Set context defaults in `~/.claude-dev-cli/config.json`
|
|
@@ -54,19 +62,39 @@ A powerful command-line tool for developers using Claude AI with multi-API routi
|
|
|
54
62
|
|
|
55
63
|
## Installation
|
|
56
64
|
|
|
57
|
-
###
|
|
65
|
+
### Via Homebrew (macOS/Linux)
|
|
58
66
|
|
|
59
67
|
```bash
|
|
60
|
-
|
|
68
|
+
# Add the tap
|
|
69
|
+
brew tap thinmanj/tap
|
|
70
|
+
|
|
71
|
+
# Install
|
|
72
|
+
brew install claude-dev-cli
|
|
73
|
+
|
|
74
|
+
# Or in one command
|
|
75
|
+
brew install thinmanj/tap/claude-dev-cli
|
|
61
76
|
```
|
|
62
77
|
|
|
63
|
-
###
|
|
78
|
+
### Via pip
|
|
64
79
|
|
|
65
80
|
```bash
|
|
66
|
-
#
|
|
81
|
+
# Basic installation
|
|
82
|
+
pip install claude-dev-cli
|
|
83
|
+
|
|
84
|
+
# With TOON support (30-60% token reduction)
|
|
67
85
|
pip install claude-dev-cli[toon]
|
|
68
86
|
```
|
|
69
87
|
|
|
88
|
+
### Via pipx (Recommended for CLI tools)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Isolated installation
|
|
92
|
+
pipx install claude-dev-cli
|
|
93
|
+
|
|
94
|
+
# With TOON support
|
|
95
|
+
pipx install claude-dev-cli[toon]
|
|
96
|
+
```
|
|
97
|
+
|
|
70
98
|
## Quick Start
|
|
71
99
|
|
|
72
100
|
### 1. Set Up API Keys
|
|
@@ -155,7 +183,7 @@ git add .
|
|
|
155
183
|
cdc git commit --auto-context
|
|
156
184
|
```
|
|
157
185
|
|
|
158
|
-
### 4. Context-Aware Operations (
|
|
186
|
+
### 4. Context-Aware Operations (v0.8.0+)
|
|
159
187
|
|
|
160
188
|
```bash
|
|
161
189
|
# Auto-context includes: git info, dependencies, related files
|
|
@@ -164,9 +192,16 @@ cdc git commit --auto-context
|
|
|
164
192
|
cdc review mymodule.py --auto-context
|
|
165
193
|
# ✓ Context gathered (git, dependencies, tests)
|
|
166
194
|
|
|
167
|
-
# Debug with parsed error details
|
|
195
|
+
# Debug with parsed error details (multi-language support)
|
|
168
196
|
python broken.py 2>&1 | cdc debug -f broken.py --auto-context
|
|
197
|
+
node app.js 2>&1 | cdc debug --auto-context # JavaScript/TypeScript
|
|
198
|
+
go run main.go 2>&1 | cdc debug --auto-context # Go
|
|
169
199
|
# ✓ Context gathered (error details, git context)
|
|
200
|
+
# Supports: Python, JavaScript, TypeScript, Go, Rust, Java
|
|
201
|
+
|
|
202
|
+
# Preview context before making API calls - NEW in v0.8.2
|
|
203
|
+
cdc context summary mymodule.py
|
|
204
|
+
# Shows: files, sizes, lines, estimated tokens, truncation warnings
|
|
170
205
|
|
|
171
206
|
# Ask questions with file context
|
|
172
207
|
cdc ask -f mycode.py --auto-context "how can I improve this?"
|
|
@@ -214,7 +249,33 @@ cdc template list --user
|
|
|
214
249
|
- **explain-code**: Detailed code explanation
|
|
215
250
|
- **api-design**: API design assistance
|
|
216
251
|
|
|
217
|
-
### 6.
|
|
252
|
+
### 6. Conversation History & Summarization (NEW in v0.8.3)
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# List recent conversations
|
|
256
|
+
cdc history list
|
|
257
|
+
|
|
258
|
+
# Search conversations
|
|
259
|
+
cdc history list --search "python decorators"
|
|
260
|
+
|
|
261
|
+
# Export conversation
|
|
262
|
+
cdc history export 20240109_143022 -o chat.md
|
|
263
|
+
|
|
264
|
+
# Summarize to reduce token usage
|
|
265
|
+
cdc history summarize --latest
|
|
266
|
+
cdc history summarize 20240109_143022 --keep-recent 6
|
|
267
|
+
|
|
268
|
+
# Delete old conversations
|
|
269
|
+
cdc history delete 20240109_143022
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Auto-Summarization** in interactive mode:
|
|
273
|
+
- Automatically triggers when conversation exceeds 8,000 tokens
|
|
274
|
+
- Keeps recent messages (default: 4 pairs), summarizes older ones
|
|
275
|
+
- Reduces API costs by ~30-50% in long conversations
|
|
276
|
+
- Shows token savings after summarization
|
|
277
|
+
|
|
278
|
+
### 7. Usage Tracking
|
|
218
279
|
|
|
219
280
|
```bash
|
|
220
281
|
# View all usage
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-dev-cli"
|
|
7
|
-
version = "0.8.
|
|
7
|
+
version = "0.8.3"
|
|
8
8
|
description = "A powerful CLI tool for developers using Claude AI with multi-API routing, test generation, code review, and usage tracking"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -145,6 +145,7 @@ def interactive(
|
|
|
145
145
|
config = Config()
|
|
146
146
|
history_dir = config.config_dir / "history"
|
|
147
147
|
conv_history = ConversationHistory(history_dir)
|
|
148
|
+
summ_config = config.get_summarization_config()
|
|
148
149
|
|
|
149
150
|
# Load or create conversation
|
|
150
151
|
if continue_conversation:
|
|
@@ -203,6 +204,42 @@ def interactive(
|
|
|
203
204
|
full_response = ''.join(response_buffer)
|
|
204
205
|
conversation.add_message("assistant", full_response)
|
|
205
206
|
|
|
207
|
+
# Check if auto-summarization is needed
|
|
208
|
+
if summ_config.auto_summarize and conversation.should_summarize(threshold_tokens=summ_config.threshold_tokens):
|
|
209
|
+
console.print("\n[yellow]⚠ Conversation getting long, summarizing older messages...[/yellow]")
|
|
210
|
+
old_messages, recent_messages = conversation.compress_messages(keep_recent=summ_config.keep_recent_messages)
|
|
211
|
+
|
|
212
|
+
if old_messages:
|
|
213
|
+
# Build summary prompt
|
|
214
|
+
conversation_text = []
|
|
215
|
+
if conversation.summary:
|
|
216
|
+
conversation_text.append(f"Previous summary:\n{conversation.summary}\n\n")
|
|
217
|
+
|
|
218
|
+
conversation_text.append("Conversation to summarize:\n")
|
|
219
|
+
for msg in old_messages:
|
|
220
|
+
role_name = "User" if msg.role == "user" else "Assistant"
|
|
221
|
+
conversation_text.append(f"{role_name}: {msg.content}\n")
|
|
222
|
+
|
|
223
|
+
summary_prompt = (
|
|
224
|
+
"Please provide a concise summary of this conversation that captures:"
|
|
225
|
+
"\n1. Main topics discussed"
|
|
226
|
+
"\n2. Key questions asked and answers provided"
|
|
227
|
+
"\n3. Important decisions or conclusions"
|
|
228
|
+
"\n4. Any action items or follow-ups mentioned"
|
|
229
|
+
"\n\nKeep the summary under 300 words but retain all important context."
|
|
230
|
+
"\n\n" + "".join(conversation_text)
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Get summary (use same client)
|
|
234
|
+
new_summary = client.call(summary_prompt)
|
|
235
|
+
|
|
236
|
+
# Update conversation
|
|
237
|
+
conversation.summary = new_summary
|
|
238
|
+
conversation.messages = recent_messages
|
|
239
|
+
|
|
240
|
+
tokens_saved = len("".join(conversation_text)) // 4
|
|
241
|
+
console.print(f"[dim]✓ Summarized older messages (~{tokens_saved:,} tokens saved)[/dim]")
|
|
242
|
+
|
|
206
243
|
# Auto-save periodically
|
|
207
244
|
if save and len(conversation.messages) % 10 == 0:
|
|
208
245
|
conv_history.save_conversation(conversation)
|
|
@@ -341,6 +378,100 @@ def history_export(ctx: click.Context, conversation_id: str, format: str, output
|
|
|
341
378
|
click.echo(content)
|
|
342
379
|
|
|
343
380
|
|
|
381
|
+
@history.command('summarize')
|
|
382
|
+
@click.argument('conversation_id', required=False)
|
|
383
|
+
@click.option('--keep-recent', type=int, default=4, help='Number of recent message pairs to keep')
|
|
384
|
+
@click.option('--latest', is_flag=True, help='Summarize the latest conversation')
|
|
385
|
+
@click.pass_context
|
|
386
|
+
def history_summarize(
|
|
387
|
+
ctx: click.Context,
|
|
388
|
+
conversation_id: Optional[str],
|
|
389
|
+
keep_recent: int,
|
|
390
|
+
latest: bool
|
|
391
|
+
) -> None:
|
|
392
|
+
"""Summarize a conversation to reduce token usage.
|
|
393
|
+
|
|
394
|
+
Older messages are compressed into an AI-generated summary while keeping
|
|
395
|
+
recent messages intact. This reduces context window usage and costs.
|
|
396
|
+
|
|
397
|
+
Examples:
|
|
398
|
+
cdc history summarize 20240109_143022
|
|
399
|
+
cdc history summarize --latest
|
|
400
|
+
cdc history summarize --latest --keep-recent 6
|
|
401
|
+
"""
|
|
402
|
+
console = ctx.obj['console']
|
|
403
|
+
config = Config()
|
|
404
|
+
conv_history = ConversationHistory(config.config_dir / "history")
|
|
405
|
+
|
|
406
|
+
# Determine which conversation to summarize
|
|
407
|
+
if latest:
|
|
408
|
+
conv = conv_history.get_latest_conversation()
|
|
409
|
+
if not conv:
|
|
410
|
+
console.print("[red]No conversations found[/red]")
|
|
411
|
+
sys.exit(1)
|
|
412
|
+
conversation_id = conv.conversation_id
|
|
413
|
+
elif not conversation_id:
|
|
414
|
+
console.print("[red]Error: Provide conversation_id or use --latest[/red]")
|
|
415
|
+
console.print("\nUsage: cdc history summarize CONVERSATION_ID")
|
|
416
|
+
console.print(" or: cdc history summarize --latest")
|
|
417
|
+
sys.exit(1)
|
|
418
|
+
|
|
419
|
+
# Load conversation to show stats
|
|
420
|
+
conv = conv_history.load_conversation(conversation_id)
|
|
421
|
+
if not conv:
|
|
422
|
+
console.print(f"[red]Conversation {conversation_id} not found[/red]")
|
|
423
|
+
sys.exit(1)
|
|
424
|
+
|
|
425
|
+
# Show before stats
|
|
426
|
+
tokens_before = conv.estimate_tokens()
|
|
427
|
+
messages_before = len(conv.messages)
|
|
428
|
+
console.print(f"\n[cyan]Conversation:[/cyan] {conversation_id}")
|
|
429
|
+
console.print(f"[dim]Messages: {messages_before} | Estimated tokens: {tokens_before:,}[/dim]\n")
|
|
430
|
+
|
|
431
|
+
if messages_before <= keep_recent:
|
|
432
|
+
console.print(f"[yellow]Too few messages to summarize ({messages_before} <= {keep_recent})[/yellow]")
|
|
433
|
+
return
|
|
434
|
+
|
|
435
|
+
# Summarize
|
|
436
|
+
with console.status("[bold blue]Generating summary..."):
|
|
437
|
+
summary = conv_history.summarize_conversation(conversation_id, keep_recent)
|
|
438
|
+
|
|
439
|
+
if not summary:
|
|
440
|
+
console.print("[red]Failed to generate summary[/red]")
|
|
441
|
+
sys.exit(1)
|
|
442
|
+
|
|
443
|
+
# Reload and show after stats
|
|
444
|
+
conv = conv_history.load_conversation(conversation_id)
|
|
445
|
+
if conv:
|
|
446
|
+
tokens_after = conv.estimate_tokens()
|
|
447
|
+
messages_after = len(conv.messages)
|
|
448
|
+
|
|
449
|
+
token_savings = tokens_before - tokens_after
|
|
450
|
+
savings_percent = (token_savings / tokens_before * 100) if tokens_before > 0 else 0
|
|
451
|
+
|
|
452
|
+
console.print("[green]✓ Conversation summarized[/green]\n")
|
|
453
|
+
console.print(f"[dim]Messages:[/dim] {messages_before} → {messages_after}")
|
|
454
|
+
console.print(f"[dim]Tokens:[/dim] {tokens_before:,} → {tokens_after:,} ({token_savings:,} saved, {savings_percent:.1f}%)\n")
|
|
455
|
+
console.print("[bold]Summary:[/bold]")
|
|
456
|
+
console.print(Panel(summary, border_style="blue"))
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
@history.command('delete')
|
|
460
|
+
@click.argument('conversation_id')
|
|
461
|
+
@click.pass_context
|
|
462
|
+
def history_delete(ctx: click.Context, conversation_id: str) -> None:
|
|
463
|
+
"""Delete a conversation."""
|
|
464
|
+
console = ctx.obj['console']
|
|
465
|
+
config = Config()
|
|
466
|
+
conv_history = ConversationHistory(config.config_dir / "history")
|
|
467
|
+
|
|
468
|
+
if conv_history.delete_conversation(conversation_id):
|
|
469
|
+
console.print(f"[green]✓[/green] Deleted conversation: {conversation_id}")
|
|
470
|
+
else:
|
|
471
|
+
console.print(f"[red]Conversation {conversation_id} not found[/red]")
|
|
472
|
+
sys.exit(1)
|
|
473
|
+
|
|
474
|
+
|
|
344
475
|
@main.group()
|
|
345
476
|
def config() -> None:
|
|
346
477
|
"""Manage configuration."""
|
|
@@ -884,6 +1015,107 @@ def git_commit(ctx: click.Context, api: Optional[str], auto_context: bool) -> No
|
|
|
884
1015
|
sys.exit(1)
|
|
885
1016
|
|
|
886
1017
|
|
|
1018
|
+
@main.group()
|
|
1019
|
+
def context() -> None:
|
|
1020
|
+
"""Context gathering tools and information."""
|
|
1021
|
+
pass
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
@context.command('summary')
|
|
1025
|
+
@click.argument('file_path', type=click.Path(exists=True))
|
|
1026
|
+
@click.option('--include-git/--no-git', default=True, help='Include git context')
|
|
1027
|
+
@click.option('--include-deps/--no-deps', default=True, help='Include dependencies')
|
|
1028
|
+
@click.option('--include-tests/--no-tests', default=True, help='Include test files')
|
|
1029
|
+
@click.pass_context
|
|
1030
|
+
def context_summary(
|
|
1031
|
+
ctx: click.Context,
|
|
1032
|
+
file_path: str,
|
|
1033
|
+
include_git: bool,
|
|
1034
|
+
include_deps: bool,
|
|
1035
|
+
include_tests: bool
|
|
1036
|
+
) -> None:
|
|
1037
|
+
"""Show what context would be gathered for a file."""
|
|
1038
|
+
from claude_dev_cli.context import ContextGatherer
|
|
1039
|
+
from rich.table import Table
|
|
1040
|
+
|
|
1041
|
+
console = ctx.obj['console']
|
|
1042
|
+
|
|
1043
|
+
try:
|
|
1044
|
+
file_path_obj = Path(file_path)
|
|
1045
|
+
gatherer = ContextGatherer()
|
|
1046
|
+
|
|
1047
|
+
# Gather context
|
|
1048
|
+
with console.status("[bold blue]Analyzing context..."):
|
|
1049
|
+
context = gatherer.gather_for_review(
|
|
1050
|
+
file_path_obj,
|
|
1051
|
+
include_git=include_git,
|
|
1052
|
+
include_tests=include_tests
|
|
1053
|
+
)
|
|
1054
|
+
|
|
1055
|
+
# Display summary
|
|
1056
|
+
console.print(f"\n[bold cyan]Context Summary for:[/bold cyan] {file_path}\n")
|
|
1057
|
+
|
|
1058
|
+
table = Table(show_header=True, header_style="bold magenta")
|
|
1059
|
+
table.add_column("Type", style="cyan")
|
|
1060
|
+
table.add_column("Content", style="white")
|
|
1061
|
+
table.add_column("Size", justify="right", style="yellow")
|
|
1062
|
+
table.add_column("Lines", justify="right", style="green")
|
|
1063
|
+
table.add_column("Truncated", justify="center", style="red")
|
|
1064
|
+
|
|
1065
|
+
total_chars = 0
|
|
1066
|
+
total_lines = 0
|
|
1067
|
+
|
|
1068
|
+
for item in context.items:
|
|
1069
|
+
lines = len(item.content.split('\n'))
|
|
1070
|
+
chars = len(item.content)
|
|
1071
|
+
truncated = "✓" if item.metadata.get('truncated') else ""
|
|
1072
|
+
|
|
1073
|
+
# Format content preview
|
|
1074
|
+
if item.type == 'file':
|
|
1075
|
+
content = item.metadata.get('path', 'unknown')
|
|
1076
|
+
if item.metadata.get('is_test'):
|
|
1077
|
+
content += " [TEST]"
|
|
1078
|
+
elif item.type == 'git':
|
|
1079
|
+
branch = item.metadata.get('branch', 'unknown')
|
|
1080
|
+
modified = item.metadata.get('modified_count', 0)
|
|
1081
|
+
content = f"Branch: {branch}, {modified} modified files"
|
|
1082
|
+
elif item.type == 'dependency':
|
|
1083
|
+
dep_files = item.metadata.get('dependency_files', [])
|
|
1084
|
+
content = f"{len(dep_files)} dependency files"
|
|
1085
|
+
else:
|
|
1086
|
+
content = item.type
|
|
1087
|
+
|
|
1088
|
+
table.add_row(
|
|
1089
|
+
item.type.title(),
|
|
1090
|
+
content[:60] + "..." if len(content) > 60 else content,
|
|
1091
|
+
f"{chars:,}",
|
|
1092
|
+
f"{lines:,}",
|
|
1093
|
+
truncated
|
|
1094
|
+
)
|
|
1095
|
+
|
|
1096
|
+
total_chars += chars
|
|
1097
|
+
total_lines += lines
|
|
1098
|
+
|
|
1099
|
+
console.print(table)
|
|
1100
|
+
|
|
1101
|
+
# Show totals
|
|
1102
|
+
console.print(f"\n[bold]Total:[/bold]")
|
|
1103
|
+
console.print(f" Characters: [yellow]{total_chars:,}[/yellow]")
|
|
1104
|
+
console.print(f" Lines: [green]{total_lines:,}[/green]")
|
|
1105
|
+
console.print(f" Estimated tokens: [cyan]~{total_chars // 4:,}[/cyan] (rough estimate)")
|
|
1106
|
+
|
|
1107
|
+
# Show any truncation warnings
|
|
1108
|
+
truncated_items = [item for item in context.items if item.metadata.get('truncated')]
|
|
1109
|
+
if truncated_items:
|
|
1110
|
+
console.print(f"\n[yellow]⚠ {len(truncated_items)} item(s) truncated to fit size limits[/yellow]")
|
|
1111
|
+
|
|
1112
|
+
console.print(f"\n[dim]Use --auto-context with commands to include this context[/dim]")
|
|
1113
|
+
|
|
1114
|
+
except Exception as e:
|
|
1115
|
+
console.print(f"[red]Error: {e}[/red]")
|
|
1116
|
+
sys.exit(1)
|
|
1117
|
+
|
|
1118
|
+
|
|
887
1119
|
@main.command('usage')
|
|
888
1120
|
@click.option('--days', type=int, help='Filter by days')
|
|
889
1121
|
@click.option('--api', help='Filter by API config')
|
|
@@ -21,6 +21,15 @@ class ContextConfig(BaseModel):
|
|
|
21
21
|
include_tests: bool = True # Include test files by default
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class SummarizationConfig(BaseModel):
|
|
25
|
+
"""Conversation summarization configuration."""
|
|
26
|
+
|
|
27
|
+
auto_summarize: bool = True # Enable automatic summarization
|
|
28
|
+
threshold_tokens: int = 8000 # Token threshold for auto-summarization
|
|
29
|
+
keep_recent_messages: int = 4 # Number of recent message pairs to keep
|
|
30
|
+
summary_max_words: int = 300 # Maximum words in generated summary
|
|
31
|
+
|
|
32
|
+
|
|
24
33
|
class APIConfig(BaseModel):
|
|
25
34
|
"""Configuration for a Claude API key."""
|
|
26
35
|
|
|
@@ -87,6 +96,7 @@ class Config:
|
|
|
87
96
|
"default_model": "claude-3-5-sonnet-20241022",
|
|
88
97
|
"max_tokens": 4096,
|
|
89
98
|
"context": ContextConfig().model_dump(),
|
|
99
|
+
"summarization": SummarizationConfig().model_dump(),
|
|
90
100
|
}
|
|
91
101
|
self._save_config(default_config)
|
|
92
102
|
return default_config
|
|
@@ -263,3 +273,8 @@ class Config:
|
|
|
263
273
|
"""Get context gathering configuration."""
|
|
264
274
|
context_data = self._data.get("context", {})
|
|
265
275
|
return ContextConfig(**context_data) if context_data else ContextConfig()
|
|
276
|
+
|
|
277
|
+
def get_summarization_config(self) -> SummarizationConfig:
|
|
278
|
+
"""Get conversation summarization configuration."""
|
|
279
|
+
summ_data = self._data.get("summarization", {})
|
|
280
|
+
return SummarizationConfig(**summ_data) if summ_data else SummarizationConfig()
|