gitarsenal-cli 1.9.75 → 1.9.76

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-15T09:24:56.539Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
1
+ {"created":"2025-08-17T05:50:53.850Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
package/Step ADDED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.9.75",
3
+ "version": "1.9.76",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -0,0 +1,239 @@
1
+ import subprocess
2
+ import time
3
+ import secrets
4
+ import string
5
+ import modal
6
+ import sys
7
+ import os
8
+
9
+ def generate_random_password(length=16):
10
+ """Generate a random password for SSH access"""
11
+ alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
12
+ password = ''.join(secrets.choice(alphabet) for i in range(length))
13
+ return password
14
+
15
+ # Image building
16
+ print("Building Modal image...")
17
+ # base_image = modal.Image.from_registry("nvidia/cuda:12.4.0-devel-ubuntu22.04", add_python="3.11")
18
+ base_image = modal.Image.debian_slim()
19
+
20
+ ssh_image = (
21
+ base_image
22
+ .apt_install("openssh-server", "sudo", "curl", "wget", "vim", "htop", "git", "python3", "python3-pip")
23
+ .uv_pip_install("uv", "modal", "gitingest", "requests", "openai", "anthropic", "exa-py")
24
+ .run_commands(
25
+ "mkdir -p /var/run/sshd",
26
+ "mkdir -p /root/.ssh",
27
+ "chmod 700 /root/.ssh",
28
+ "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config",
29
+ "sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config",
30
+ "sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config",
31
+ "echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config",
32
+ "echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config",
33
+ "ssh-keygen -A",
34
+ "echo 'export PS1=\"\\[\\e[1;32m\\]modal:\\[\\e[1;34m\\]\\w\\[\\e[0m\\]$ \"' >> /root/.bashrc",
35
+ "mkdir -p /python",
36
+ )
37
+ )
38
+
39
+ print("✅ SSH image built successfully")
40
+
41
+ # Create app
42
+ app = modal.App("test_container", image=ssh_image)
43
+ print("✅ Created app successfully")
44
+
45
+ @app.function(gpu="A10G", timeout=3600, memory=32768)
46
+ def get_ssh_connection(
47
+ test_data=None,
48
+ repo_info=None,
49
+ setup_commands=None,
50
+ env_vars=None,
51
+ credentials=None,
52
+ debug_config=None
53
+ ):
54
+ """Test complex remote parameter passing that causes segfault"""
55
+
56
+ print("🧪 TESTING COMPLEX REMOTE PARAMETER PASSING")
57
+ print("=" * 60)
58
+
59
+ # Test complex parameter handling
60
+ if test_data:
61
+ print(f"📦 Received extra_data: {type(test_data)} with {len(test_data) if hasattr(test_data, '__len__') else 'N/A'} items")
62
+ if isinstance(test_data, dict):
63
+ for key, value in test_data.items():
64
+ print(f" • {key}: {type(value)} = {str(value)[:100]}...")
65
+
66
+ if repo_info:
67
+ print(f"📂 Received repo_info: {repo_info}")
68
+
69
+ if setup_commands:
70
+ print(f"⚙️ Received {len(setup_commands)} setup commands:")
71
+ for i, cmd in enumerate(setup_commands[:3]):
72
+ print(f" {i+1}. {cmd}")
73
+ if len(setup_commands) > 3:
74
+ print(f" ... and {len(setup_commands) - 3} more")
75
+
76
+ if env_vars:
77
+ print(f"🔧 Received {len(env_vars)} environment variables:")
78
+ for key, value in list(env_vars.items())[:3]:
79
+ masked_value = str(value)[:8] + "..." if len(str(value)) > 8 else str(value)
80
+ print(f" • {key} = {masked_value}")
81
+
82
+ if credentials:
83
+ print(f"🔐 Received {len(credentials)} credentials")
84
+ for key in list(credentials.keys())[:3]:
85
+ print(f" • {key}: [MASKED]")
86
+
87
+ if debug_config:
88
+ print(f"🐛 Received debug_config: {debug_config}")
89
+
90
+ print("=" * 60)
91
+
92
+ # Generate SSH password
93
+ password = generate_random_password()
94
+
95
+ # Set root password
96
+ subprocess.run(["bash", "-c", f"echo 'root:{password}' | chpasswd"], check=True)
97
+
98
+ # Start SSH server
99
+ ssh_process = subprocess.Popen(["/usr/sbin/sshd", "-D"])
100
+ time.sleep(2)
101
+
102
+ # Test CUDA
103
+ cuda_info = {}
104
+ nvidia_result = subprocess.run(["nvidia-smi"], capture_output=True, text=True, timeout=30)
105
+ cuda_info["nvidia_smi_return_code"] = nvidia_result.returncode
106
+ cuda_info["nvidia_smi_output"] = nvidia_result.stdout[:500] if nvidia_result.stdout else "No output"
107
+
108
+ # nvcc_result = subprocess.run(["nvcc", "--version"], capture_output=True, text=True, timeout=30)
109
+ # cuda_info["nvcc_return_code"] = nvcc_result.returncode
110
+ # cuda_info["nvcc_output"] = nvcc_result.stdout[:500] if nvcc_result.stdout else "No output"
111
+
112
+ # Forward SSH port and return connection info
113
+ with modal.forward(port=22, unencrypted=True) as tunnel:
114
+ hostname, port = tunnel.tcp_socket
115
+
116
+ return {
117
+ "status": "success",
118
+ "hostname": hostname,
119
+ "port": port,
120
+ "password": password,
121
+ "cuda_info": cuda_info,
122
+ "ssh_command": f"ssh -p {port} root@{hostname}",
123
+ "parameters_received": {
124
+ "test_data": bool(test_data),
125
+ "repo_info": bool(repo_info),
126
+ "setup_commands": len(setup_commands) if setup_commands else 0,
127
+ "env_vars": len(env_vars) if env_vars else 0,
128
+ "credentials": len(credentials) if credentials else 0,
129
+ "debug_config": bool(debug_config),
130
+ }
131
+ }
132
+
133
+ if __name__ == "__main__":
134
+ print("Starting CUDA container setup...")
135
+
136
+ # Check Modal authentication
137
+ modal_toml = os.path.expanduser("~/.modal.toml")
138
+ modal_dir = os.path.expanduser("~/.modal/")
139
+
140
+ if os.path.exists(modal_toml):
141
+ print("✓ Modal configuration found")
142
+ elif os.path.exists(modal_dir):
143
+ print("✓ Modal configuration found")
144
+ else:
145
+ print("⚠️ Warning: No Modal configuration found")
146
+
147
+ print("Initializing Modal app...")
148
+ print("Building container image (this may take a while on first run)...")
149
+
150
+ try:
151
+ with app.run():
152
+ print("Getting SSH connection info...")
153
+
154
+ # THE COMPLEX DATA THAT CAUSES SEGFAULT
155
+ # Prepare test data to send to remote function
156
+ test_data = {
157
+ "message": "Hello from local machine!",
158
+ "number": 42,
159
+ "list": [1, 2, 3, "test"],
160
+ "nested": {
161
+ "key1": "value1",
162
+ "key2": 123
163
+ }
164
+ }
165
+
166
+ setup_commands = [
167
+ "apt-get update",
168
+ "pip install numpy",
169
+ "echo 'Setup complete'"
170
+ ]
171
+
172
+ env_vars = {
173
+ "CUSTOM_VAR": "test_value",
174
+ "DEBUG_MODE": "true",
175
+ "API_URL": "https://api.example.com"
176
+ }
177
+
178
+ repo_info = {
179
+ "url": "https://github.com/test/repo.git",
180
+ "branch": "main"
181
+ }
182
+
183
+ credentials = {
184
+ "openai_api_key": "sk-test123456789abcdef",
185
+ "anthropic_api_key": "sk-ant-api-key-987654321",
186
+ "github_token": "ghp_github_token_123456",
187
+ "modal_token": "ak-modal-token-abcdef"
188
+ }
189
+
190
+ debug_config = {
191
+ "log_level": "INFO",
192
+ "enable_trace": True,
193
+ "output_file": "/tmp/debug.log",
194
+ "max_retries": 3
195
+ }
196
+
197
+ model_settings = {
198
+ "model_name": "gpt-4",
199
+ "temperature": 0.7,
200
+ "max_tokens": 2048,
201
+ "timeout": 30,
202
+ "provider": "openai"
203
+ }
204
+
205
+ print(f"📦 Sending complex data to remote function:")
206
+ print(f" • test_data: {len(test_data)} items (includes 1KB string)")
207
+ print(f" • repo_info: {len(repo_info)} items")
208
+ print(f" • setup_commands: {len(setup_commands)} commands")
209
+ print(f" • environment_vars: {len(env_vars)} variables")
210
+ print(f" • credentials: {len(credentials)} credentials")
211
+ print(f" • debug_config: {len(debug_config)} debug settings")
212
+ print("\n🚨 This should trigger the segfault...")
213
+ print()
214
+
215
+ # This call should cause the segfault
216
+ result = get_ssh_connection.remote(
217
+ test_data=test_data,
218
+ repo_info=repo_info,
219
+ setup_commands=setup_commands,
220
+ env_vars=env_vars,
221
+ credentials=credentials,
222
+ debug_config=debug_config
223
+ )
224
+
225
+ # If we get here, it didn't segfault
226
+ print("\n🎉 NO SEGFAULT! Function completed successfully")
227
+ print(f"SSH Command: {result['ssh_command']}")
228
+ print(f"Password: {result['password']}")
229
+
230
+ # Keep container running
231
+ while True:
232
+ time.sleep(60)
233
+ print("Container still running... (Press Ctrl+C to stop)")
234
+
235
+ except Exception as e:
236
+ print(f"\n💥 Error occurred: {e}")
237
+ print("This might be the segfault or another error")
238
+
239
+ print("Container stopped")
@@ -0,0 +1,290 @@
1
+ import subprocess
2
+ import time
3
+ import secrets
4
+ import string
5
+ import modal
6
+ import sys
7
+
8
+ def generate_random_password(length=16):
9
+ """Generate a random password for SSH access"""
10
+ alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
11
+ password = ''.join(secrets.choice(alphabet) for i in range(length))
12
+ return password
13
+
14
+ base_image = modal.Image.from_registry("nvidia/cuda:12.4.0-devel-ubuntu22.04", add_python="3.11")
15
+
16
+ ssh_image = (
17
+ base_image
18
+ .apt_install("openssh-server", "sudo", "curl", "wget", "vim", "htop", "git", "python3", "python3-pip")
19
+ .uv_pip_install("uv", "modal", "gitingest", "requests", "openai", "anthropic", "exa-py")
20
+ .run_commands(
21
+ "mkdir -p /var/run/sshd",
22
+ "mkdir -p /root/.ssh",
23
+ "chmod 700 /root/.ssh",
24
+ "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config",
25
+ "sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config",
26
+ "sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config",
27
+ "echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config",
28
+ "echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config",
29
+ "ssh-keygen -A",
30
+ "echo 'export PS1=\"\\[\\e[1;32m\\]modal:\\[\\e[1;34m\\]\\w\\[\\e[0m\\]$ \"' >> /root/.bashrc",
31
+ "mkdir -p /python",
32
+ )
33
+ )
34
+ print("✅ SSH image built successfully")
35
+
36
+
37
+ # Create app with image passed directly (THIS IS THE KEY CHANGE)
38
+ print("🔍 Testing app creation...")
39
+ app = modal.App("test_container", image=ssh_image) # Pass image here
40
+ print("✅ Created app successfully")
41
+
42
+ # Define the SSH container function (remove image from decorator)
43
+ @app.function(
44
+ timeout= 3600, # Convert to seconds
45
+ gpu="A10G", # Use the user-selected GPU type and count
46
+ serialized=True,
47
+ # volumes=volumes_config if volumes_config else None,
48
+ memory=32768,
49
+ )
50
+ def start_ssh():
51
+ # Generate SSH password
52
+ password = generate_random_password()
53
+
54
+ # Set root password
55
+ subprocess.run(["bash", "-c", f"echo 'root:{password}' | chpasswd"], check=True)
56
+
57
+ # Start SSH server
58
+ ssh_process = subprocess.Popen(["/usr/sbin/sshd", "-D"])
59
+ time.sleep(2)
60
+
61
+ # Test CUDA
62
+ cuda_info = {}
63
+ nvidia_result = subprocess.run(["nvidia-smi"], capture_output=True, text=True, timeout=30)
64
+ cuda_info["nvidia_smi_output"] = nvidia_result.stdout if nvidia_result.stdout else "No output"
65
+
66
+ nvcc_result = subprocess.run(["nvcc", "--version"], capture_output=True, text=True, timeout=30)
67
+ cuda_info["nvcc_output"] = nvcc_result.stdout if nvcc_result.stdout else "No output"
68
+
69
+ # Forward SSH port
70
+ with modal.forward(port=22, unencrypted=True) as tunnel:
71
+ hostname, port = tunnel.tcp_socket
72
+
73
+ # Return connection info to local terminal
74
+ connection_info = {
75
+ "hostname": hostname,
76
+ "port": port,
77
+ "password": password,
78
+ "cuda_info": cuda_info,
79
+ "status": "success"
80
+ }
81
+
82
+ # Keep alive with periodic status updates
83
+ counter = 0
84
+ while True:
85
+ counter += 1
86
+ time.sleep(60)
87
+
88
+ @app.function(gpu="A10G", timeout=3600)
89
+ def get_ssh_connection(test_data=None, setup_commands=None, env_vars=None, repo_info=None,
90
+ credentials=None, debug_config=None, model_settings=None):
91
+ """Get SSH connection info and test remote parameter passing"""
92
+
93
+ print("🧪 REMOTE FUNCTION - Testing parameter passing...")
94
+ print("=" * 50)
95
+
96
+ if test_data:
97
+ print(f"📦 Received test_data: {type(test_data)}")
98
+ if isinstance(test_data, dict):
99
+ for key, value in test_data.items():
100
+ print(f" • {key}: {value}")
101
+ elif isinstance(test_data, list):
102
+ print(f" • List with {len(test_data)} items: {test_data}")
103
+ else:
104
+ print(f" • Value: {test_data}")
105
+
106
+ if setup_commands:
107
+ print(f"⚙️ Received {len(setup_commands)} setup commands:")
108
+ for i, cmd in enumerate(setup_commands):
109
+ print(f" {i+1}. {cmd}")
110
+
111
+ if env_vars:
112
+ print(f"🔧 Received {len(env_vars)} environment variables:")
113
+ for key, value in env_vars.items():
114
+ print(f" • {key} = {value}")
115
+
116
+ if repo_info:
117
+ print(f"📂 Received repo_info: {repo_info}")
118
+
119
+ if credentials:
120
+ print(f"🔐 Received {len(credentials)} credentials:")
121
+ for key, value in credentials.items():
122
+ # Mask sensitive data
123
+ masked_value = value[:8] + "..." if len(str(value)) > 8 else "***"
124
+ print(f" • {key}: {masked_value}")
125
+
126
+ if debug_config:
127
+ print(f"🐛 Received debug_config:")
128
+ for key, value in debug_config.items():
129
+ print(f" • {key}: {value}")
130
+
131
+ if model_settings:
132
+ print(f"🤖 Received model_settings:")
133
+ for key, value in model_settings.items():
134
+ print(f" • {key}: {value}")
135
+
136
+ print("=" * 50)
137
+
138
+ # Generate SSH password
139
+ password = generate_random_password()
140
+
141
+ # Set root password
142
+ subprocess.run(["bash", "-c", f"echo 'root:{password}' | chpasswd"], check=True)
143
+
144
+ # Start SSH server
145
+ ssh_process = subprocess.Popen(["/usr/sbin/sshd", "-D"])
146
+ time.sleep(2)
147
+
148
+ # Test CUDA
149
+ cuda_info = {}
150
+ nvidia_result = subprocess.run(["nvidia-smi"], capture_output=True, text=True, timeout=30)
151
+ cuda_info["nvidia_smi_return_code"] = nvidia_result.returncode
152
+ cuda_info["nvidia_smi_output"] = nvidia_result.stdout[:500] if nvidia_result.stdout else "No output"
153
+
154
+ nvcc_result = subprocess.run(["nvcc", "--version"], capture_output=True, text=True, timeout=30)
155
+ cuda_info["nvcc_return_code"] = nvcc_result.returncode
156
+ cuda_info["nvcc_output"] = nvcc_result.stdout[:500] if nvcc_result.stdout else "No output"
157
+
158
+ # Forward SSH port and return connection info
159
+ with modal.forward(port=22, unencrypted=True) as tunnel:
160
+ hostname, port = tunnel.tcp_socket
161
+
162
+ # Return connection info immediately
163
+ return {
164
+ "status": "success",
165
+ "hostname": hostname,
166
+ "port": port,
167
+ "password": password,
168
+ "cuda_info": cuda_info,
169
+ "ssh_command": f"ssh -p {port} root@{hostname}"
170
+ }
171
+
172
+ if __name__ == "__main__":
173
+ print("Starting CUDA container setup...")
174
+
175
+ # Check Modal authentication files
176
+ import os
177
+ modal_toml = os.path.expanduser("~/.modal.toml")
178
+ modal_dir = os.path.expanduser("~/.modal/")
179
+
180
+ if os.path.exists(modal_toml):
181
+ print("✓ Modal configuration found")
182
+ elif os.path.exists(modal_dir):
183
+ print("✓ Modal configuration found")
184
+ else:
185
+ print("⚠️ Warning: No Modal configuration found")
186
+
187
+ print("Initializing Modal app...")
188
+ print("Building container image (this may take a while on first run)...")
189
+
190
+ with app.run():
191
+ print("Getting SSH connection info...")
192
+
193
+ # Prepare test data to send to remote function
194
+ test_data = {
195
+ "message": "Hello from local machine!",
196
+ "number": 42,
197
+ "list": [1, 2, 3, "test"],
198
+ "nested": {
199
+ "key1": "value1",
200
+ "key2": 123
201
+ }
202
+ }
203
+
204
+ setup_commands = [
205
+ "apt-get update",
206
+ "pip install numpy",
207
+ "echo 'Setup complete'"
208
+ ]
209
+
210
+ env_vars = {
211
+ "CUSTOM_VAR": "test_value",
212
+ "DEBUG_MODE": "true",
213
+ "API_URL": "https://api.example.com"
214
+ }
215
+
216
+ repo_info = {
217
+ "url": "https://github.com/test/repo.git",
218
+ "branch": "main"
219
+ }
220
+
221
+ credentials = {
222
+ "openai_api_key": "sk-test123456789abcdef",
223
+ "anthropic_api_key": "sk-ant-api-key-987654321",
224
+ "github_token": "ghp_github_token_123456",
225
+ "modal_token": "ak-modal-token-abcdef"
226
+ }
227
+
228
+ debug_config = {
229
+ "log_level": "INFO",
230
+ "enable_trace": True,
231
+ "output_file": "/tmp/debug.log",
232
+ "max_retries": 3
233
+ }
234
+
235
+ model_settings = {
236
+ "model_name": "gpt-4",
237
+ "temperature": 0.7,
238
+ "max_tokens": 2048,
239
+ "timeout": 30,
240
+ "provider": "openai"
241
+ }
242
+
243
+ print("📦 Sending test parameters to remote function:")
244
+ print(f" • test_data: {len(test_data)} items")
245
+ print(f" • setup_commands: {len(setup_commands)} commands")
246
+ print(f" • env_vars: {len(env_vars)} variables")
247
+ print(f" • repo_info: {repo_info}")
248
+ print(f" • credentials: {len(credentials)} items")
249
+ print(f" • debug_config: {len(debug_config)} items")
250
+ print(f" • model_settings: {len(model_settings)} items")
251
+ print()
252
+
253
+ # Get connection info with test parameters
254
+ result = get_ssh_connection.remote(
255
+ test_data=test_data,
256
+ setup_commands=setup_commands,
257
+ env_vars=env_vars,
258
+ repo_info=repo_info,
259
+ credentials=credentials,
260
+ debug_config=debug_config,
261
+ model_settings=model_settings
262
+ )
263
+
264
+ if result and "error" not in result:
265
+ print("\n" + "="*60)
266
+ print("🚀 CUDA CONTAINER READY!")
267
+ print("="*60)
268
+ print(f"SSH Command: {result['ssh_command']}")
269
+ print(f"Password: {result['password']}")
270
+ print("="*60)
271
+
272
+ print("\n📊 CUDA Information:")
273
+ if "nvidia_smi_output" in result["cuda_info"]:
274
+ print("nvidia-smi output:")
275
+ print(result["cuda_info"]["nvidia_smi_output"])
276
+ if "nvcc_output" in result["cuda_info"]:
277
+ print("\nnvcc output:")
278
+ print(result["cuda_info"]["nvcc_output"])
279
+
280
+ print("\n⚠️ Note: Container will stay running until you stop this script")
281
+ print("Press Ctrl+C to stop the container")
282
+
283
+ # Keep the local script running to maintain the container
284
+ while True:
285
+ time.sleep(60)
286
+ print("Container still running... (Press Ctrl+C to stop)")
287
+ else:
288
+ print(f"\n❌ Error: {result.get('error', 'Unknown error')}")
289
+
290
+ print("Container stopped")