gitarsenal-cli 1.9.55 → 1.9.58

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-12T17:14:40.503Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
1
+ {"created":"2025-08-12T19:09:30.955Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
package/bin/gitarsenal.js CHANGED
@@ -376,27 +376,42 @@ function getDefaultVolumeName(repoUrl) {
376
376
  // Remove trailing slash
377
377
  if (url.endsWith('/')) url = url.slice(0, -1);
378
378
 
379
- let repoName = null;
379
+ // Prefer everything after github.com/ (owner/repo)
380
+ if (url.toLowerCase().includes('github.com')) {
381
+ let after = url;
382
+ const markerIndex = after.toLowerCase().indexOf('github.com');
383
+ after = after.slice(markerIndex + 'github.com'.length); // e.g., '/owner/repo.git' or ':owner/repo.git'
384
+ // Strip leading separators
385
+ while (after.startsWith('/') || after.startsWith(':')) after = after.slice(1);
386
+ // Trim query/fragment if present
387
+ const stopIdx = Math.min(
388
+ ...[after.indexOf('?'), after.indexOf('#')].map(i => (i === -1 ? after.length : i))
389
+ );
390
+ after = after.slice(0, stopIdx);
391
+ // Remove .git suffix
392
+ if (after.toLowerCase().endsWith('.git')) after = after.slice(0, -4);
393
+ // Sanitize: replace '/' with '_' first, then keep docker-friendly chars
394
+ let vol = after.replace(/[\\/]+/g, '_')
395
+ .replace(/[^a-zA-Z0-9_.-]/g, '_')
396
+ .replace(/_+/g, '_')
397
+ .toLowerCase();
398
+ return vol || 'repo';
399
+ }
380
400
 
381
- // Try URL parsing for http/https
401
+ // Fallback behavior for non-GitHub URLs: use last path segment (repo name)
402
+ let repoName = null;
382
403
  try {
383
404
  const u = new URL(url);
384
405
  const parts = u.pathname.split('/').filter(Boolean);
385
406
  repoName = parts[parts.length - 1] || null;
386
407
  } catch (_) {
387
- // Fallback for SSH-like URLs (e.g., git@github.com:user/repo.git)
388
408
  const parts = url.split(/[/:]/).filter(Boolean);
389
409
  repoName = parts[parts.length - 1] || null;
390
410
  }
391
411
 
392
412
  if (!repoName) return 'repo';
413
+ if (repoName.toLowerCase().endsWith('.git')) repoName = repoName.slice(0, -4);
393
414
 
394
- // Strip .git suffix if present
395
- if (repoName.toLowerCase().endsWith('.git')) {
396
- repoName = repoName.slice(0, -4);
397
- }
398
-
399
- // Sanitize to a Docker-friendly volume name
400
415
  repoName = repoName
401
416
  .replace(/[^a-zA-Z0-9_.-]/g, '_')
402
417
  .replace(/_+/g, '_')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.9.55",
3
+ "version": "1.9.58",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -365,7 +365,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
365
365
  "python3", "python3-pip", "build-essential", "tmux", "screen", "nano",
366
366
  "gpg", "ca-certificates", "software-properties-common"
367
367
  )
368
- .uv_pip_install("uv", "modal", "requests", "openai", "anthropic", "exa-py") # Remove problematic CUDA packages
368
+ .uv_pip_install("uv", "modal", "gitingest", "requests", "openai", "anthropic", "exa-py") # Remove problematic CUDA packages
369
369
  .run_commands(
370
370
  # Create SSH directory
371
371
  "mkdir -p /var/run/sshd",
@@ -498,6 +498,9 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
498
498
  # Start SSH service
499
499
  subprocess.run(["service", "ssh", "start"], check=True)
500
500
 
501
+ # Fetch setup commands from API if repo_url is provided and no commands exist
502
+ setup_commands = get_setup_commands_from_gitingest(repo_url)
503
+
501
504
  # Preprocess setup commands using LLM to inject credentials
502
505
  if setup_commands:
503
506
  print(f"🔧 Preprocessing {len(setup_commands)} setup commands with LLM to inject credentials...")
@@ -836,7 +839,7 @@ def fetch_setup_commands_from_api(repo_url):
836
839
 
837
840
  # Define API endpoints to try in order - using only online endpoints
838
841
  api_endpoints = [
839
- "https://www.gitarsenal.dev/api/analyze-with-gitingest" # Working endpoint with www prefix
842
+ "https://www.gitarsenal.dev/api/gitingest-setup-commands" # Working endpoint with www prefix
840
843
  ]
841
844
 
842
845
  print(f"🔍 Fetching setup commands from API for repository: {repo_url}")
@@ -871,12 +874,6 @@ def fetch_setup_commands_from_api(repo_url):
871
874
  # Use gitingest CLI tool to analyze the repository directly from URL
872
875
  print(f"🔎 Running GitIngest analysis on {repo_url}...")
873
876
 
874
- # Based on the help output, the correct format is:
875
- # gitingest [OPTIONS] [SOURCE]
876
- # With options:
877
- # -o, --output TEXT Output file path
878
- # --format TEXT Output format (json)
879
-
880
877
  # Run gitingest command with proper parameters
881
878
  gitingest_run_cmd = [
882
879
  gitingest_cmd_name,
@@ -1620,8 +1617,6 @@ def get_setup_commands_from_gitingest(repo_url):
1620
1617
  api_endpoints = [
1621
1618
  "https://www.gitarsenal.dev/api/gitingest-setup-commands",
1622
1619
  "https://gitarsenal.dev/api/gitingest-setup-commands",
1623
- "https://www.gitarsenal.dev/api/analyze-with-gitingest",
1624
- "http://localhost:3000/api/gitingest-setup-commands"
1625
1620
  ]
1626
1621
 
1627
1622
  # Generate basic gitingest data