gitarsenal-cli 1.1.10 → 1.1.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -46,7 +46,7 @@ The Modal proxy service allows users to access Modal services (like GPU-accelera
46
46
 
47
47
  This will provide you with a public URL that you can share with users.
48
48
 
49
- Current ngrok URL: `https://cf487e07fd45.ngrok-free.app`
49
+ Current ngrok URL: `https://932ffd63ad3d.ngrok-free.app`
50
50
 
51
51
  ## Client-Side Setup
52
52
 
@@ -56,7 +56,7 @@ The Modal proxy service allows users to access Modal services (like GPU-accelera
56
56
  ```
57
57
 
58
58
  You'll be prompted to enter:
59
- - The proxy URL (the default is now set to `https://cf487e07fd45.ngrok-free.app`)
59
+ - The proxy URL (the default is now set to `https://932ffd63ad3d.ngrok-free.app`)
60
60
  - Your API key
61
61
 
62
62
  2. **Check proxy service status**:
@@ -0,0 +1,82 @@
1
+ # Modal Token Setup Solution
2
+
3
+ This document explains how the Modal token setup solution works in GitArsenal CLI.
4
+
5
+ ## Problem
6
+
7
+ The GitArsenal CLI was failing with errors like:
8
+
9
+ ```
10
+ 🔍 MODAL_TOKEN_ID not found in environment.
11
+ ❌ No Modal token found in environment variables
12
+ ❌ Modal token file not found
13
+ ❌ Could not find Modal token in any location
14
+ ```
15
+
16
+ This happened because the Modal token was not being properly set in the environment variables.
17
+
18
+ ## Solution
19
+
20
+ We implemented a comprehensive solution to automatically find and set up the Modal token from various sources:
21
+
22
+ 1. Created a `setup_modal_token.py` module that:
23
+ - Checks for the token in environment variables (MODAL_TOKEN_ID and MODAL_TOKEN)
24
+ - Checks for the token in GitArsenal credentials file (~/.gitarsenal/credentials.json)
25
+ - Checks for the token in Modal token file (~/.modal/token.json)
26
+ - Sets the token in both MODAL_TOKEN_ID and MODAL_TOKEN environment variables
27
+
28
+ 2. Modified key files to use this module:
29
+ - `gitarsenal.py` - Main CLI entry point
30
+ - `modal_proxy_service.py` - Modal proxy service
31
+ - `test_modalSandboxScript.py` - Modal sandbox script
32
+
33
+ 3. Created a wrapper script `run_with_modal_token.py` that:
34
+ - Sets up the Modal token using the setup_modal_token module
35
+ - Runs a specified command with the token properly set in the environment
36
+
37
+ ## Usage
38
+
39
+ ### Running Commands with Modal Token
40
+
41
+ Use the wrapper script to run any command that requires Modal authentication:
42
+
43
+ ```bash
44
+ python run_with_modal_token.py <command> [args...]
45
+ ```
46
+
47
+ Example:
48
+
49
+ ```bash
50
+ python run_with_modal_token.py python modal_proxy_service.py
51
+ ```
52
+
53
+ ### Setting Up Modal Token
54
+
55
+ If you need to set up the Modal token manually:
56
+
57
+ ```bash
58
+ python setup_modal_token.py
59
+ ```
60
+
61
+ This will prompt you for the token if it's not found in any of the sources.
62
+
63
+ ### Adding Modal Token to GitArsenal Credentials
64
+
65
+ You can also add the Modal token to GitArsenal credentials:
66
+
67
+ ```bash
68
+ ./gitarsenal.py credentials set modal_token
69
+ ```
70
+
71
+ ## How It Works
72
+
73
+ 1. The `setup_modal_token.py` module checks multiple sources for the Modal token:
74
+ - Environment variables (MODAL_TOKEN_ID and MODAL_TOKEN)
75
+ - GitArsenal credentials file (~/.gitarsenal/credentials.json)
76
+ - Modal token file (~/.modal/token.json)
77
+
78
+ 2. When it finds a token, it sets both MODAL_TOKEN_ID and MODAL_TOKEN environment variables.
79
+
80
+ 3. The modified files import and use this module to ensure the token is set before any Modal operations.
81
+
82
+ 4. The wrapper script makes it easy to run any command with the token properly set up.
package/python/README.md CHANGED
@@ -198,7 +198,7 @@ Proxy configuration is stored in `~/.gitarsenal/proxy_config.json` with similar
198
198
 
199
199
  ### Modal Authentication Issues
200
200
 
201
- If you see errors like "Token missing" or "Could not authenticate client":
201
+ If you see errors like "Token missing", "Could not authenticate client", or "MODAL_TOKEN_ID not found in environment":
202
202
 
203
203
  1. Ensure Modal is installed:
204
204
  ```bash
@@ -215,6 +215,16 @@ If you see errors like "Token missing" or "Could not authenticate client":
215
215
  ./gitarsenal.py credentials set modal_token
216
216
  ```
217
217
 
218
+ 4. Use the wrapper script to run commands with the Modal token properly set up:
219
+ ```bash
220
+ python run_with_modal_token.py python modal_proxy_service.py
221
+ ```
222
+
223
+ The wrapper script automatically sets up the Modal token from one of these sources:
224
+ - Environment variables (MODAL_TOKEN_ID or MODAL_TOKEN)
225
+ - GitArsenal credentials file (~/.gitarsenal/credentials.json)
226
+ - Modal token file (~/.modal/token.json)
227
+
218
228
  ### Proxy Service Issues
219
229
 
220
230
  If you're having issues with the proxy service:
@@ -12,6 +12,16 @@ import subprocess
12
12
  import json
13
13
  from pathlib import Path
14
14
 
15
+ # Import the Modal token setup module
16
+ try:
17
+ from setup_modal_token import setup_modal_token
18
+ # Set up Modal token at import time
19
+ setup_modal_token()
20
+ except ImportError:
21
+ print("⚠️ Warning: setup_modal_token module not found. Modal authentication may fail.")
22
+ except Exception as e:
23
+ print(f"⚠️ Warning: Error setting up Modal token: {e}")
24
+
15
25
  def check_modal_auth():
16
26
  """Check if Modal is authenticated and guide user if not"""
17
27
  try:
@@ -74,7 +84,7 @@ def check_proxy_config():
74
84
  print("⚠️ Modal proxy not configured. Setting up with default values...")
75
85
 
76
86
  # Set default proxy URL to the ngrok URL
77
- default_url = "https://cf487e07fd45.ngrok-free.app"
87
+ default_url = "https://932ffd63ad3d.ngrok-free.app"
78
88
 
79
89
  # Update configuration with default URL
80
90
  config["proxy_url"] = default_url
@@ -32,7 +32,7 @@ class GitArsenalProxyClient:
32
32
 
33
33
  # If still no URL, use default
34
34
  if not self.base_url:
35
- self.base_url = "https://cf487e07fd45.ngrok-free.app" # Default to new ngrok URL
35
+ self.base_url = "https://932ffd63ad3d.ngrok-free.app" # Default to new ngrok URL
36
36
 
37
37
  # Warn if no API key
38
38
  if not self.api_key:
@@ -42,8 +42,21 @@ logger = logging.getLogger("modal-proxy")
42
42
  app = Flask(__name__)
43
43
  CORS(app) # Enable CORS for all routes
44
44
 
45
+ # Try to set up Modal token using our setup module
46
+ try:
47
+ from setup_modal_token import setup_modal_token
48
+ token_setup_success = setup_modal_token()
49
+ if token_setup_success:
50
+ logger.info("Modal token set up successfully using setup_modal_token module")
51
+ else:
52
+ logger.warning("setup_modal_token module failed to set up Modal token")
53
+ except ImportError:
54
+ logger.warning("setup_modal_token module not found")
55
+ except Exception as e:
56
+ logger.error(f"Error using setup_modal_token module: {e}")
57
+
45
58
  # Get Modal token from environment variable
46
- MODAL_TOKEN = os.environ.get("MODAL_TOKEN")
59
+ MODAL_TOKEN = os.environ.get("MODAL_TOKEN") or os.environ.get("MODAL_TOKEN_ID")
47
60
  if not MODAL_TOKEN:
48
61
  logger.error("MODAL_TOKEN environment variable is not set!")
49
62
 
@@ -75,19 +88,34 @@ def generate_random_password(length=16):
75
88
 
76
89
  def setup_modal_auth():
77
90
  """Set up Modal authentication using the server's token"""
78
- if not MODAL_TOKEN:
91
+ # Try to use our setup_modal_token module first
92
+ try:
93
+ from setup_modal_token import setup_modal_token
94
+ if setup_modal_token():
95
+ logger.info("Modal token set up successfully using setup_modal_token module")
96
+ return True
97
+ except ImportError:
98
+ logger.info("setup_modal_token module not found, falling back to direct setup")
99
+ except Exception as e:
100
+ logger.warning(f"Error using setup_modal_token module: {e}, falling back to direct setup")
101
+
102
+ # Fall back to direct token setup if the module approach failed
103
+ token = MODAL_TOKEN or os.environ.get("MODAL_TOKEN") or os.environ.get("MODAL_TOKEN_ID")
104
+
105
+ if not token:
79
106
  logger.error("Cannot set up Modal authentication: No token provided")
80
107
  return False
81
108
 
82
109
  try:
83
- # Set the token in the environment
84
- os.environ["MODAL_TOKEN_ID"] = MODAL_TOKEN
110
+ # Set the token in the environment (both variables to be safe)
111
+ os.environ["MODAL_TOKEN_ID"] = token
112
+ os.environ["MODAL_TOKEN"] = token
85
113
 
86
114
  # Try to set the token using Modal CLI
87
115
  try:
88
116
  import subprocess
89
117
  result = subprocess.run(
90
- ["modal", "token", "set", MODAL_TOKEN],
118
+ ["modal", "token", "set", token],
91
119
  capture_output=True, text=True, check=False
92
120
  )
93
121
  if result.returncode == 0:
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Run With Modal Token - Wrapper Script
4
+
5
+ This script sets up the Modal token in the environment and then runs a specified command.
6
+ It's useful for running commands that need Modal authentication without modifying them.
7
+
8
+ Usage:
9
+ python run_with_modal_token.py <command> [args...]
10
+
11
+ Example:
12
+ python run_with_modal_token.py python modal_proxy_service.py
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ import subprocess
18
+ from setup_modal_token import setup_modal_token
19
+
20
+ def main():
21
+ # Set up Modal token
22
+ if not setup_modal_token():
23
+ print("❌ Failed to set up Modal token")
24
+ print("Please set up your credentials with:")
25
+ print(" ./gitarsenal.py credentials set modal_token")
26
+ sys.exit(1)
27
+
28
+ # Check if a command was provided
29
+ if len(sys.argv) < 2:
30
+ print("❌ No command provided")
31
+ print(f"Usage: {sys.argv[0]} <command> [args...]")
32
+ sys.exit(1)
33
+
34
+ # Get the command and arguments
35
+ cmd = sys.argv[1]
36
+ args = sys.argv[2:]
37
+
38
+ # Print what we're about to run
39
+ print(f"🚀 Running command with Modal token: {cmd} {' '.join(args)}")
40
+
41
+ # Run the command
42
+ try:
43
+ result = subprocess.run([cmd] + args)
44
+ sys.exit(result.returncode)
45
+ except Exception as e:
46
+ print(f"❌ Error running command: {e}")
47
+ sys.exit(1)
48
+
49
+ if __name__ == "__main__":
50
+ main()
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Modal Token Setup Script for GitArsenal CLI
4
+
5
+ This script ensures that the Modal token is properly set up in the environment
6
+ before running any Modal operations. It checks for the token in various locations
7
+ and sets the required environment variables.
8
+ """
9
+
10
+ import os
11
+ import sys
12
+ from pathlib import Path
13
+ import logging
14
+
15
+ # Configure logging
16
+ logging.basicConfig(
17
+ level=logging.INFO,
18
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
19
+ )
20
+ logger = logging.getLogger("modal-setup")
21
+
22
+ def setup_modal_token():
23
+ """
24
+ Set up Modal token in the environment.
25
+
26
+ Checks for the token in:
27
+ 1. Environment variables (MODAL_TOKEN_ID and MODAL_TOKEN)
28
+ 2. GitArsenal credentials file
29
+ 3. Modal token file (~/.modal/token.json)
30
+
31
+ Returns:
32
+ bool: True if token was set up successfully, False otherwise
33
+ """
34
+ # Check if token is already in environment
35
+ if os.environ.get("MODAL_TOKEN_ID") and os.environ.get("MODAL_TOKEN"):
36
+ logger.info("Modal token already set in environment")
37
+ return True
38
+
39
+ # Try to get token from GitArsenal credentials
40
+ token = get_token_from_gitarsenal()
41
+ if token:
42
+ os.environ["MODAL_TOKEN_ID"] = token
43
+ os.environ["MODAL_TOKEN"] = token
44
+ logger.info("Modal token set from GitArsenal credentials")
45
+ return True
46
+
47
+ # Try to get token from Modal token file
48
+ token = get_token_from_modal_file()
49
+ if token:
50
+ os.environ["MODAL_TOKEN_ID"] = token
51
+ os.environ["MODAL_TOKEN"] = token
52
+ logger.info("Modal token set from Modal token file")
53
+ return True
54
+
55
+ # If we got here, no token was found
56
+ logger.error("No Modal token found in any location")
57
+ return False
58
+
59
+ def get_token_from_gitarsenal():
60
+ """Get Modal token from GitArsenal credentials file"""
61
+ try:
62
+ from credentials_manager import CredentialsManager
63
+ credentials_manager = CredentialsManager()
64
+ token = credentials_manager.get_modal_token()
65
+ if token:
66
+ logger.info("Found Modal token in GitArsenal credentials")
67
+ return token
68
+ except ImportError:
69
+ logger.warning("Could not import CredentialsManager")
70
+ except Exception as e:
71
+ logger.warning(f"Error getting token from GitArsenal credentials: {e}")
72
+
73
+ return None
74
+
75
+ def get_token_from_modal_file():
76
+ """Get Modal token from Modal token file"""
77
+ try:
78
+ import json
79
+ token_file = Path.home() / ".modal" / "token.json"
80
+
81
+ if not token_file.exists():
82
+ logger.warning(f"Modal token file not found at {token_file}")
83
+ return None
84
+
85
+ with open(token_file, 'r') as f:
86
+ token_data = json.load(f)
87
+
88
+ # The token file contains both token_id and token
89
+ token_id = token_data.get("token_id")
90
+ if token_id:
91
+ logger.info("Found token_id in Modal token file")
92
+ return token_id
93
+ except Exception as e:
94
+ logger.warning(f"Error reading Modal token file: {e}")
95
+
96
+ return None
97
+
98
+ if __name__ == "__main__":
99
+ if setup_modal_token():
100
+ print("✅ Modal token set up successfully")
101
+ sys.exit(0)
102
+ else:
103
+ print("❌ Failed to set up Modal token")
104
+ print("Please set up your credentials with:")
105
+ print(" ./gitarsenal.py credentials set modal_token")
106
+ sys.exit(1)
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  import sys
3
- import modal
4
3
  import time
5
4
  import subprocess
6
5
  import json
@@ -11,6 +10,18 @@ import requests
11
10
  import secrets
12
11
  import string
13
12
 
13
+ # Try to set up Modal token before importing modal
14
+ try:
15
+ from setup_modal_token import setup_modal_token
16
+ setup_modal_token()
17
+ except ImportError:
18
+ print("⚠️ Warning: setup_modal_token module not found. Modal authentication may fail.")
19
+ except Exception as e:
20
+ print(f"⚠️ Warning: Error setting up Modal token: {e}")
21
+
22
+ # Import modal after token setup
23
+ import modal
24
+
14
25
  def handle_interactive_input(prompt, is_password=False):
15
26
  """Handle interactive input from the user with optional password masking"""
16
27
  print("\n" + "="*60)