gitarsenal-cli 1.9.85 → 1.9.87

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.
package/.venv_status.json CHANGED
@@ -1 +1 @@
1
- {"created":"2025-08-20T12:21:13.646Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
1
+ {"created":"2025-08-20T13:10:12.929Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
@@ -109,7 +109,7 @@ When you run `query "read main.py"`, you now see:
109
109
 
110
110
  ### Enhanced Todo Management
111
111
  Todo lists are now displayed as professional tables with:
112
- - Status indicators (⏳ Pending, 🔄 In Progress, Completed)
112
+ - Status indicators (⏳ Pending, 🔄 In Progress, Completed)
113
113
  - Organized columns
114
114
  - Clean borders and styling
115
115
 
@@ -33,8 +33,11 @@ from rich.text import Text
33
33
  from rich.progress import Progress, SpinnerColumn, TextColumn
34
34
  from rich.tree import Tree
35
35
  from rich.syntax import Syntax
36
- from rich.prompt import Prompt
36
+ from rich.prompt import Prompt, Confirm, IntPrompt
37
37
  from rich import print as rprint
38
+ from rich.layout import Layout
39
+ from rich.live import Live
40
+ from pathlib import Path
38
41
 
39
42
  def load_tool_modules():
40
43
  """Load all tool modules from the tools directory."""
@@ -444,7 +447,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
444
447
  todo_table.add_column("Task", style="cyan")
445
448
 
446
449
  for i, todo in enumerate(todos, 1):
447
- status_emoji = {"pending": "⏳ Pending", "in_progress": "🔄 In Progress", "completed": " Completed"}.get(todo.get("status", "pending"), "❓ Unknown")
450
+ status_emoji = {"pending": "⏳ Pending", "in_progress": "🔄 In Progress", "completed": " Completed"}.get(todo.get("status", "pending"), "❓ Unknown")
448
451
  content = todo.get("content", "No description")
449
452
  if len(content) > 80:
450
453
  content = content[:80] + "..."
@@ -557,7 +560,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
557
560
 
558
561
  # Success panel
559
562
  success_panel = Panel(
560
- f" [bold green]Tool {tool_name} completed successfully[/bold green]",
563
+ f" [bold green]Tool {tool_name} completed successfully[/bold green]",
561
564
  border_style="green",
562
565
  padding=(0, 1)
563
566
  )
@@ -566,7 +569,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
566
569
  console.print(result_panel)
567
570
  else:
568
571
  console.print(Panel(
569
- " [bold green]Tool completed successfully[/bold green]\n[dim](no output)[/dim]",
572
+ " [bold green]Tool completed successfully[/bold green]\n[dim](no output)[/dim]",
570
573
  title=f"Tool {tool_name}",
571
574
  border_style="green",
572
575
  padding=(0, 1)
@@ -577,7 +580,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
577
580
 
578
581
  except Exception as e:
579
582
  console.print(Panel(
580
- f" [bold red]Tool {tool_name} failed:[/bold red]\n{str(e)}",
583
+ f" [bold red]Tool {tool_name} failed:[/bold red]\n{str(e)}",
581
584
  border_style="red",
582
585
  padding=(0, 1)
583
586
  ))
@@ -617,6 +620,10 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
617
620
  return self._get_bash_output(tool_input)
618
621
  elif tool_name == "KillBash":
619
622
  return self._kill_bash(tool_input)
623
+ elif tool_name == "WebSearch":
624
+ return self._web_search(tool_input)
625
+ elif tool_name == "WebFetch":
626
+ return self._web_fetch(tool_input)
620
627
  else:
621
628
  return f"Tool {tool_name} not implemented"
622
629
 
@@ -844,6 +851,60 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
844
851
  except Exception as e:
845
852
  return f"Error searching: {str(e)}"
846
853
 
854
+ def _web_search(self, tool_input: Dict[str, Any]) -> str:
855
+ """Handle WebSearch tool - search the web for information."""
856
+ query = tool_input.get('query', '')
857
+ allowed_domains = tool_input.get('allowed_domains', [])
858
+ blocked_domains = tool_input.get('blocked_domains', [])
859
+
860
+ if not query:
861
+ return "Error: No search query provided"
862
+
863
+ # Since we don't have actual web search capability, return a mock response
864
+ # In a real implementation, this would use a search API like Google, Bing, or DuckDuckGo
865
+ domain_filter = ""
866
+ if allowed_domains:
867
+ domain_filter = f" (restricted to: {', '.join(allowed_domains)})"
868
+ elif blocked_domains:
869
+ domain_filter = f" (excluding: {', '.join(blocked_domains)})"
870
+
871
+ return f"""Web search results for: "{query}"{domain_filter}
872
+
873
+ ⚠️ Note: WebSearch is not fully implemented in this demo version.
874
+
875
+ In a production environment, this would:
876
+ • Search the web using APIs like Google Search API, Bing API, or similar
877
+ • Return formatted search results with titles, snippets, and URLs
878
+ • Support domain filtering as specified
879
+ • Provide up-to-date information beyond the AI's knowledge cutoff
880
+
881
+ Query processed: "{query}"
882
+ Domain restrictions: {domain_filter if domain_filter else "None"}"""
883
+
884
+ def _web_fetch(self, tool_input: Dict[str, Any]) -> str:
885
+ """Handle WebFetch tool - fetch content from a URL."""
886
+ url = tool_input.get('url', '')
887
+ prompt = tool_input.get('prompt', '')
888
+
889
+ if not url:
890
+ return "Error: No URL provided"
891
+
892
+ # Since we don't have actual web fetching capability, return a mock response
893
+ # In a real implementation, this would fetch the URL content and process it
894
+ return f"""WebFetch results for: {url}
895
+
896
+ ⚠️ Note: WebFetch is not fully implemented in this demo version.
897
+
898
+ In a production environment, this would:
899
+ • Fetch content from the specified URL
900
+ • Convert HTML to markdown if needed
901
+ • Process the content with the provided prompt: "{prompt}"
902
+ • Return the AI model's analysis of the fetched content
903
+ • Handle redirects and various content types
904
+
905
+ URL to fetch: {url}
906
+ Processing prompt: "{prompt}" """
907
+
847
908
  def process_query(self, user_input: str) -> str:
848
909
  """
849
910
  Main method to process user queries using the Anthropic API.
@@ -929,7 +990,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
929
990
  break
930
991
  except Exception as e:
931
992
  console.print(Panel(
932
- f"[bold red] Error:[/bold red] {str(e)}",
993
+ f"[bold red] Error:[/bold red] {str(e)}",
933
994
  border_style="red"
934
995
  ))
935
996
 
@@ -1007,7 +1068,7 @@ The following {len(TOOL_SCHEMAS)} tools are loaded and available:
1007
1068
  config_table = Table(show_header=False, box=None)
1008
1069
  config_table.add_column("Setting", style="yellow")
1009
1070
  config_table.add_column("Value", style="green")
1010
- config_table.add_row("API Key", " Set" if self.api_key else " Missing")
1071
+ config_table.add_row("API Key", " Set" if self.api_key else " Missing")
1011
1072
  config_table.add_row("Model", "claude-sonnet-4-20250514")
1012
1073
  config_table.add_row("Working Directory", self.working_dir)
1013
1074
  config_table.add_row("Git Repository", "Yes" if self.is_git_repo else "No")
@@ -1061,7 +1122,7 @@ def interactive(
1061
1122
  agent.interactive_mode()
1062
1123
  except ValueError as e:
1063
1124
  console.print(Panel(
1064
- f"[bold red] Configuration Error:[/bold red]\n{str(e)}\n\n" +
1125
+ f"[bold red] Configuration Error:[/bold red]\n{str(e)}\n\n" +
1065
1126
  "[yellow]To fix this:[/yellow]\n" +
1066
1127
  "1. Get your Anthropic API key from: https://console.anthropic.com/\n" +
1067
1128
  "2. Set environment variable: [cyan]export ANTHROPIC_API_KEY=your_key_here[/cyan]\n" +
@@ -1072,7 +1133,7 @@ def interactive(
1072
1133
  raise typer.Exit(1)
1073
1134
  except Exception as e:
1074
1135
  console.print(Panel(
1075
- f"[bold red] Error:[/bold red] {str(e)}",
1136
+ f"[bold red] Error:[/bold red] {str(e)}",
1076
1137
  border_style="red"
1077
1138
  ))
1078
1139
  raise typer.Exit(1)
@@ -1109,7 +1170,7 @@ def query(
1109
1170
 
1110
1171
  except ValueError as e:
1111
1172
  console.print(Panel(
1112
- f"[bold red] Configuration Error:[/bold red]\n{str(e)}\n\n" +
1173
+ f"[bold red] Configuration Error:[/bold red]\n{str(e)}\n\n" +
1113
1174
  "[yellow]To fix this:[/yellow]\n" +
1114
1175
  "1. Get your Anthropic API key from: https://console.anthropic.com/\n" +
1115
1176
  "2. Set environment variable: [cyan]export ANTHROPIC_API_KEY=your_key_here[/cyan]\n" +
@@ -1120,7 +1181,7 @@ def query(
1120
1181
  raise typer.Exit(1)
1121
1182
  except Exception as e:
1122
1183
  console.print(Panel(
1123
- f"[bold red] Error:[/bold red] {str(e)}",
1184
+ f"[bold red] Error:[/bold red] {str(e)}",
1124
1185
  border_style="red"
1125
1186
  ))
1126
1187
  raise typer.Exit(1)
@@ -1137,7 +1198,7 @@ def setup():
1137
1198
  system_info.add_row("Platform", os.uname().sysname if hasattr(os, 'uname') else 'unknown')
1138
1199
  system_info.add_row("Working Directory", os.getcwd())
1139
1200
  system_info.add_row("Git Repository", "Yes" if os.path.exists('.git') else "No")
1140
- system_info.add_row("API Key Status", " Set" if os.getenv('ANTHROPIC_API_KEY') else " Missing")
1201
+ system_info.add_row("API Key Status", " Set" if os.getenv('ANTHROPIC_API_KEY') else " Missing")
1141
1202
 
1142
1203
  # Setup instructions
1143
1204
  setup_instructions = """[bold yellow]1. Get your API key:[/bold yellow]
@@ -1152,7 +1213,10 @@ def setup():
1152
1213
  [bold yellow]4. Run the agent:[/bold yellow]
1153
1214
  [cyan]python claude_code_agent.py interactive[/cyan]
1154
1215
  or
1155
- [cyan]python claude_code_agent.py query "your question"[/cyan]"""
1216
+ [cyan]python claude_code_agent.py query "your question"[/cyan]
1217
+
1218
+ [bold cyan]5. Quick setup:[/bold cyan]
1219
+ [cyan]python claude_code_agent.py configure[/cyan]"""
1156
1220
 
1157
1221
  console.print(Panel(
1158
1222
  Columns([
@@ -1164,6 +1228,287 @@ def setup():
1164
1228
  padding=(1, 1)
1165
1229
  ))
1166
1230
 
1231
+ @app.command()
1232
+ def configure(
1233
+ reset: bool = typer.Option(False, "--reset", "-r", help="Reset configuration to defaults")
1234
+ ):
1235
+ """🔧 Interactive configuration wizard"""
1236
+ console = Console()
1237
+ config_file = Path.home() / ".claude_code_agent.json"
1238
+
1239
+ if reset:
1240
+ if config_file.exists():
1241
+ config_file.unlink()
1242
+ console.print("✓ [green]Configuration reset to defaults[/green]")
1243
+ return
1244
+
1245
+ console.print(Panel(
1246
+ "[bold blue]🔧 Claude Code Agent Configuration Wizard[/bold blue]\n" +
1247
+ "This will help you set up your preferences and API credentials.",
1248
+ title="Configuration Wizard",
1249
+ border_style="blue"
1250
+ ))
1251
+
1252
+ # Load existing config
1253
+ config = {}
1254
+ if config_file.exists():
1255
+ with open(config_file) as f:
1256
+ config = json.load(f)
1257
+ console.print(f"[dim]Found existing config at: {config_file}[/dim]")
1258
+
1259
+ # API Key configuration
1260
+ current_api_key = config.get('api_key') or os.getenv('ANTHROPIC_API_KEY')
1261
+ if current_api_key:
1262
+ console.print(f"✓ [green]API Key is already configured[/green]")
1263
+ if not Confirm.ask("Would you like to update it?"):
1264
+ api_key = current_api_key
1265
+ else:
1266
+ api_key = typer.prompt("Enter your Anthropic API key", hide_input=True)
1267
+ else:
1268
+ console.print("✗ [red]API Key not found[/red]")
1269
+ api_key = typer.prompt("Enter your Anthropic API key", hide_input=True)
1270
+
1271
+ # Model selection
1272
+ models = [
1273
+ "claude-sonnet-4-20250514",
1274
+ "claude-3-5-sonnet-20241022",
1275
+ "claude-3-opus-20240229",
1276
+ "claude-3-haiku-20240307"
1277
+ ]
1278
+ current_model = config.get('default_model', models[0])
1279
+ console.print(f"\nCurrent model: [cyan]{current_model}[/cyan]")
1280
+
1281
+ model_choice = typer.prompt(
1282
+ "Select model",
1283
+ type=typer.Choice(models),
1284
+ default=current_model
1285
+ )
1286
+
1287
+ # Timeout configuration
1288
+ current_timeout = config.get('default_timeout', 120)
1289
+ timeout = IntPrompt.ask(
1290
+ "Default timeout (seconds)",
1291
+ default=current_timeout,
1292
+ show_default=True
1293
+ )
1294
+
1295
+ # Tool preferences
1296
+ console.print("\n[bold]Tool Preferences:[/bold]")
1297
+ use_progress_bars = Confirm.ask(
1298
+ "Show progress bars for long operations?",
1299
+ default=config.get('use_progress_bars', True)
1300
+ )
1301
+
1302
+ auto_todos = Confirm.ask(
1303
+ "Automatically create todo lists for complex tasks?",
1304
+ default=config.get('auto_todos', True)
1305
+ )
1306
+
1307
+ syntax_highlighting = Confirm.ask(
1308
+ "Enable syntax highlighting for code files?",
1309
+ default=config.get('syntax_highlighting', True)
1310
+ )
1311
+
1312
+ # Save configuration
1313
+ new_config = {
1314
+ 'api_key': api_key,
1315
+ 'default_model': model_choice,
1316
+ 'default_timeout': timeout,
1317
+ 'use_progress_bars': use_progress_bars,
1318
+ 'auto_todos': auto_todos,
1319
+ 'syntax_highlighting': syntax_highlighting,
1320
+ 'configured_at': str(datetime.now())
1321
+ }
1322
+
1323
+ # Ensure config directory exists
1324
+ config_file.parent.mkdir(exist_ok=True)
1325
+
1326
+ with open(config_file, 'w') as f:
1327
+ json.dump(new_config, f, indent=2)
1328
+
1329
+ # Show summary
1330
+ summary_table = Table(title="Configuration Summary", show_header=True)
1331
+ summary_table.add_column("Setting", style="yellow")
1332
+ summary_table.add_column("Value", style="green")
1333
+
1334
+ summary_table.add_row("API Key", "✓ Configured" if api_key else "✗ Missing")
1335
+ summary_table.add_row("Model", model_choice)
1336
+ summary_table.add_row("Timeout", f"{timeout}s")
1337
+ summary_table.add_row("Progress Bars", "✓ Enabled" if use_progress_bars else "✗ Disabled")
1338
+ summary_table.add_row("Auto Todos", "✓ Enabled" if auto_todos else "✗ Disabled")
1339
+ summary_table.add_row("Syntax Highlighting", "✓ Enabled" if syntax_highlighting else "✗ Disabled")
1340
+ summary_table.add_row("Config File", str(config_file))
1341
+
1342
+ console.print(Panel(
1343
+ summary_table,
1344
+ title="✓ Configuration Complete",
1345
+ border_style="green"
1346
+ ))
1347
+
1348
+ @app.command()
1349
+ def browse():
1350
+ """📁 Interactive file browser"""
1351
+ console = Console()
1352
+ current_dir = Path.cwd()
1353
+
1354
+ while True:
1355
+ # List directory contents
1356
+ items = []
1357
+ if current_dir.parent != current_dir: # Not root
1358
+ items.append((".. (parent directory)", current_dir.parent, "dir"))
1359
+
1360
+ for item in sorted(current_dir.iterdir()):
1361
+ if item.is_dir():
1362
+ items.append((f"{item.name}/", item, "dir"))
1363
+ else:
1364
+ size = item.stat().st_size
1365
+ size_str = f"{size:,} bytes" if size < 1024 else f"{size//1024:,} KB"
1366
+ items.append((f"{item.name} ({size_str})", item, "file"))
1367
+
1368
+ # Create selection table
1369
+ table = Table(title=f"Directory: {current_dir}", show_header=True)
1370
+ table.add_column("#", style="dim", width=3)
1371
+ table.add_column("Type", width=4)
1372
+ table.add_column("Name", style="cyan")
1373
+
1374
+ for i, (display_name, path, item_type) in enumerate(items, 1):
1375
+ icon = "📁" if item_type == "dir" else "📄"
1376
+ table.add_row(str(i), icon, display_name)
1377
+
1378
+ console.clear()
1379
+ console.print(table)
1380
+
1381
+ # Get user choice
1382
+ console.print("\n[dim]Commands: [cyan]number[/cyan] to select, [cyan]q[/cyan] to quit, [cyan]r[/cyan] to read file[/dim]")
1383
+ choice = typer.prompt("Select item")
1384
+
1385
+ if choice.lower() == 'q':
1386
+ break
1387
+ elif choice.lower() == 'r':
1388
+ file_num = typer.prompt("File number to read", type=int)
1389
+ if 1 <= file_num <= len(items):
1390
+ selected_path = items[file_num - 1][1]
1391
+ if selected_path.is_file():
1392
+ try:
1393
+ # Read file directly without requiring API key
1394
+ with open(selected_path, 'r', encoding='utf-8') as f:
1395
+ lines = f.readlines()
1396
+
1397
+ # Format with line numbers
1398
+ formatted_lines = []
1399
+ for i, line in enumerate(lines[:100], 1): # Limit to 100 lines
1400
+ clean_line = line.rstrip('\n\r')
1401
+ if len(clean_line) > 2000:
1402
+ clean_line = clean_line[:2000] + "..."
1403
+ formatted_lines.append(f"{i:>5}→{clean_line}")
1404
+
1405
+ content = '\n'.join(formatted_lines)
1406
+ if len(lines) > 100:
1407
+ content += f"\n... (showing first 100 lines of {len(lines)} total)"
1408
+
1409
+ console.print(Panel(
1410
+ content,
1411
+ title=f"📄 {selected_path.name}",
1412
+ border_style="blue"
1413
+ ))
1414
+ typer.prompt("Press Enter to continue")
1415
+ except Exception as e:
1416
+ console.print(f"[red]✗ Error reading file: {e}[/red]")
1417
+ else:
1418
+ try:
1419
+ choice_num = int(choice)
1420
+ if 1 <= choice_num <= len(items):
1421
+ selected_path = items[choice_num - 1][1]
1422
+ if selected_path.is_dir():
1423
+ current_dir = selected_path
1424
+ else:
1425
+ console.print(f"Selected file: [cyan]{selected_path}[/cyan]")
1426
+ break
1427
+ except ValueError:
1428
+ console.print("[red]Invalid choice[/red]")
1429
+ typer.prompt("Press Enter to continue")
1430
+
1431
+ @app.command()
1432
+ def templates():
1433
+ """🎨 Manage project templates"""
1434
+ console = Console()
1435
+
1436
+ # Built-in templates
1437
+ builtin_templates = {
1438
+ "python-basic": {
1439
+ "description": "Basic Python project structure",
1440
+ "files": {
1441
+ "main.py": "#!/usr/bin/env python3\n\nif __name__ == '__main__':\n print('Hello, World!')\n",
1442
+ "requirements.txt": "",
1443
+ "README.md": "# Project\n\nDescription here.\n"
1444
+ }
1445
+ },
1446
+ "python-package": {
1447
+ "description": "Python package with setup.py",
1448
+ "files": {
1449
+ "setup.py": "from setuptools import setup, find_packages\n\nsetup(\n name='my-package',\n version='0.1.0',\n packages=find_packages(),\n)\n",
1450
+ "my_package/__init__.py": "",
1451
+ "my_package/main.py": "def main():\n pass\n",
1452
+ "requirements.txt": "",
1453
+ "README.md": "# My Package\n"
1454
+ }
1455
+ },
1456
+ "claude-agent": {
1457
+ "description": "Claude Code Agent project structure",
1458
+ "files": {
1459
+ "main.py": "#!/usr/bin/env python3\nfrom claude_code_agent import ClaudeCodeAgent\n\ndef main():\n agent = ClaudeCodeAgent()\n agent.interactive_mode()\n\nif __name__ == '__main__':\n main()\n",
1460
+ "requirements.txt": "anthropic>=0.25.0\ntyper>=0.12.0\nrich>=13.0.0\n",
1461
+ "README.md": "# Claude Agent Project\n\nA project using Claude Code Agent.\n",
1462
+ ".env.example": "ANTHROPIC_API_KEY=your_key_here\n"
1463
+ }
1464
+ }
1465
+ }
1466
+
1467
+ # List available templates
1468
+ table = Table(title="Available Templates", show_header=True)
1469
+ table.add_column("Name", style="cyan")
1470
+ table.add_column("Description", style="yellow")
1471
+ table.add_column("Files", style="green")
1472
+
1473
+ for name, template in builtin_templates.items():
1474
+ file_count = len(template["files"])
1475
+ table.add_row(name, template["description"], f"{file_count} files")
1476
+
1477
+ console.print(table)
1478
+
1479
+ template_name = typer.prompt("Select template to create")
1480
+ if template_name not in builtin_templates:
1481
+ console.print(f"[red]✗ Template '{template_name}' not found[/red]")
1482
+ return
1483
+
1484
+ project_name = typer.prompt("Project name")
1485
+ project_dir = Path.cwd() / project_name
1486
+
1487
+ if project_dir.exists():
1488
+ if not Confirm.ask(f"Directory {project_name} exists. Continue?"):
1489
+ return
1490
+
1491
+ project_dir.mkdir(exist_ok=True)
1492
+ template = builtin_templates[template_name]
1493
+
1494
+ # Create files with progress bar
1495
+ with Progress() as progress:
1496
+ task = progress.add_task("Creating project...", total=len(template["files"]))
1497
+
1498
+ for file_path, content in template["files"].items():
1499
+ full_path = project_dir / file_path
1500
+ full_path.parent.mkdir(parents=True, exist_ok=True)
1501
+ full_path.write_text(content)
1502
+ progress.advance(task)
1503
+
1504
+ console.print(Panel(
1505
+ f"✓ [green]Project '{project_name}' created successfully![/green]\n" +
1506
+ f"Location: [cyan]{project_dir}[/cyan]\n" +
1507
+ f"Template: [yellow]{template_name}[/yellow]",
1508
+ title="Project Created",
1509
+ border_style="green"
1510
+ ))
1511
+
1167
1512
  def main():
1168
1513
  """Main entry point - delegate to Typer app."""
1169
1514
  app()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.9.85",
3
+ "version": "1.9.87",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -322,7 +322,8 @@ def ssh_container_function(ssh_password=None, repo_url=None, repo_name=None, set
322
322
  # Process complete lines immediately
323
323
  while '\n' in stdout_buffer:
324
324
  line, stdout_buffer = stdout_buffer.split('\n', 1)
325
- print(line, flush=True) # Force immediate flush
325
+ # Add subtle color to agent output for better readability
326
+ print(line, flush=True) # Use default terminal colors
326
327
  elif stream == process.stderr:
327
328
  chunk = stream.read(1024)
328
329
  if chunk is not None and chunk:
@@ -816,32 +817,32 @@ def show_usage_examples():
816
817
 
817
818
  print("Basic Container Creation with Agent")
818
819
  print("┌────────────────────────────────────────────────────────────────────────┐")
819
- print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
820
+ print("│ gitarsenal --gpu A10G --repo https://github.com/username/repo.git │")
820
821
  print("│ # Agent will intelligently clone and setup the repository │")
821
822
  print("└────────────────────────────────────────────────────────────────────────┘\n")
822
823
 
823
824
  print("With Persistent Storage")
824
825
  print("┌────────────────────────────────────────────────────────────────────────────────────┐")
825
- print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git \\ │")
826
+ print("│ gitarsenal --gpu A10G --repo https://github.com/username/repo.git \\ │")
826
827
  print("│ --volume-name my-persistent-volume │")
827
828
  print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
828
829
 
829
830
  print("With Multiple GPUs")
830
831
  print("┌────────────────────────────────────────────────────────────────────────────────────┐")
831
832
  print("│ gitarsenal --gpu A100-80GB --gpu-count 4 \\ │")
832
- print("│ --repo-url https://github.com/username/repo.git │")
833
+ print("│ --repo https://github.com/username/repo.git │")
833
834
  print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
834
835
 
835
836
  print("Intelligent Repository Setup (default)")
836
837
  print("┌────────────────────────────────────────────────────────────────────────────────────┐")
837
- print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
838
+ print("│ gitarsenal --gpu A10G --repo https://github.com/username/repo.git │")
838
839
  print("│ # Agent analyzes repo and sets up environment automatically │")
839
840
  print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
840
841
 
841
842
  print("With Manual Setup Commands (Advanced)")
842
843
  print("┌────────────────────────────────────────────────────────────────────────────────────┐")
843
844
  print("│ gitarsenal --gpu A10G --setup-commands \"pip install torch\" \"python train.py\" │")
844
- print("│ # Only use when not providing --repo-url (bypasses Agent) │")
845
+ print("│ # Only use when not providing --repo (bypasses Agent) │")
845
846
  print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
846
847
 
847
848
  print("Development Mode (Skip Authentication)")
@@ -863,16 +864,16 @@ def show_usage_examples():
863
864
  print(" • Without --gpu: Shows interactive GPU selection menu")
864
865
  print()
865
866
  print("Repository Setup Behavior:")
866
- print(" • With --repo-url Agent intelligently clones and sets up repository")
867
- print(" • Without --repo-url: Manual container setup (no automatic repository setup)")
868
- print(" • Legacy --setup-commands: Only used when --repo-url not provided")
867
+ print(" • With --repo Agent intelligently clones and sets up repository")
868
+ print(" • Without --repo: Manual container setup (no automatic repository setup)")
869
+ print(" • Legacy --setup-commands: Only used when --repo not provided")
869
870
  print()
870
871
  print("Examples:")
871
872
  print(" # Intelligent repository setup (recommended):")
872
- print(" gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git")
873
+ print(" gitarsenal --gpu A10G --repo https://github.com/username/repo.git")
873
874
  print()
874
875
  print(" # Development mode (skip authentication):")
875
- print(" gitarsenal --skip-auth --gpu A10G --repo-url https://github.com/username/repo.git")
876
+ print(" gitarsenal --skip-auth --gpu A10G --repo https://github.com/username/repo.git")
876
877
  print()
877
878
  print(" # Manual setup (advanced users):")
878
879
  print(" gitarsenal --gpu A10G --setup-commands \"pip install torch\" \"python train.py\"")