claude-dev-cli 0.12.1__py3-none-any.whl → 0.13.0__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 +255 -52
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/METADATA +18 -5
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/RECORD +8 -8
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/WHEEL +0 -0
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/entry_points.txt +0 -0
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/licenses/LICENSE +0 -0
- {claude_dev_cli-0.12.1.dist-info → claude_dev_cli-0.13.0.dist-info}/top_level.txt +0 -0
claude_dev_cli/__init__.py
CHANGED
claude_dev_cli/cli.py
CHANGED
|
@@ -1065,12 +1065,14 @@ def gen_docs(
|
|
|
1065
1065
|
@click.option('-f', '--file', 'spec_file', type=click.Path(exists=True), help='Read specification from file')
|
|
1066
1066
|
@click.option('--pdf', type=click.Path(exists=True), help='Read specification from PDF')
|
|
1067
1067
|
@click.option('--url', help='Fetch specification from URL')
|
|
1068
|
-
@click.option('-o', '--output', required=True, type=click.Path(), help='Output file path (required)')
|
|
1068
|
+
@click.option('-o', '--output', required=True, type=click.Path(), help='Output file or directory path (required)')
|
|
1069
1069
|
@click.option('--language', help='Target language (auto-detected from output extension)')
|
|
1070
1070
|
@click.option('-m', '--model', help='Model profile to use')
|
|
1071
1071
|
@click.option('-a', '--api', help='API config to use')
|
|
1072
1072
|
@click.option('-i', '--interactive', is_flag=True, help='Interactive refinement mode')
|
|
1073
1073
|
@click.option('--auto-context', is_flag=True, help='Include project context')
|
|
1074
|
+
@click.option('--dry-run', is_flag=True, help='Preview without writing files')
|
|
1075
|
+
@click.option('--yes', '-y', is_flag=True, help='Skip confirmation prompts')
|
|
1074
1076
|
@click.pass_context
|
|
1075
1077
|
def gen_code(
|
|
1076
1078
|
ctx: click.Context,
|
|
@@ -1083,17 +1085,25 @@ def gen_code(
|
|
|
1083
1085
|
model: Optional[str],
|
|
1084
1086
|
api: Optional[str],
|
|
1085
1087
|
interactive: bool,
|
|
1086
|
-
auto_context: bool
|
|
1088
|
+
auto_context: bool,
|
|
1089
|
+
dry_run: bool,
|
|
1090
|
+
yes: bool
|
|
1087
1091
|
) -> None:
|
|
1088
1092
|
"""Generate code from a specification.
|
|
1089
1093
|
|
|
1090
1094
|
Reads specification from text, file, PDF, or URL and generates complete code.
|
|
1091
1095
|
|
|
1092
|
-
|
|
1096
|
+
Single file mode (output is file):
|
|
1093
1097
|
cdc generate code --description "REST API client" -o client.py
|
|
1098
|
+
|
|
1099
|
+
Multi-file mode (output is directory):
|
|
1100
|
+
cdc generate code --description "FastAPI app" -o my-api/
|
|
1101
|
+
cdc generate code --file spec.md -o project/
|
|
1102
|
+
|
|
1103
|
+
Examples:
|
|
1094
1104
|
cdc generate code --file spec.md -o implementation.go
|
|
1095
1105
|
cdc generate code --pdf requirements.pdf -o app.js
|
|
1096
|
-
cdc generate code --url https://example.com/spec -o service
|
|
1106
|
+
cdc generate code --url https://example.com/spec -o service/ --dry-run
|
|
1097
1107
|
"""
|
|
1098
1108
|
console = ctx.obj['console']
|
|
1099
1109
|
from claude_dev_cli.input_sources import get_input_content
|
|
@@ -1129,18 +1139,51 @@ def gen_code(
|
|
|
1129
1139
|
}
|
|
1130
1140
|
language = language_map.get(ext, ext.upper() if ext else None)
|
|
1131
1141
|
|
|
1142
|
+
# Detect if output is directory (multi-file mode)
|
|
1143
|
+
output_path = Path(output)
|
|
1144
|
+
is_directory = output.endswith('/') or output_path.is_dir()
|
|
1145
|
+
|
|
1132
1146
|
console.print(f"[cyan]Generating code from:[/cyan] {source_desc}")
|
|
1133
1147
|
if language:
|
|
1134
1148
|
console.print(f"[cyan]Target language:[/cyan] {language}")
|
|
1135
|
-
console.print(f"[cyan]Output:[/cyan] {output}\n")
|
|
1136
1149
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1150
|
+
if is_directory:
|
|
1151
|
+
console.print(f"[cyan]Output directory:[/cyan] {output}")
|
|
1152
|
+
console.print(f"[cyan]Mode:[/cyan] Multi-file project generation\n")
|
|
1153
|
+
else:
|
|
1154
|
+
console.print(f"[cyan]Output file:[/cyan] {output}\n")
|
|
1155
|
+
|
|
1156
|
+
# Build prompt (different for single vs multi-file)
|
|
1157
|
+
if is_directory:
|
|
1158
|
+
# Multi-file mode: request structured output
|
|
1159
|
+
prompt = f"Specification:\n\n{spec_content}\n\n"
|
|
1160
|
+
if language:
|
|
1161
|
+
prompt += f"Generate a complete, production-ready {language} project that implements this specification. "
|
|
1162
|
+
else:
|
|
1163
|
+
prompt += "Generate a complete, production-ready project that implements this specification. "
|
|
1164
|
+
prompt += """\n
|
|
1165
|
+
Provide your response in this format:
|
|
1166
|
+
|
|
1167
|
+
## File: relative/path/to/file.ext
|
|
1168
|
+
```language
|
|
1169
|
+
// Complete file content
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
## File: another/file.ext
|
|
1173
|
+
```language
|
|
1174
|
+
// Complete file content
|
|
1175
|
+
```
|
|
1176
|
+
|
|
1177
|
+
Include ALL necessary files: source code, configuration, dependencies, README, etc.
|
|
1178
|
+
Use proper directory structure and include proper error handling, documentation, and best practices."""
|
|
1141
1179
|
else:
|
|
1142
|
-
|
|
1143
|
-
|
|
1180
|
+
# Single file mode: simple prompt
|
|
1181
|
+
prompt = f"Specification:\n\n{spec_content}\n\n"
|
|
1182
|
+
if language:
|
|
1183
|
+
prompt += f"Generate complete, production-ready {language} code that implements this specification. "
|
|
1184
|
+
else:
|
|
1185
|
+
prompt += "Generate complete, production-ready code that implements this specification. "
|
|
1186
|
+
prompt += "Include proper error handling, documentation, and best practices."
|
|
1144
1187
|
|
|
1145
1188
|
# Add context if requested
|
|
1146
1189
|
if auto_context:
|
|
@@ -1197,8 +1240,51 @@ def gen_code(
|
|
|
1197
1240
|
conversation_context.append(result)
|
|
1198
1241
|
|
|
1199
1242
|
# Save output
|
|
1200
|
-
|
|
1201
|
-
|
|
1243
|
+
if is_directory:
|
|
1244
|
+
# Multi-file mode: parse and write multiple files
|
|
1245
|
+
from claude_dev_cli.multi_file_handler import MultiFileResponse
|
|
1246
|
+
|
|
1247
|
+
multi_file = MultiFileResponse()
|
|
1248
|
+
multi_file.parse_response(result, base_path=output_path)
|
|
1249
|
+
|
|
1250
|
+
if not multi_file.files:
|
|
1251
|
+
console.print("[yellow]Warning: No files were detected in the response.[/yellow]")
|
|
1252
|
+
console.print("[dim]Falling back to single file output...[/dim]")
|
|
1253
|
+
# Save as single file anyway
|
|
1254
|
+
fallback_file = output_path / "generated_code.txt"
|
|
1255
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
1256
|
+
fallback_file.write_text(result)
|
|
1257
|
+
console.print(f"\n[green]✓[/green] Output saved to: {fallback_file}")
|
|
1258
|
+
return
|
|
1259
|
+
|
|
1260
|
+
# Validate paths
|
|
1261
|
+
errors = multi_file.validate_paths(output_path)
|
|
1262
|
+
if errors:
|
|
1263
|
+
console.print("[red]Path validation errors:[/red]")
|
|
1264
|
+
for error in errors:
|
|
1265
|
+
console.print(f" • {error}")
|
|
1266
|
+
sys.exit(1)
|
|
1267
|
+
|
|
1268
|
+
# Show preview
|
|
1269
|
+
multi_file.preview(console, output_path)
|
|
1270
|
+
|
|
1271
|
+
# Confirm or auto-accept
|
|
1272
|
+
if not yes and not dry_run:
|
|
1273
|
+
if not multi_file.confirm(console):
|
|
1274
|
+
console.print("[yellow]Cancelled[/yellow]")
|
|
1275
|
+
return
|
|
1276
|
+
|
|
1277
|
+
# Write files
|
|
1278
|
+
multi_file.write_all(output_path, dry_run=dry_run, console=console)
|
|
1279
|
+
|
|
1280
|
+
if dry_run:
|
|
1281
|
+
console.print("\n[yellow]Dry-run mode - no files were written[/yellow]")
|
|
1282
|
+
else:
|
|
1283
|
+
console.print(f"\n[green]✓[/green] Project created in: {output}")
|
|
1284
|
+
else:
|
|
1285
|
+
# Single file mode: simple write
|
|
1286
|
+
Path(output).write_text(result)
|
|
1287
|
+
console.print(f"\n[green]✓[/green] Code saved to: {output}")
|
|
1202
1288
|
|
|
1203
1289
|
except Exception as e:
|
|
1204
1290
|
console.print(f"[red]Error: {e}[/red]")
|
|
@@ -1217,6 +1303,8 @@ def gen_code(
|
|
|
1217
1303
|
@click.option('-i', '--interactive', is_flag=True, help='Interactive refinement mode')
|
|
1218
1304
|
@click.option('--auto-context', is_flag=True, help='Include project context')
|
|
1219
1305
|
@click.option('--preview', is_flag=True, help='Preview changes without applying')
|
|
1306
|
+
@click.option('--dry-run', is_flag=True, help='Show what would be changed without writing')
|
|
1307
|
+
@click.option('--yes', '-y', is_flag=True, help='Apply changes without confirmation')
|
|
1220
1308
|
@click.pass_context
|
|
1221
1309
|
def gen_feature(
|
|
1222
1310
|
ctx: click.Context,
|
|
@@ -1230,7 +1318,9 @@ def gen_feature(
|
|
|
1230
1318
|
api: Optional[str],
|
|
1231
1319
|
interactive: bool,
|
|
1232
1320
|
auto_context: bool,
|
|
1233
|
-
preview: bool
|
|
1321
|
+
preview: bool,
|
|
1322
|
+
dry_run: bool,
|
|
1323
|
+
yes: bool
|
|
1234
1324
|
) -> None:
|
|
1235
1325
|
"""Generate code to add a feature to existing project.
|
|
1236
1326
|
|
|
@@ -1241,6 +1331,8 @@ def gen_feature(
|
|
|
1241
1331
|
cdc generate feature --file feature-spec.md
|
|
1242
1332
|
cdc generate feature --pdf requirements.pdf --preview
|
|
1243
1333
|
cdc generate feature --url https://example.com/spec src/
|
|
1334
|
+
cdc generate feature -f spec.md --dry-run
|
|
1335
|
+
cdc generate feature -f spec.md --yes
|
|
1244
1336
|
"""
|
|
1245
1337
|
console = ctx.obj['console']
|
|
1246
1338
|
from claude_dev_cli.input_sources import get_input_content
|
|
@@ -1290,15 +1382,19 @@ def gen_feature(
|
|
|
1290
1382
|
except Exception as e:
|
|
1291
1383
|
console.print(f"[yellow]Warning: Could not read {file_path}: {e}[/yellow]")
|
|
1292
1384
|
|
|
1293
|
-
# Build prompt
|
|
1385
|
+
# Build prompt with multi-file support
|
|
1294
1386
|
prompt = f"Feature Specification:\n\n{spec_content}\n\n"
|
|
1295
1387
|
prompt += f"Existing Codebase:{codebase_content}\n\n"
|
|
1296
|
-
prompt += "Analyze the existing code and provide
|
|
1297
|
-
prompt += "
|
|
1298
|
-
prompt += "
|
|
1299
|
-
prompt += "
|
|
1300
|
-
prompt += "
|
|
1301
|
-
prompt += "
|
|
1388
|
+
prompt += "Analyze the existing code and provide the complete implementation.\n\n"
|
|
1389
|
+
prompt += "IMPORTANT: Structure your response with file markers:\n"
|
|
1390
|
+
prompt += "## File: path/to/file.ext\n"
|
|
1391
|
+
prompt += "```language\n"
|
|
1392
|
+
prompt += "// complete file content\n"
|
|
1393
|
+
prompt += "```\n\n"
|
|
1394
|
+
prompt += "Use '## Create: path/to/new.ext' for new files.\n"
|
|
1395
|
+
prompt += "Use '## Modify: path/to/existing.ext' for changes to existing files.\n"
|
|
1396
|
+
prompt += "Use '## Delete: path/to/old.ext' if files should be removed.\n\n"
|
|
1397
|
+
prompt += "Provide complete, working code for all affected files."
|
|
1302
1398
|
|
|
1303
1399
|
# Add context if requested
|
|
1304
1400
|
if auto_context:
|
|
@@ -1317,39 +1413,32 @@ def gen_feature(
|
|
|
1317
1413
|
client = ClaudeClient(api_config_name=api)
|
|
1318
1414
|
result = client.call(prompt, model=model)
|
|
1319
1415
|
|
|
1320
|
-
# Show result
|
|
1321
|
-
from rich.markdown import Markdown
|
|
1322
|
-
md = Markdown(result)
|
|
1323
|
-
console.print(md)
|
|
1324
|
-
|
|
1325
|
-
if preview:
|
|
1326
|
-
console.print("\n[yellow]Preview mode - no changes applied[/yellow]")
|
|
1327
|
-
console.print("[dim]Remove --preview flag to apply changes[/dim]")
|
|
1328
|
-
return
|
|
1329
|
-
|
|
1330
1416
|
# Interactive refinement
|
|
1331
1417
|
if interactive:
|
|
1418
|
+
from rich.markdown import Markdown
|
|
1419
|
+
md = Markdown(result)
|
|
1420
|
+
console.print(md)
|
|
1421
|
+
|
|
1332
1422
|
client = ClaudeClient(api_config_name=api)
|
|
1333
1423
|
conversation_context = [result]
|
|
1334
1424
|
|
|
1335
1425
|
while True:
|
|
1336
|
-
console.print("\n[dim]Ask for changes, '
|
|
1426
|
+
console.print("\n[dim]Ask for changes, 'save' to continue, or 'exit' to cancel[/dim]")
|
|
1337
1427
|
user_input = console.input("[cyan]You:[/cyan] ").strip()
|
|
1338
1428
|
|
|
1339
1429
|
if user_input.lower() == 'exit':
|
|
1340
1430
|
console.print("[yellow]Cancelled[/yellow]")
|
|
1341
1431
|
return
|
|
1342
1432
|
|
|
1343
|
-
if user_input.lower() == '
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
return
|
|
1433
|
+
if user_input.lower() == 'save':
|
|
1434
|
+
result = conversation_context[-1]
|
|
1435
|
+
break
|
|
1347
1436
|
|
|
1348
1437
|
if not user_input:
|
|
1349
1438
|
continue
|
|
1350
1439
|
|
|
1351
1440
|
# Get refinement
|
|
1352
|
-
refinement_prompt = f"Previous implementation
|
|
1441
|
+
refinement_prompt = f"Previous implementation:\n\n{conversation_context[-1]}\n\nUser request: {user_input}\n\nProvide the updated implementation with file markers."
|
|
1353
1442
|
|
|
1354
1443
|
console.print("\n[bold green]Claude:[/bold green] ", end='')
|
|
1355
1444
|
response_parts = []
|
|
@@ -1360,9 +1449,54 @@ def gen_feature(
|
|
|
1360
1449
|
|
|
1361
1450
|
result = ''.join(response_parts)
|
|
1362
1451
|
conversation_context.append(result)
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1452
|
+
|
|
1453
|
+
# Parse multi-file response
|
|
1454
|
+
from claude_dev_cli.multi_file_handler import MultiFileResponse
|
|
1455
|
+
from pathlib import Path
|
|
1456
|
+
|
|
1457
|
+
# Use current directory as base
|
|
1458
|
+
base_path = Path.cwd()
|
|
1459
|
+
|
|
1460
|
+
multi_file = MultiFileResponse()
|
|
1461
|
+
multi_file.parse_response(result, base_path=base_path)
|
|
1462
|
+
|
|
1463
|
+
if not multi_file.files:
|
|
1464
|
+
# No structured output detected, show markdown
|
|
1465
|
+
console.print("\n[yellow]No structured file output detected[/yellow]")
|
|
1466
|
+
from rich.markdown import Markdown
|
|
1467
|
+
md = Markdown(result)
|
|
1468
|
+
console.print(md)
|
|
1469
|
+
console.print("\n[dim]Apply the changes manually from the output above[/dim]")
|
|
1470
|
+
return
|
|
1471
|
+
|
|
1472
|
+
# Validate paths
|
|
1473
|
+
errors = multi_file.validate_paths(base_path)
|
|
1474
|
+
if errors:
|
|
1475
|
+
console.print("[red]Path validation errors:[/red]")
|
|
1476
|
+
for error in errors:
|
|
1477
|
+
console.print(f" • {error}")
|
|
1478
|
+
sys.exit(1)
|
|
1479
|
+
|
|
1480
|
+
# Show preview
|
|
1481
|
+
multi_file.preview(console, base_path)
|
|
1482
|
+
|
|
1483
|
+
# Handle preview/dry-run modes
|
|
1484
|
+
if preview or dry_run:
|
|
1485
|
+
console.print("\n[yellow]Preview mode - no changes applied[/yellow]")
|
|
1486
|
+
if preview:
|
|
1487
|
+
console.print("[dim]Remove --preview flag to apply changes[/dim]")
|
|
1488
|
+
return
|
|
1489
|
+
|
|
1490
|
+
# Confirm or auto-accept
|
|
1491
|
+
if not yes:
|
|
1492
|
+
if not multi_file.confirm(console):
|
|
1493
|
+
console.print("[yellow]Cancelled[/yellow]")
|
|
1494
|
+
return
|
|
1495
|
+
|
|
1496
|
+
# Write files
|
|
1497
|
+
multi_file.write_all(base_path, dry_run=False, console=console)
|
|
1498
|
+
|
|
1499
|
+
console.print(f"\n[green]✓[/green] Feature implemented successfully")
|
|
1366
1500
|
|
|
1367
1501
|
except Exception as e:
|
|
1368
1502
|
console.print(f"[red]Error: {e}[/red]")
|
|
@@ -1541,6 +1675,9 @@ def debug(
|
|
|
1541
1675
|
@click.option('-i', '--interactive', is_flag=True, help='Interactive refinement mode')
|
|
1542
1676
|
@click.option('--auto-context', is_flag=True, help='Automatically include git, dependencies, and related files')
|
|
1543
1677
|
@click.option('--max-files', type=int, default=20, help='Maximum files to refactor (default: 20)')
|
|
1678
|
+
@click.option('--preview', is_flag=True, help='Preview changes without applying')
|
|
1679
|
+
@click.option('--dry-run', is_flag=True, help='Show what would be changed without writing')
|
|
1680
|
+
@click.option('--yes', '-y', is_flag=True, help='Apply changes without confirmation')
|
|
1544
1681
|
@click.pass_context
|
|
1545
1682
|
def refactor(
|
|
1546
1683
|
ctx: click.Context,
|
|
@@ -1549,7 +1686,10 @@ def refactor(
|
|
|
1549
1686
|
api: Optional[str],
|
|
1550
1687
|
interactive: bool,
|
|
1551
1688
|
auto_context: bool,
|
|
1552
|
-
max_files: int
|
|
1689
|
+
max_files: int,
|
|
1690
|
+
preview: bool,
|
|
1691
|
+
dry_run: bool,
|
|
1692
|
+
yes: bool
|
|
1553
1693
|
) -> None:
|
|
1554
1694
|
"""Suggest refactoring improvements.
|
|
1555
1695
|
|
|
@@ -1558,6 +1698,8 @@ def refactor(
|
|
|
1558
1698
|
cdc refactor file1.py file2.py # Multiple files
|
|
1559
1699
|
cdc refactor src/ # Directory
|
|
1560
1700
|
cdc refactor # Auto-detect git changes
|
|
1701
|
+
cdc refactor src/ --dry-run # Preview changes
|
|
1702
|
+
cdc refactor file.py --yes # Apply without confirmation
|
|
1561
1703
|
"""
|
|
1562
1704
|
console = ctx.obj['console']
|
|
1563
1705
|
from claude_dev_cli.path_utils import expand_paths, auto_detect_files
|
|
@@ -1589,7 +1731,7 @@ def refactor(
|
|
|
1589
1731
|
console.print(f" ... and {len(files) - 10} more")
|
|
1590
1732
|
console.print()
|
|
1591
1733
|
|
|
1592
|
-
# Build combined prompt
|
|
1734
|
+
# Build combined prompt with multi-file support
|
|
1593
1735
|
files_content = ""
|
|
1594
1736
|
for file_path in files:
|
|
1595
1737
|
try:
|
|
@@ -1599,6 +1741,16 @@ def refactor(
|
|
|
1599
1741
|
except Exception as e:
|
|
1600
1742
|
console.print(f"[yellow]Warning: Could not read {file_path}: {e}[/yellow]")
|
|
1601
1743
|
|
|
1744
|
+
refactor_instructions = (
|
|
1745
|
+
"\n\nIMPORTANT: Structure your response with file markers:\n"
|
|
1746
|
+
"## File: path/to/file.ext\n"
|
|
1747
|
+
"```language\n"
|
|
1748
|
+
"// complete refactored file content\n"
|
|
1749
|
+
"```\n\n"
|
|
1750
|
+
"Use '## Modify: path/to/file.ext' to indicate files being refactored.\n"
|
|
1751
|
+
"Provide complete, working refactored code for all files.\n"
|
|
1752
|
+
)
|
|
1753
|
+
|
|
1602
1754
|
# Gather context if requested
|
|
1603
1755
|
if auto_context:
|
|
1604
1756
|
from claude_dev_cli.context import ContextGatherer
|
|
@@ -1611,11 +1763,11 @@ def refactor(
|
|
|
1611
1763
|
console.print("[dim]✓ Context gathered[/dim]")
|
|
1612
1764
|
|
|
1613
1765
|
client = ClaudeClient(api_config_name=api)
|
|
1614
|
-
prompt = f"{context_info}\n\nFiles:{files_content}\n\nPlease suggest refactoring improvements."
|
|
1766
|
+
prompt = f"{context_info}\n\nFiles:{files_content}\n\nPlease suggest refactoring improvements.{refactor_instructions}"
|
|
1615
1767
|
else:
|
|
1616
1768
|
with console.status(f"[bold blue]Analyzing {len(files)} file(s)..."):
|
|
1617
1769
|
client = ClaudeClient(api_config_name=api)
|
|
1618
|
-
prompt = f"Files to refactor:{files_content}\n\nPlease suggest refactoring improvements focusing on code quality, maintainability, and performance."
|
|
1770
|
+
prompt = f"Files to refactor:{files_content}\n\nPlease suggest refactoring improvements focusing on code quality, maintainability, and performance.{refactor_instructions}"
|
|
1619
1771
|
|
|
1620
1772
|
result = client.call(prompt)
|
|
1621
1773
|
|
|
@@ -1627,7 +1779,7 @@ def refactor(
|
|
|
1627
1779
|
conversation_context = [result]
|
|
1628
1780
|
|
|
1629
1781
|
while True:
|
|
1630
|
-
console.print("\n[dim]Commands: 'save' to
|
|
1782
|
+
console.print("\n[dim]Commands: 'save' to continue, 'exit' to discard, or ask for changes[/dim]")
|
|
1631
1783
|
user_input = console.input("[cyan]You:[/cyan] ").strip()
|
|
1632
1784
|
|
|
1633
1785
|
if user_input.lower() == 'exit':
|
|
@@ -1641,7 +1793,7 @@ def refactor(
|
|
|
1641
1793
|
if not user_input:
|
|
1642
1794
|
continue
|
|
1643
1795
|
|
|
1644
|
-
refinement_prompt = f"Previous refactoring:\n\n{conversation_context[-1]}\n\nUser request: {user_input}\n\nProvide the updated refactoring
|
|
1796
|
+
refinement_prompt = f"Previous refactoring:\n\n{conversation_context[-1]}\n\nUser request: {user_input}\n\nProvide the updated refactoring with file markers."
|
|
1645
1797
|
|
|
1646
1798
|
console.print("\n[bold green]Claude:[/bold green] ", end='')
|
|
1647
1799
|
response_parts = []
|
|
@@ -1653,13 +1805,64 @@ def refactor(
|
|
|
1653
1805
|
result = ''.join(response_parts)
|
|
1654
1806
|
conversation_context.append(result)
|
|
1655
1807
|
|
|
1808
|
+
# Handle single file output mode (legacy behavior)
|
|
1656
1809
|
if output:
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1810
|
+
if len(files) == 1:
|
|
1811
|
+
with open(output, 'w') as f:
|
|
1812
|
+
f.write(result)
|
|
1813
|
+
console.print(f"\n[green]✓[/green] Refactored code saved to: {output}")
|
|
1814
|
+
else:
|
|
1815
|
+
console.print("[yellow]Warning: --output only works with single file. Using multi-file mode.[/yellow]")
|
|
1816
|
+
output = None
|
|
1817
|
+
|
|
1818
|
+
# Parse multi-file response if output not specified
|
|
1819
|
+
if not output:
|
|
1820
|
+
from claude_dev_cli.multi_file_handler import MultiFileResponse
|
|
1821
|
+
from pathlib import Path
|
|
1822
|
+
|
|
1823
|
+
# Use current directory as base
|
|
1824
|
+
base_path = Path.cwd()
|
|
1825
|
+
|
|
1826
|
+
multi_file = MultiFileResponse()
|
|
1827
|
+
multi_file.parse_response(result, base_path=base_path)
|
|
1828
|
+
|
|
1829
|
+
if not multi_file.files:
|
|
1830
|
+
# No structured output detected, show markdown
|
|
1831
|
+
if not interactive:
|
|
1832
|
+
console.print("\n[yellow]No structured file output detected[/yellow]")
|
|
1833
|
+
md = Markdown(result)
|
|
1834
|
+
console.print(md)
|
|
1835
|
+
console.print("\n[dim]Apply the changes manually from the output above[/dim]")
|
|
1836
|
+
return
|
|
1837
|
+
|
|
1838
|
+
# Validate paths
|
|
1839
|
+
errors = multi_file.validate_paths(base_path)
|
|
1840
|
+
if errors:
|
|
1841
|
+
console.print("[red]Path validation errors:[/red]")
|
|
1842
|
+
for error in errors:
|
|
1843
|
+
console.print(f" • {error}")
|
|
1844
|
+
sys.exit(1)
|
|
1845
|
+
|
|
1846
|
+
# Show preview
|
|
1847
|
+
multi_file.preview(console, base_path)
|
|
1848
|
+
|
|
1849
|
+
# Handle preview/dry-run modes
|
|
1850
|
+
if preview or dry_run:
|
|
1851
|
+
console.print("\n[yellow]Preview mode - no changes applied[/yellow]")
|
|
1852
|
+
if preview:
|
|
1853
|
+
console.print("[dim]Remove --preview flag to apply changes[/dim]")
|
|
1854
|
+
return
|
|
1855
|
+
|
|
1856
|
+
# Confirm or auto-accept
|
|
1857
|
+
if not yes:
|
|
1858
|
+
if not multi_file.confirm(console):
|
|
1859
|
+
console.print("[yellow]Cancelled[/yellow]")
|
|
1860
|
+
return
|
|
1861
|
+
|
|
1862
|
+
# Write files
|
|
1863
|
+
multi_file.write_all(base_path, dry_run=False, console=console)
|
|
1864
|
+
|
|
1865
|
+
console.print(f"\n[green]✓[/green] Refactoring applied successfully")
|
|
1663
1866
|
|
|
1664
1867
|
except Exception as e:
|
|
1665
1868
|
console.print(f"[red]Error: {e}[/red]")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-dev-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
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
|
|
@@ -281,22 +281,28 @@ cdc review -m powerful complex_file.py # More thorough review
|
|
|
281
281
|
cdc generate tests -m smart mymodule.py # Balanced approach
|
|
282
282
|
```
|
|
283
283
|
|
|
284
|
-
### 3. Code Generation Commands (NEW in v0.12.0)
|
|
284
|
+
### 3. Code Generation Commands (NEW in v0.12.0, enhanced v0.13.0)
|
|
285
285
|
|
|
286
286
|
```bash
|
|
287
|
-
# Generate code from specification
|
|
287
|
+
# Generate code from specification (single file)
|
|
288
288
|
cdc generate code --description "REST API client for weather data" -o client.py
|
|
289
289
|
cdc generate code --file spec.md -o implementation.go
|
|
290
290
|
cdc generate code --pdf requirements.pdf -o app.js
|
|
291
291
|
cdc generate code --url https://example.com/api-spec -o service.py
|
|
292
292
|
|
|
293
|
+
# Generate multi-file projects (NEW in v0.13.0)
|
|
294
|
+
cdc generate code --description "FastAPI REST API with auth" -o my-api/
|
|
295
|
+
cdc generate code --file spec.md -o project/ --dry-run # Preview first
|
|
296
|
+
cdc generate code --file spec.md -o project/ --yes # No confirmation
|
|
297
|
+
# Creates complete directory structure with multiple files
|
|
298
|
+
|
|
293
299
|
# Generate code with interactive refinement
|
|
294
300
|
cdc generate code --description "Database ORM" -o orm.py --interactive
|
|
295
301
|
|
|
296
302
|
# Generate code with project context
|
|
297
303
|
cdc generate code --file spec.md -o service.py --auto-context
|
|
298
304
|
|
|
299
|
-
# Add features to existing project
|
|
305
|
+
# Add features to existing project (NEW: multi-file output in v0.13.0)
|
|
300
306
|
cdc generate feature --description "Add user authentication with JWT" src/
|
|
301
307
|
cdc generate feature --file feature-spec.md
|
|
302
308
|
cdc generate feature --pdf product-requirements.pdf --preview
|
|
@@ -304,6 +310,8 @@ cdc generate feature --url https://example.com/feature-spec
|
|
|
304
310
|
|
|
305
311
|
# Preview feature changes before applying
|
|
306
312
|
cdc generate feature --description "Add caching layer" src/ --preview
|
|
313
|
+
cdc generate feature --description "Add REST API" --dry-run # Preview changes
|
|
314
|
+
cdc generate feature --file spec.md --yes # Apply without confirmation
|
|
307
315
|
|
|
308
316
|
# Interactive feature implementation
|
|
309
317
|
cdc generate feature --description "Add logging" src/ --interactive
|
|
@@ -363,11 +371,16 @@ cdc generate docs mymodule.py --auto-context
|
|
|
363
371
|
# Refactor (single file)
|
|
364
372
|
cdc refactor legacy_code.py
|
|
365
373
|
|
|
366
|
-
# Refactor multiple files (NEW in v0.11.0)
|
|
374
|
+
# Refactor multiple files (NEW in v0.11.0, enhanced v0.13.0)
|
|
367
375
|
cdc refactor file1.py file2.py file3.py
|
|
368
376
|
cdc refactor src/
|
|
369
377
|
cdc refactor # Auto-detect git changes
|
|
370
378
|
|
|
379
|
+
# Multi-file refactoring with preview (NEW in v0.13.0)
|
|
380
|
+
cdc refactor src/ --dry-run # Preview changes
|
|
381
|
+
cdc refactor src/ --yes # Apply without confirmation
|
|
382
|
+
cdc refactor src/ --preview # Review before applying
|
|
383
|
+
|
|
371
384
|
# Refactor with context (includes related files)
|
|
372
385
|
cdc refactor legacy_code.py --auto-context
|
|
373
386
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
claude_dev_cli/__init__.py,sha256=
|
|
2
|
-
claude_dev_cli/cli.py,sha256=
|
|
1
|
+
claude_dev_cli/__init__.py,sha256=m1PPg9TBL_opaZdRHkV3d_MDa4IFCPqCFE0KUyBlpVg,470
|
|
2
|
+
claude_dev_cli/cli.py,sha256=pIIZv3AT0gCF4faTVSlY_d6F-ya9L3gYoVeUTlq07VY,100412
|
|
3
3
|
claude_dev_cli/commands.py,sha256=RKGx2rv56PM6eErvA2uoQ20hY8babuI5jav8nCUyUOk,3964
|
|
4
4
|
claude_dev_cli/config.py,sha256=ZnPvzwlXsoY9YhqTl4S__fwY1MzJXKIaYK0nIIelNXk,19978
|
|
5
5
|
claude_dev_cli/context.py,sha256=1TlLzpREFZDEIuU7RAtlkjxARKWZpnxHHvK283sUAZE,26714
|
|
@@ -20,9 +20,9 @@ claude_dev_cli/plugins/base.py,sha256=H4HQet1I-a3WLCfE9F06Lp8NuFvVoIlou7sIgyJFK-
|
|
|
20
20
|
claude_dev_cli/plugins/diff_editor/__init__.py,sha256=gqR5S2TyIVuq-sK107fegsutQ7Z-sgAIEbtc71FhXIM,101
|
|
21
21
|
claude_dev_cli/plugins/diff_editor/plugin.py,sha256=M1bUoqpasD3ZNQo36Fu_8g92uySPZyG_ujMbj5UplsU,3073
|
|
22
22
|
claude_dev_cli/plugins/diff_editor/viewer.py,sha256=1IOXIKw_01ppJx5C1dQt9Kr6U1TdAHT8_iUT5r_q0NM,17169
|
|
23
|
-
claude_dev_cli-0.
|
|
24
|
-
claude_dev_cli-0.
|
|
25
|
-
claude_dev_cli-0.
|
|
26
|
-
claude_dev_cli-0.
|
|
27
|
-
claude_dev_cli-0.
|
|
28
|
-
claude_dev_cli-0.
|
|
23
|
+
claude_dev_cli-0.13.0.dist-info/licenses/LICENSE,sha256=DGueuJwMJtMwgLO5mWlS0TaeBrFwQuNpNZ22PU9J2bw,1062
|
|
24
|
+
claude_dev_cli-0.13.0.dist-info/METADATA,sha256=vzv4dlBOqJ5Y-tz6OgcafaMq1ponwWgYdVhZIkYD13U,24788
|
|
25
|
+
claude_dev_cli-0.13.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
26
|
+
claude_dev_cli-0.13.0.dist-info/entry_points.txt,sha256=zymgUIIVpFTARkFmxAuW2A4BQsNITh_L0uU-XunytHg,85
|
|
27
|
+
claude_dev_cli-0.13.0.dist-info/top_level.txt,sha256=m7MF6LOIuTe41IT5Fgt0lc-DK1EgM4gUU_IZwWxK0pg,15
|
|
28
|
+
claude_dev_cli-0.13.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|