gitarsenal-cli 1.9.64 โ†’ 1.9.65

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-14T08:14:09.791Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
1
+ {"created":"2025-08-14T08:39:09.974Z","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.64",
3
+ "version": "1.9.65",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -197,7 +197,7 @@ def get_stored_credentials():
197
197
 
198
198
  # Now modify the create_modal_ssh_container function to use the PersistentShell
199
199
  def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_commands=None,
200
- volume_name=None, timeout_minutes=60, ssh_password=None, interactive=False):
200
+ volume_name=None, timeout_minutes=60, ssh_password=None, interactive=False, gpu_count=1):
201
201
  """Create a Modal SSH container with GPU support and tunneling"""
202
202
 
203
203
  # Use interactive mode if specified
@@ -295,7 +295,18 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
295
295
  gpu_type = 'A10G'
296
296
 
297
297
  gpu_spec = gpu_configs[gpu_type]
298
- print(f"๐Ÿš€ Creating SSH container with {gpu_spec['gpu']} GPU ({gpu_spec['memory']}GB VRAM)")
298
+
299
+ # Configure GPU string for Modal (support multiple GPUs)
300
+ if gpu_count > 1:
301
+ modal_gpu_spec = f"{gpu_spec['gpu']}:{gpu_count}"
302
+ total_memory = gpu_spec['memory'] * gpu_count
303
+ print(f"๐Ÿš€ Creating SSH container with {gpu_count}x {gpu_spec['gpu']} GPUs ({total_memory}GB total VRAM)")
304
+ else:
305
+ modal_gpu_spec = gpu_spec['gpu']
306
+ print(f"๐Ÿš€ Creating SSH container with {gpu_spec['gpu']} GPU ({gpu_spec['memory']}GB VRAM)")
307
+
308
+ # Store the modal GPU specification for the decorator
309
+ gpu_spec['modal_gpu'] = modal_gpu_spec
299
310
 
300
311
  # Generate or use provided SSH password
301
312
  if not ssh_password:
@@ -394,7 +405,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
394
405
  # Define the SSH container function (remove image from decorator)
395
406
  @app.function(
396
407
  timeout=timeout_minutes * 60, # Convert to seconds
397
- gpu=gpu_spec['gpu'], # Use the user-selected GPU type
408
+ gpu=gpu_spec['modal_gpu'], # Use the user-selected GPU type and count
398
409
  serialized=True,
399
410
  volumes=volumes_config if volumes_config else None,
400
411
  )
@@ -1262,6 +1273,12 @@ def show_usage_examples():
1262
1273
  print("โ”‚ --volume-name my-persistent-volume โ”‚")
1263
1274
  print("โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜\n")
1264
1275
 
1276
+ print("With Multiple GPUs")
1277
+ print("โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”")
1278
+ print("โ”‚ gitarsenal --gpu A100-80GB --gpu-count 4 \\ โ”‚")
1279
+ print("โ”‚ --repo-url https://github.com/username/repo.git โ”‚")
1280
+ print("โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜\n")
1281
+
1265
1282
  print("With GitIngest API (default)")
1266
1283
  print("โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”")
1267
1284
  print("โ”‚ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git โ”‚")
@@ -1286,6 +1303,7 @@ def show_usage_examples():
1286
1303
 
1287
1304
  print("Available GPU Options:")
1288
1305
  print(" T4, L4, A10G, A100-40GB, A100-80GB, L40S, H100, H200, B200")
1306
+ print(" Use --gpu-count to specify multiple GPUs (1-8)")
1289
1307
  print()
1290
1308
  print("Authentication Behavior:")
1291
1309
  print(" โ€ข First time: Interactive registration/login required")
@@ -1977,6 +1995,7 @@ if __name__ == "__main__":
1977
1995
  parser.add_argument('--proxy-url', help='URL of the proxy server')
1978
1996
  parser.add_argument('--proxy-api-key', help='API key for the proxy server')
1979
1997
  parser.add_argument('--gpu', default='A10G', help='GPU type to use')
1998
+ parser.add_argument('--gpu-count', type=int, default=1, help='Number of GPUs to use (default: 1)')
1980
1999
  parser.add_argument('--repo-url', help='Repository URL')
1981
2000
 
1982
2001
  # Authentication-related arguments
@@ -2022,6 +2041,8 @@ if __name__ == "__main__":
2022
2041
  print("โ”‚ 9. B200 โ”‚ 141GB โ”‚")
2023
2042
  print("โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜")
2024
2043
  print("Use --gpu <type> to specify a GPU type")
2044
+ print("Use --gpu-count <number> to specify multiple GPUs (1-8)")
2045
+ print("\nExample: --gpu A100-80GB --gpu-count 4 (for 4x A100-80GB GPUs)")
2025
2046
  sys.exit(0)
2026
2047
 
2027
2048
  # If no arguments or only --show-examples is provided, show usage examples
@@ -2091,7 +2112,11 @@ if __name__ == "__main__":
2091
2112
  # Display configuration after GPU selection
2092
2113
  print("\n๐Ÿ“‹ Container Configuration:")
2093
2114
  print(f"Repository URL: {args.repo_url or 'Not specified'}")
2094
- print(f"GPU Type: {gpu_type}")
2115
+ gpu_count = getattr(args, 'gpu_count', 1)
2116
+ if gpu_count > 1:
2117
+ print(f"GPU Type: {gpu_count}x {gpu_type}")
2118
+ else:
2119
+ print(f"GPU Type: {gpu_type}")
2095
2120
  print(f"Volume: {args.volume_name or 'None'}")
2096
2121
  if args.use_api:
2097
2122
  print("Setup Commands: Auto-detect from repository")
@@ -2142,6 +2167,24 @@ if __name__ == "__main__":
2142
2167
  print("\n๐Ÿ›‘ Setup cancelled.")
2143
2168
  sys.exit(1)
2144
2169
 
2170
+ # Ask about GPU count if not specified
2171
+ gpu_count = getattr(args, 'gpu_count', 1)
2172
+ if not hasattr(args, 'gpu_count') or args.gpu_count == 1:
2173
+ try:
2174
+ gpu_count_input = input("? How many GPUs do you need? (1-8, default: 1): ").strip()
2175
+ if gpu_count_input:
2176
+ try:
2177
+ gpu_count = int(gpu_count_input)
2178
+ if gpu_count < 1 or gpu_count > 8:
2179
+ print("โš ๏ธ GPU count must be between 1 and 8. Using default: 1")
2180
+ gpu_count = 1
2181
+ except ValueError:
2182
+ print("โš ๏ธ Invalid GPU count. Using default: 1")
2183
+ gpu_count = 1
2184
+ except KeyboardInterrupt:
2185
+ print("\n๐Ÿ›‘ Setup cancelled.")
2186
+ sys.exit(1)
2187
+
2145
2188
  # Ask about setup commands
2146
2189
  use_gitingest = args.use_gitingest and not args.no_gitingest
2147
2190
  if not args.use_api and not args.setup_commands and not args.setup_commands_json:
@@ -2156,6 +2199,7 @@ if __name__ == "__main__":
2156
2199
  # Update args with interactive values
2157
2200
  args.repo_url = repo_url
2158
2201
  args.volume_name = volume_name
2202
+ args.gpu_count = gpu_count
2159
2203
  args.use_gitingest = use_gitingest
2160
2204
 
2161
2205
  try:
@@ -2256,14 +2300,11 @@ if __name__ == "__main__":
2256
2300
  volume_name=args.volume_name,
2257
2301
  timeout_minutes=args.timeout,
2258
2302
  ssh_password=ssh_password,
2259
- interactive=args.interactive
2303
+ interactive=args.interactive,
2304
+ gpu_count=getattr(args, 'gpu_count', 1)
2260
2305
  )
2261
2306
  except KeyboardInterrupt:
2262
- # print("\n\n๐Ÿ›‘ Execution interrupted")
2263
- # print("๐Ÿงน Cleaning up resources...")
2264
2307
  cleanup_modal_token()
2265
2308
  sys.exit(1)
2266
2309
  except Exception as e:
2267
- # print(f"\nโŒ Error: {e}")
2268
- # print("๐Ÿงน Cleaning up resources...")
2269
2310
  cleanup_modal_token()