claude-dev-cli 0.8.2__py3-none-any.whl → 0.8.3__py3-none-any.whl
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/__init__.py +1 -1
- claude_dev_cli/cli.py +131 -0
- claude_dev_cli/config.py +15 -0
- claude_dev_cli/history.py +90 -4
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/METADATA +59 -6
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/RECORD +10 -10
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/WHEEL +0 -0
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/entry_points.txt +0 -0
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/licenses/LICENSE +0 -0
- {claude_dev_cli-0.8.2.dist-info → claude_dev_cli-0.8.3.dist-info}/top_level.txt +0 -0
claude_dev_cli/__init__.py
CHANGED
claude_dev_cli/cli.py
CHANGED
|
@@ -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."""
|
claude_dev_cli/config.py
CHANGED
|
@@ -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()
|
claude_dev_cli/history.py
CHANGED
|
@@ -39,11 +39,13 @@ class Conversation:
|
|
|
39
39
|
self,
|
|
40
40
|
conversation_id: Optional[str] = None,
|
|
41
41
|
created_at: Optional[datetime] = None,
|
|
42
|
-
updated_at: Optional[datetime] = None
|
|
42
|
+
updated_at: Optional[datetime] = None,
|
|
43
|
+
summary: Optional[str] = None
|
|
43
44
|
):
|
|
44
|
-
self.conversation_id = conversation_id or datetime.utcnow().strftime("%Y%m%d_%H%M%
|
|
45
|
+
self.conversation_id = conversation_id or datetime.utcnow().strftime("%Y%m%d_%H%M%S_%f")
|
|
45
46
|
self.created_at = created_at or datetime.utcnow()
|
|
46
47
|
self.updated_at = updated_at or datetime.utcnow()
|
|
48
|
+
self.summary = summary # AI-generated summary of older messages
|
|
47
49
|
self.messages: List[Message] = []
|
|
48
50
|
|
|
49
51
|
def add_message(self, role: str, content: str) -> None:
|
|
@@ -62,14 +64,37 @@ class Conversation:
|
|
|
62
64
|
return summary
|
|
63
65
|
return "(empty conversation)"
|
|
64
66
|
|
|
67
|
+
def estimate_tokens(self) -> int:
|
|
68
|
+
"""Estimate token count for the conversation."""
|
|
69
|
+
# Rough estimation: ~4 characters per token
|
|
70
|
+
total_chars = len(self.summary or "")
|
|
71
|
+
for msg in self.messages:
|
|
72
|
+
total_chars += len(msg.content)
|
|
73
|
+
return total_chars // 4
|
|
74
|
+
|
|
75
|
+
def should_summarize(self, threshold_tokens: int = 8000) -> bool:
|
|
76
|
+
"""Check if conversation should be summarized."""
|
|
77
|
+
return self.estimate_tokens() > threshold_tokens and len(self.messages) > 4
|
|
78
|
+
|
|
79
|
+
def compress_messages(self, keep_recent: int = 4) -> tuple[List[Message], List[Message]]:
|
|
80
|
+
"""Split messages into old (to summarize) and recent (to keep)."""
|
|
81
|
+
if len(self.messages) <= keep_recent:
|
|
82
|
+
return [], self.messages
|
|
83
|
+
|
|
84
|
+
split_point = len(self.messages) - keep_recent
|
|
85
|
+
return self.messages[:split_point], self.messages[split_point:]
|
|
86
|
+
|
|
65
87
|
def to_dict(self) -> Dict[str, Any]:
|
|
66
88
|
"""Convert to dictionary for storage."""
|
|
67
|
-
|
|
89
|
+
data = {
|
|
68
90
|
"conversation_id": self.conversation_id,
|
|
69
91
|
"created_at": self.created_at.isoformat(),
|
|
70
92
|
"updated_at": self.updated_at.isoformat(),
|
|
71
93
|
"messages": [msg.to_dict() for msg in self.messages]
|
|
72
94
|
}
|
|
95
|
+
if self.summary:
|
|
96
|
+
data["summary"] = self.summary
|
|
97
|
+
return data
|
|
73
98
|
|
|
74
99
|
@classmethod
|
|
75
100
|
def from_dict(cls, data: Dict[str, Any]) -> "Conversation":
|
|
@@ -77,7 +102,8 @@ class Conversation:
|
|
|
77
102
|
conv = cls(
|
|
78
103
|
conversation_id=data["conversation_id"],
|
|
79
104
|
created_at=datetime.fromisoformat(data["created_at"]),
|
|
80
|
-
updated_at=datetime.fromisoformat(data["updated_at"])
|
|
105
|
+
updated_at=datetime.fromisoformat(data["updated_at"]),
|
|
106
|
+
summary=data.get("summary")
|
|
81
107
|
)
|
|
82
108
|
conv.messages = [Message.from_dict(msg) for msg in data.get("messages", [])]
|
|
83
109
|
return conv
|
|
@@ -187,3 +213,63 @@ class ConversationHistory:
|
|
|
187
213
|
return json.dumps(conv.to_dict(), indent=2)
|
|
188
214
|
|
|
189
215
|
return None
|
|
216
|
+
|
|
217
|
+
def summarize_conversation(
|
|
218
|
+
self,
|
|
219
|
+
conversation_id: str,
|
|
220
|
+
keep_recent: int = 4
|
|
221
|
+
) -> Optional[str]:
|
|
222
|
+
"""Summarize older messages in a conversation, keeping recent ones.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
conversation_id: The conversation to summarize
|
|
226
|
+
keep_recent: Number of recent message pairs to keep unsummarized
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
The generated summary or None if conversation not found
|
|
230
|
+
"""
|
|
231
|
+
from claude_dev_cli.core import ClaudeClient
|
|
232
|
+
|
|
233
|
+
conv = self.load_conversation(conversation_id)
|
|
234
|
+
if not conv:
|
|
235
|
+
return None
|
|
236
|
+
|
|
237
|
+
# Split messages
|
|
238
|
+
old_messages, recent_messages = conv.compress_messages(keep_recent)
|
|
239
|
+
|
|
240
|
+
if not old_messages:
|
|
241
|
+
return "No messages to summarize (too few messages)"
|
|
242
|
+
|
|
243
|
+
# Build summary prompt
|
|
244
|
+
conversation_text = []
|
|
245
|
+
if conv.summary:
|
|
246
|
+
conversation_text.append(f"Previous summary:\n{conv.summary}\n\n")
|
|
247
|
+
|
|
248
|
+
conversation_text.append("Conversation to summarize:\n")
|
|
249
|
+
for msg in old_messages:
|
|
250
|
+
role_name = "User" if msg.role == "user" else "Assistant"
|
|
251
|
+
conversation_text.append(f"{role_name}: {msg.content}\n")
|
|
252
|
+
|
|
253
|
+
prompt = (
|
|
254
|
+
"Please provide a concise summary of this conversation that captures:"
|
|
255
|
+
"\n1. Main topics discussed"
|
|
256
|
+
"\n2. Key questions asked and answers provided"
|
|
257
|
+
"\n3. Important decisions or conclusions"
|
|
258
|
+
"\n4. Any action items or follow-ups mentioned"
|
|
259
|
+
"\n\nKeep the summary under 300 words but retain all important context."
|
|
260
|
+
"\n\n" + "".join(conversation_text)
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
# Get summary from Claude
|
|
264
|
+
client = ClaudeClient()
|
|
265
|
+
new_summary = client.call(prompt)
|
|
266
|
+
|
|
267
|
+
# Update conversation
|
|
268
|
+
conv.summary = new_summary
|
|
269
|
+
conv.messages = recent_messages
|
|
270
|
+
conv.updated_at = datetime.utcnow()
|
|
271
|
+
|
|
272
|
+
# Save updated conversation
|
|
273
|
+
self.save_conversation(conv)
|
|
274
|
+
|
|
275
|
+
return new_summary
|
|
@@ -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
|
|
@@ -99,19 +106,39 @@ A powerful command-line tool for developers using Claude AI with multi-API routi
|
|
|
99
106
|
|
|
100
107
|
## Installation
|
|
101
108
|
|
|
102
|
-
###
|
|
109
|
+
### Via Homebrew (macOS/Linux)
|
|
103
110
|
|
|
104
111
|
```bash
|
|
105
|
-
|
|
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
|
|
106
120
|
```
|
|
107
121
|
|
|
108
|
-
###
|
|
122
|
+
### Via pip
|
|
109
123
|
|
|
110
124
|
```bash
|
|
111
|
-
#
|
|
125
|
+
# Basic installation
|
|
126
|
+
pip install claude-dev-cli
|
|
127
|
+
|
|
128
|
+
# With TOON support (30-60% token reduction)
|
|
112
129
|
pip install claude-dev-cli[toon]
|
|
113
130
|
```
|
|
114
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
|
+
|
|
115
142
|
## Quick Start
|
|
116
143
|
|
|
117
144
|
### 1. Set Up API Keys
|
|
@@ -266,7 +293,33 @@ cdc template list --user
|
|
|
266
293
|
- **explain-code**: Detailed code explanation
|
|
267
294
|
- **api-design**: API design assistance
|
|
268
295
|
|
|
269
|
-
### 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
|
|
270
323
|
|
|
271
324
|
```bash
|
|
272
325
|
# View all usage
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
claude_dev_cli/__init__.py,sha256=
|
|
2
|
-
claude_dev_cli/cli.py,sha256=
|
|
1
|
+
claude_dev_cli/__init__.py,sha256=4-FONrbZl8GAHKPOWIDbvA7AmSZsTv8CRep1rwl1w5Y,469
|
|
2
|
+
claude_dev_cli/cli.py,sha256=hy2HjU7oEWgGwNB7apBKFQmzjhYrxhHxTqtJ18iePZE,61164
|
|
3
3
|
claude_dev_cli/commands.py,sha256=RKGx2rv56PM6eErvA2uoQ20hY8babuI5jav8nCUyUOk,3964
|
|
4
|
-
claude_dev_cli/config.py,sha256=
|
|
4
|
+
claude_dev_cli/config.py,sha256=hisG91dUfDwuSdBhmYovU-rrGv__nFq-6fp7S288cSw,10471
|
|
5
5
|
claude_dev_cli/context.py,sha256=1TlLzpREFZDEIuU7RAtlkjxARKWZpnxHHvK283sUAZE,26714
|
|
6
6
|
claude_dev_cli/core.py,sha256=yaLjEixDvPzvUy4fJ2UB7nMpPPLyKACjR-RuM-1OQBY,4780
|
|
7
|
-
claude_dev_cli/history.py,sha256=
|
|
7
|
+
claude_dev_cli/history.py,sha256=v952xORhxZD0ayrrMaIbTLfe6kOW5fYryoeEmQLlQPg,10163
|
|
8
8
|
claude_dev_cli/secure_storage.py,sha256=TK3WOaU7a0yTOtzdP_t_28fDRp2lovANNAC6MBdm4nQ,7096
|
|
9
9
|
claude_dev_cli/template_manager.py,sha256=ZFXOtRIoB6hpf8kLSF9TWJfvUPJt9b-PyEv3qTBK7Zs,8600
|
|
10
10
|
claude_dev_cli/templates.py,sha256=lKxH943ySfUKgyHaWa4W3LVv91SgznKgajRtSRp_4UY,2260
|
|
@@ -17,9 +17,9 @@ claude_dev_cli/plugins/base.py,sha256=H4HQet1I-a3WLCfE9F06Lp8NuFvVoIlou7sIgyJFK-
|
|
|
17
17
|
claude_dev_cli/plugins/diff_editor/__init__.py,sha256=gqR5S2TyIVuq-sK107fegsutQ7Z-sgAIEbtc71FhXIM,101
|
|
18
18
|
claude_dev_cli/plugins/diff_editor/plugin.py,sha256=M1bUoqpasD3ZNQo36Fu_8g92uySPZyG_ujMbj5UplsU,3073
|
|
19
19
|
claude_dev_cli/plugins/diff_editor/viewer.py,sha256=1IOXIKw_01ppJx5C1dQt9Kr6U1TdAHT8_iUT5r_q0NM,17169
|
|
20
|
-
claude_dev_cli-0.8.
|
|
21
|
-
claude_dev_cli-0.8.
|
|
22
|
-
claude_dev_cli-0.8.
|
|
23
|
-
claude_dev_cli-0.8.
|
|
24
|
-
claude_dev_cli-0.8.
|
|
25
|
-
claude_dev_cli-0.8.
|
|
20
|
+
claude_dev_cli-0.8.3.dist-info/licenses/LICENSE,sha256=DGueuJwMJtMwgLO5mWlS0TaeBrFwQuNpNZ22PU9J2bw,1062
|
|
21
|
+
claude_dev_cli-0.8.3.dist-info/METADATA,sha256=zgkMO_8g4hwJ7ccfDqGqXM-d3OfghrhxsWt7JK0evgs,17356
|
|
22
|
+
claude_dev_cli-0.8.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
claude_dev_cli-0.8.3.dist-info/entry_points.txt,sha256=zymgUIIVpFTARkFmxAuW2A4BQsNITh_L0uU-XunytHg,85
|
|
24
|
+
claude_dev_cli-0.8.3.dist-info/top_level.txt,sha256=m7MF6LOIuTe41IT5Fgt0lc-DK1EgM4gUU_IZwWxK0pg,15
|
|
25
|
+
claude_dev_cli-0.8.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|