gitarsenal-cli 1.9.66 → 1.9.68

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-14T20:40:04.217Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
1
+ {"created":"2025-08-15T04:06:48.506Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.9.66",
3
+ "version": "1.9.68",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -203,8 +203,8 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
203
203
  volume_name=None, timeout_minutes=60, ssh_password=None, interactive=False, gpu_count=1):
204
204
  """Create a Modal SSH container with GPU support and intelligent repository setup.
205
205
 
206
- When repo_url is provided, uses Claude Code Agent for intelligent repository setup.
207
- The setup_commands parameter is maintained for backwards compatibility but ignored when using Claude Code Agent.
206
+ When repo_url is provided, uses Agent for intelligent repository setup.
207
+ The setup_commands parameter is maintained for backwards compatibility but ignored when using Agent.
208
208
  """
209
209
 
210
210
  # Use interactive mode if specified
@@ -388,29 +388,12 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
388
388
  # Set up a nice bash prompt
389
389
  "echo 'export PS1=\"\\[\\e[1;32m\\]modal:\\[\\e[1;34m\\]\\w\\[\\e[0m\\]$ \"' >> /root/.bashrc",
390
390
 
391
- # Create directories for Claude Code Agent
392
- "mkdir -p /python/kill_claude/tools /python/kill_claude/prompts",
391
+ # Create base directories (subdirectories will be created automatically when mounting)
392
+ "mkdir -p /python",
393
393
  )
394
- # Mount all local files (must be done after run_commands)
395
- .add_local_file(os.path.join(current_dir, "shell.py"), "/python/shell.py") # Mount shell.py
396
- .add_local_file(os.path.join(current_dir, "command_manager.py"), "/python/command_manager.py") # Mount command_manager.py
397
- .add_local_file(os.path.join(current_dir, "fetch_modal_tokens.py"), "/python/fetch_modal_tokens.py") # Mount fetch_modal_token.py
398
- .add_local_file(os.path.join(current_dir, "llm_debugging.py"), "/python/llm_debugging.py") # Mount llm_debugging.py
399
- .add_local_file(os.path.join(current_dir, "credentials_manager.py"), "/python/credentials_manager.py") # Mount credentials_manager.py
400
- # Mount Claude Code Agent and its dependencies
401
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "claude_code_agent.py"), "/python/kill_claude/claude_code_agent.py")
402
- # Mount the tools and prompts directories manually with key files
403
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "__init__.py"), "/python/kill_claude/tools/__init__.py")
404
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "bash_tool.py"), "/python/kill_claude/tools/bash_tool.py")
405
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "read_tool.py"), "/python/kill_claude/tools/read_tool.py")
406
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "write_tool.py"), "/python/kill_claude/tools/write_tool.py")
407
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "ls_tool.py"), "/python/kill_claude/tools/ls_tool.py")
408
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "edit_tool.py"), "/python/kill_claude/tools/edit_tool.py")
409
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "grep_tool.py"), "/python/kill_claude/tools/grep_tool.py")
410
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "glob_tool.py"), "/python/kill_claude/tools/glob_tool.py")
411
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "tools", "todo_write_tool.py"), "/python/kill_claude/tools/todo_write_tool.py")
412
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "prompts", "claude-code-system-prompt.md"), "/python/kill_claude/prompts/claude-code-system-prompt.md")
413
- .add_local_file(os.path.join(gitarsenal_root, "kill_claude", "prompts", "claude-code-agent-prompts.md"), "/python/kill_claude/prompts/claude-code-agent-prompts.md")
394
+ # Mount entire directories instead of individual files
395
+ .add_local_dir(current_dir, "/python", ignore=lambda p: not p.name.endswith('.py')) # Mount all Python files from current directory
396
+ .add_local_dir(os.path.join(gitarsenal_root, "kill_claude"), "/python/kill_claude") # Mount entire kill_claude directory with all subdirectories
414
397
 
415
398
  )
416
399
  print("āœ… SSH image built successfully")
@@ -437,7 +420,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
437
420
  volumes=volumes_config if volumes_config else None,
438
421
  )
439
422
  def ssh_container_function(ssh_password=None, repo_url=None, repo_name=None, setup_commands=None, openai_api_key=None, anthropic_api_key=None, stored_credentials=None):
440
- """Start SSH container with password authentication and intelligent repository setup using Claude Code Agent."""
423
+ """Start SSH container with password authentication and intelligent repository setup using Agent."""
441
424
  import subprocess
442
425
  import time
443
426
  import os
@@ -514,11 +497,11 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
514
497
  # Start SSH service
515
498
  subprocess.run(["service", "ssh", "start"], check=True)
516
499
 
517
- # Use Claude Code Agent for intelligent repository setup
500
+ # Use Agent for intelligent repository setup
518
501
  if repo_url:
519
- print("šŸ¤– Using Claude Code Agent for intelligent repository setup...")
502
+ print("šŸ¤– Using Agent for intelligent repository setup...")
520
503
 
521
- # Set up environment variables for the Claude Code Agent
504
+ # Set up environment variables for the Agent
522
505
  if openai_api_key:
523
506
  os.environ['OPENAI_API_KEY'] = openai_api_key
524
507
  if anthropic_api_key:
@@ -537,13 +520,13 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
537
520
 
538
521
  if not anthropic_api_key:
539
522
  print("āš ļø No Anthropic API key found in stored credentials")
540
- print("šŸ’” Claude Code Agent will require an Anthropic API key for operation")
523
+ print("šŸ’” Agent will require an Anthropic API key for operation")
541
524
 
542
525
  try:
543
- print("šŸ”§ Running Claude Code Agent for repository setup...")
526
+ print("šŸ”§ Running Agent for repository setup...")
544
527
 
545
528
  print("\n" + "="*80)
546
- print("šŸ¤– CLAUDE CODE AGENT REPOSITORY SETUP")
529
+ print("šŸ¤– AGENT REPOSITORY SETUP")
547
530
  print("="*80)
548
531
  print(f"Repository: {repo_url}")
549
532
  print(f"Working Directory: /root")
@@ -551,36 +534,51 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
551
534
  print(f"Available Credentials: {len(stored_credentials)} items")
552
535
  print("="*80 + "\n")
553
536
 
554
- # Call Claude Code Agent directly as subprocess
555
- claude_prompt = f"clone and setup {repo_url}"
556
- print(f"šŸš€ Executing: python /python/kill_claude/claude_code_agent.py \"{claude_prompt}\"")
537
+ # Call Agent directly as subprocess with real-time output
538
+ claude_prompt = f"clone, setup and run {repo_url}"
539
+ print(f"šŸš€ Executing the task: \"{claude_prompt}\"")
540
+ print("\n" + "="*60)
541
+ print("šŸŽ‰ AGENT OUTPUT (LIVE)")
542
+ print("="*60)
557
543
 
558
- result = subprocess.run(
544
+ # Use Popen for real-time output streaming
545
+ process = subprocess.Popen(
559
546
  ["python", "/python/kill_claude/claude_code_agent.py", claude_prompt],
560
547
  cwd="/root",
561
- capture_output=True,
548
+ stdout=subprocess.PIPE,
549
+ stderr=subprocess.STDOUT, # Merge stderr into stdout
562
550
  text=True,
563
- timeout=600 # 10 minute timeout
551
+ bufsize=1, # Line buffered
552
+ universal_newlines=True
564
553
  )
565
554
 
566
- print("\n" + "="*60)
567
- print("šŸŽ‰ CLAUDE CODE AGENT OUTPUT")
568
- print("="*60)
569
-
570
- if result.stdout:
571
- print("šŸ“‹ STDOUT:")
572
- print(result.stdout)
555
+ # Stream output in real-time
556
+ try:
557
+ while True:
558
+ output = process.stdout.readline()
559
+ if output == '' and process.poll() is not None:
560
+ break
561
+ if output:
562
+ print(output.rstrip())
573
563
 
574
- if result.stderr:
575
- print("āš ļø STDERR:")
576
- print(result.stderr)
564
+ # Wait for process to complete and get return code
565
+ return_code = process.wait(timeout=600) # 10 minute timeout
577
566
 
578
- if result.returncode == 0:
579
- print("āœ… Claude Code Agent completed successfully!")
580
- else:
581
- print(f"āš ļø Claude Code Agent exited with code: {result.returncode}")
582
-
583
- print("="*60)
567
+ print("\n" + "="*60)
568
+ if return_code == 0:
569
+ print("āœ… Agent completed successfully!")
570
+ else:
571
+ print(f"āš ļø Agent exited with code: {return_code}")
572
+ print("="*60)
573
+
574
+ except subprocess.TimeoutExpired:
575
+ print("\nāš ļø Agent timed out after 10 minutes")
576
+ process.kill()
577
+ process.wait()
578
+ except Exception as stream_error:
579
+ print(f"\nāš ļø Error streaming output: {stream_error}")
580
+ process.kill()
581
+ process.wait()
584
582
 
585
583
  except Exception as e:
586
584
  print(f"āŒ Error during repository setup: {e}")
@@ -626,11 +624,11 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
626
624
  with app.run():
627
625
  # Get the API key from environment
628
626
  api_key = os.environ.get("OPENAI_API_KEY")
629
- print(f"šŸ” API key: {api_key}")
627
+ # print(f"šŸ” API key: {api_key}")
630
628
 
631
629
  # Get stored credentials from local file
632
630
  stored_credentials = get_stored_credentials()
633
- print(f"šŸ” Stored credentials: {stored_credentials}")
631
+ # print(f"šŸ” Stored credentials: {stored_credentials}")
634
632
  if stored_credentials:
635
633
  print(f"šŸ” Found {len(stored_credentials)} stored credentials to send to container")
636
634
  else:
@@ -1093,10 +1091,10 @@ def show_usage_examples():
1093
1091
  print("│ gitarsenal --auth # Interactive auth management │")
1094
1092
  print("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n")
1095
1093
 
1096
- print("Basic Container Creation with Claude Code Agent")
1094
+ print("Basic Container Creation with Agent")
1097
1095
  print("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”")
1098
1096
  print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
1099
- print("│ # Claude Code Agent will intelligently clone and setup the repository │")
1097
+ print("│ # Agent will intelligently clone and setup the repository │")
1100
1098
  print("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n")
1101
1099
 
1102
1100
  print("With Persistent Storage")
@@ -1114,13 +1112,13 @@ def show_usage_examples():
1114
1112
  print("Intelligent Repository Setup (default)")
1115
1113
  print("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”")
1116
1114
  print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
1117
- print("│ # Claude Code Agent analyzes repo and sets up environment automatically │")
1115
+ print("│ # Agent analyzes repo and sets up environment automatically │")
1118
1116
  print("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n")
1119
1117
 
1120
1118
  print("With Manual Setup Commands (Advanced)")
1121
1119
  print("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”")
1122
1120
  print("│ gitarsenal --gpu A10G --setup-commands \"pip install torch\" \"python train.py\" │")
1123
- print("│ # Only use when not providing --repo-url (bypasses Claude Code Agent) │")
1121
+ print("│ # Only use when not providing --repo-url (bypasses Agent) │")
1124
1122
  print("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n")
1125
1123
 
1126
1124
  print("Development Mode (Skip Authentication)")
@@ -1142,7 +1140,7 @@ def show_usage_examples():
1142
1140
  print(" • Without --gpu: Shows interactive GPU selection menu")
1143
1141
  print()
1144
1142
  print("Repository Setup Behavior:")
1145
- print(" • With --repo-url: Claude Code Agent intelligently clones and sets up repository")
1143
+ print(" • With --repo-url Agent intelligently clones and sets up repository")
1146
1144
  print(" • Without --repo-url: Manual container setup (no automatic repository setup)")
1147
1145
  print(" • Legacy --setup-commands: Only used when --repo-url not provided")
1148
1146
  print()
@@ -1816,9 +1814,9 @@ if __name__ == "__main__":
1816
1814
  parser.add_argument('--volume-name', type=str, help='Name of the Modal volume for persistent storage')
1817
1815
  parser.add_argument('--timeout', type=int, default=60, help='Container timeout in minutes (default: 60)')
1818
1816
  parser.add_argument('--ssh-password', type=str, help='SSH password (random if not provided)')
1819
- parser.add_argument('--use-api', action='store_true', help='[DEPRECATED] Fetch setup commands from original API (use --repo-url for Claude Code Agent instead)')
1820
- parser.add_argument('--use-gitingest', action='store_true', default=True, help='[DEPRECATED] Use gitingest approach (Claude Code Agent is now used when --repo-url is provided)')
1821
- parser.add_argument('--no-gitingest', action='store_true', help='[DEPRECATED] Disable gitingest approach (no longer needed with Claude Code Agent)')
1817
+ parser.add_argument('--use-api', action='store_true', help='[DEPRECATED] Fetch setup commands from original API (use --repo-url for Agent instead)')
1818
+ parser.add_argument('--use-gitingest', action='store_true', default=True, help='[DEPRECATED] Use gitingest approach (Agent is now used when --repo-url is provided)')
1819
+ parser.add_argument('--no-gitingest', action='store_true', help='[DEPRECATED] Disable gitingest approach (no longer needed with Agent)')
1822
1820
  parser.add_argument('--show-examples', action='store_true', help='Show usage examples')
1823
1821
  parser.add_argument('--list-gpus', action='store_true', help='List available GPU types with their specifications')
1824
1822
  parser.add_argument('--interactive', action='store_true', help='Run in interactive mode with prompts')
@@ -1951,7 +1949,7 @@ if __name__ == "__main__":
1951
1949
  print(f"GPU Type: {gpu_type}")
1952
1950
  print(f"Volume: {args.volume_name or 'None'}")
1953
1951
  if args.repo_url:
1954
- print("Repository Setup: Claude Code Agent (intelligent)")
1952
+ print("Repository Setup: Agent (intelligent)")
1955
1953
  elif args.use_api:
1956
1954
  print("Setup Commands: Auto-detect from repository")
1957
1955
  elif args.setup_commands:
@@ -2037,13 +2035,13 @@ if __name__ == "__main__":
2037
2035
  args.use_gitingest = use_gitingest
2038
2036
 
2039
2037
  try:
2040
- # Setup commands are no longer used when repo_url is provided (Claude Code Agent handles setup)
2038
+ # Setup commands are no longer used when repo_url is provided ( Agent handles setup)
2041
2039
  setup_commands = args.setup_commands or []
2042
2040
 
2043
2041
  # Repository setup approach
2044
2042
  if args.repo_url:
2045
- print("šŸ¤– Repository setup will be handled by Claude Code Agent in container")
2046
- setup_commands = [] # Claude Code Agent will handle setup intelligently
2043
+ print("šŸ¤– Repository setup will be handled by Agent in container")
2044
+ setup_commands = [] # Agent will handle setup intelligently
2047
2045
  else:
2048
2046
  print("āš ļø No repository URL provided - setup commands may be needed manually")
2049
2047