gitarsenal-cli 1.5.3 ā 1.5.5
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/README.md +86 -41
- package/package.json +1 -1
- package/python/__pycache__/fetch_modal_tokens.cpython-313.pyc +0 -0
- package/python/test_modalSandboxScript.py +3 -7
- package/python/MODAL_PROXY_README.md +0 -145
- package/python/README.md +0 -68
- package/python/fix_commands.py +0 -71
- package/python/fixed_function.py +0 -58
- package/python/manage_credentials.py +0 -119
- package/python/patch_modal_script.py +0 -75
- package/python/run_with_modal_token.py +0 -47
- package/python/test_import.py +0 -55
- package/python/test_llm_debug.py +0 -120
- package/python/test_modalSandboxScript.py.bak +0 -3672
- package/python/test_modal_auth.py +0 -90
- package/python/test_token_cleanup.py +0 -256
- package/python/verify_env_vars.py +0 -64
package/README.md
CHANGED
@@ -1,74 +1,119 @@
|
|
1
1
|
# GitArsenal CLI
|
2
2
|
|
3
|
-
|
3
|
+
**Run any GitHub repository instantly with pre-configured GPU environments.**
|
4
4
|
|
5
|
-
|
5
|
+
GitArsenal CLI makes it incredibly easy to run any GitHub repository without worrying about setup, dependencies, or environment configuration. Just point it at a repository and start coding with GPU acceleration.
|
6
6
|
|
7
|
-
|
8
|
-
- Clone repositories and run setup commands
|
9
|
-
- Persistent storage with Modal volumes
|
10
|
-
- SSH access to containers
|
11
|
-
- API key management for various services
|
7
|
+
## Why GitArsenal CLI?
|
12
8
|
|
13
|
-
|
9
|
+
- **Zero Setup**: No need to install dependencies, configure environments, or manage GPU drivers
|
10
|
+
- **GPU Ready**: Every environment comes with GPU acceleration (A10G, A100, H100)
|
11
|
+
- **Persistent Storage**: Your work and data persist between sessions
|
12
|
+
- **SSH Access**: Connect directly to your running environment
|
13
|
+
- **API Key Management**: Securely store and auto-inject API keys for services like OpenAI, Weights & Biases, and Hugging Face
|
14
14
|
|
15
|
-
|
15
|
+
## Quick Start
|
16
16
|
|
17
|
-
###
|
17
|
+
### Run any GitHub repository
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
```bash
|
20
|
+
# Basic usage - clone and run any repo
|
21
|
+
gitarsenal container --repo-url https://github.com/username/awesome-project.git
|
22
|
+
|
23
|
+
# With GPU acceleration
|
24
|
+
gitarsenal container --gpu A10G --repo-url https://github.com/username/awesome-project.git
|
22
25
|
|
23
|
-
|
26
|
+
# With custom setup commands
|
27
|
+
gitarsenal container --gpu A100 --repo-url https://github.com/username/awesome-project.git --setup-commands "pip install -r requirements.txt" "python setup.py install"
|
28
|
+
```
|
24
29
|
|
25
|
-
|
30
|
+
### Examples
|
26
31
|
|
27
32
|
```bash
|
28
|
-
#
|
29
|
-
|
33
|
+
# Run a machine learning project
|
34
|
+
gitarsenal container --gpu A100 --repo-url https://github.com/username/transformer-project.git --setup-commands "pip install torch transformers" "wandb login"
|
30
35
|
|
31
|
-
#
|
32
|
-
|
36
|
+
# Run a web development project
|
37
|
+
gitarsenal container --repo-url https://github.com/username/react-app.git --setup-commands "npm install" "npm start"
|
38
|
+
|
39
|
+
# Run a data science project with persistent storage
|
40
|
+
gitarsenal container --gpu A10G --repo-url https://github.com/username/data-analysis.git --volume-name my-data --setup-commands "pip install pandas numpy matplotlib"
|
33
41
|
```
|
34
42
|
|
35
|
-
|
43
|
+
## API Key Management
|
44
|
+
|
45
|
+
Store your API keys once and use them across all projects:
|
36
46
|
|
37
47
|
```bash
|
38
|
-
|
39
|
-
|
48
|
+
# Add API keys for seamless integration
|
49
|
+
gitarsenal keys add --service openai
|
50
|
+
gitarsenal keys add --service wandb
|
51
|
+
gitarsenal keys add --service huggingface
|
40
52
|
|
41
|
-
|
53
|
+
# View your saved keys
|
54
|
+
gitarsenal keys list
|
42
55
|
|
43
|
-
|
44
|
-
|
56
|
+
# Remove a key
|
57
|
+
gitarsenal keys delete --service openai
|
45
58
|
```
|
46
59
|
|
47
|
-
|
60
|
+
### Supported Services
|
61
|
+
|
62
|
+
- **OpenAI** - For debugging and AI assistance
|
63
|
+
- **Weights & Biases** - For experiment tracking
|
64
|
+
- **Hugging Face** - For model access and downloads
|
65
|
+
|
66
|
+
## Features
|
67
|
+
|
68
|
+
### Automatic Environment Setup
|
69
|
+
The CLI automatically:
|
70
|
+
- Clones your repository
|
71
|
+
- Installs dependencies based on your setup commands
|
72
|
+
- Configures GPU acceleration
|
73
|
+
- Sets up persistent storage
|
74
|
+
- Injects your saved API keys
|
75
|
+
|
76
|
+
### Persistent Storage
|
77
|
+
Keep your work safe with persistent volumes:
|
48
78
|
|
49
79
|
```bash
|
50
|
-
|
80
|
+
# Create a persistent environment
|
81
|
+
gitarsenal container --repo-url https://github.com/username/project.git --volume-name my-work
|
82
|
+
|
83
|
+
# Your data, models, and work will persist between sessions
|
51
84
|
```
|
52
85
|
|
53
|
-
|
86
|
+
### SSH Access
|
87
|
+
Connect directly to your running environment:
|
54
88
|
|
55
89
|
```bash
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
# With setup commands
|
60
|
-
python test_modalSandboxScript.py container --gpu A100 --repo-url https://github.com/username/repo.git --setup-commands "pip install -r requirements.txt" "python setup.py install"
|
90
|
+
# Get SSH connection details
|
91
|
+
gitarsenal container --repo-url https://github.com/username/project.git --ssh
|
61
92
|
|
62
|
-
#
|
63
|
-
|
93
|
+
# Connect via SSH to your environment
|
94
|
+
ssh user@your-environment-ip
|
64
95
|
```
|
65
96
|
|
66
|
-
##
|
97
|
+
## Workflow
|
98
|
+
|
99
|
+
1. **Choose a repository** - Any GitHub repo you want to work with
|
100
|
+
2. **Run the command** - Specify GPU, setup commands, and storage
|
101
|
+
3. **Start coding** - Your environment is ready with all dependencies installed
|
102
|
+
4. **Save your work** - Use persistent volumes to keep your progress
|
103
|
+
|
104
|
+
## Perfect For
|
105
|
+
|
106
|
+
- **Machine Learning Projects** - GPU-accelerated training with pre-configured environments
|
107
|
+
- **Data Science** - Jupyter notebooks with all dependencies ready
|
108
|
+
- **Web Development** - Full-stack projects with development servers
|
109
|
+
- **Research** - Reproducible environments for academic work
|
110
|
+
- **Hackathons** - Quick setup for rapid prototyping
|
67
111
|
|
68
|
-
|
112
|
+
## Getting Started
|
69
113
|
|
70
|
-
1.
|
71
|
-
2.
|
72
|
-
3.
|
114
|
+
1. Install the CLI (see installation instructions)
|
115
|
+
2. Add your API keys: `gitarsenal keys add --service openai`
|
116
|
+
3. Run any repository: `gitarsenal container --repo-url https://github.com/username/project.git`
|
117
|
+
4. Start coding!
|
73
118
|
|
74
|
-
|
119
|
+
No more "works on my machine" - every environment is identical and ready to go.
|
package/package.json
CHANGED
Binary file
|
@@ -343,10 +343,6 @@ def call_openai_for_debug(command, error_output, api_key=None, current_dir=None,
|
|
343
343
|
print(f"š DEBUG: Current directory: {current_dir}")
|
344
344
|
print(f"š DEBUG: Sandbox available: {sandbox is not None}")
|
345
345
|
print(f"š DEBUG: API key provided: {'Yes' if api_key else 'No'}")
|
346
|
-
if api_key:
|
347
|
-
print(f"š DEBUG: API key value: {api_key}")
|
348
|
-
else:
|
349
|
-
print(f"š DEBUG: API key from environment: {os.environ.get('OPENAI_API_KEY')}")
|
350
346
|
|
351
347
|
# Define _to_str function locally to avoid NameError
|
352
348
|
def _to_str(maybe_bytes):
|
@@ -692,9 +688,9 @@ Do not provide any explanations, just the exact command to run.
|
|
692
688
|
def try_api_call(model_name, retries=2, backoff_factor=1.5):
|
693
689
|
print(f"š DEBUG: Attempting API call with model: {model_name}")
|
694
690
|
print(f"š DEBUG: API key available: {'Yes' if api_key else 'No'}")
|
695
|
-
if api_key:
|
696
|
-
|
697
|
-
|
691
|
+
# if api_key:
|
692
|
+
# print(f"š DEBUG: API key length: {len(api_key)}")
|
693
|
+
# print(f"š DEBUG: API key starts with: {api_key[:10]}...")
|
698
694
|
|
699
695
|
payload = {
|
700
696
|
"model": model_name,
|
@@ -1,145 +0,0 @@
|
|
1
|
-
# Modal Proxy Service for GitArsenal CLI
|
2
|
-
|
3
|
-
This document explains how to set up and use the Modal proxy service with GitArsenal CLI.
|
4
|
-
|
5
|
-
## What is the Modal Proxy Service?
|
6
|
-
|
7
|
-
The Modal proxy service allows users to access Modal services (like GPU-accelerated containers) without exposing the owner's Modal token. The service runs on a server and provides API endpoints for creating sandboxes and SSH containers, using API key authentication.
|
8
|
-
|
9
|
-
## Server-Side Setup
|
10
|
-
|
11
|
-
1. **Install Requirements**:
|
12
|
-
```bash
|
13
|
-
pip install flask flask-cors modal python-dotenv
|
14
|
-
```
|
15
|
-
|
16
|
-
2. **Set Environment Variables**:
|
17
|
-
Create a `.env` file in the same directory as `modal_proxy_service.py`:
|
18
|
-
```
|
19
|
-
MODAL_TOKEN=your_modal_token_here
|
20
|
-
ADMIN_KEY=your_admin_key_here
|
21
|
-
API_KEYS=optional_comma_separated_list_of_api_keys
|
22
|
-
```
|
23
|
-
|
24
|
-
3. **Start the Service**:
|
25
|
-
```bash
|
26
|
-
python modal_proxy_service.py
|
27
|
-
```
|
28
|
-
|
29
|
-
The service will start on port 5001 by default.
|
30
|
-
|
31
|
-
4. **Create an API Key** (if not pre-configured in `.env`):
|
32
|
-
```bash
|
33
|
-
curl -X POST http://localhost:5001/api/create-api-key \
|
34
|
-
-H "X-Admin-Key: your_admin_key_here"
|
35
|
-
```
|
36
|
-
|
37
|
-
This will return a JSON response with a new API key:
|
38
|
-
```json
|
39
|
-
{"api_key": "generated_api_key_here"}
|
40
|
-
```
|
41
|
-
|
42
|
-
5. **Optional: Use ngrok to expose the service publicly**:
|
43
|
-
```bash
|
44
|
-
ngrok http 5001
|
45
|
-
```
|
46
|
-
|
47
|
-
This will provide you with a public URL that you can share with users.
|
48
|
-
|
49
|
-
Current ngrok URL: `https://932ffd63ad3d.ngrok-free.app`
|
50
|
-
|
51
|
-
## Client-Side Setup
|
52
|
-
|
53
|
-
1. **Configure the proxy client**:
|
54
|
-
```bash
|
55
|
-
./gitarsenal.py proxy configure
|
56
|
-
```
|
57
|
-
|
58
|
-
You'll be prompted to enter:
|
59
|
-
- The proxy URL (the default is now set to `https://932ffd63ad3d.ngrok-free.app`)
|
60
|
-
- Your API key
|
61
|
-
|
62
|
-
2. **Check proxy service status**:
|
63
|
-
```bash
|
64
|
-
./gitarsenal.py proxy status
|
65
|
-
```
|
66
|
-
|
67
|
-
## Using the Proxy Service
|
68
|
-
|
69
|
-
### Create an SSH Container
|
70
|
-
|
71
|
-
```bash
|
72
|
-
# Using the proxy command
|
73
|
-
./gitarsenal.py proxy ssh --gpu A10G --repo-url https://github.com/username/repo.git --wait
|
74
|
-
|
75
|
-
# Or using the standard ssh command with --use-proxy flag
|
76
|
-
./gitarsenal.py ssh --use-proxy --gpu A10G --repo-url https://github.com/username/repo.git
|
77
|
-
```
|
78
|
-
|
79
|
-
### Create a Sandbox
|
80
|
-
|
81
|
-
```bash
|
82
|
-
# Using the proxy command
|
83
|
-
./gitarsenal.py proxy sandbox --gpu A10G --repo-url https://github.com/username/repo.git --wait
|
84
|
-
|
85
|
-
# Or using the standard sandbox command with --use-proxy flag
|
86
|
-
./gitarsenal.py sandbox --use-proxy --gpu A10G --repo-url https://github.com/username/repo.git
|
87
|
-
```
|
88
|
-
|
89
|
-
## Troubleshooting
|
90
|
-
|
91
|
-
### "Token missing" Error
|
92
|
-
|
93
|
-
If you see a "Token missing" error when creating containers through the proxy service:
|
94
|
-
|
95
|
-
1. **Check that the MODAL_TOKEN is set on the server**:
|
96
|
-
- Verify the `.env` file has a valid MODAL_TOKEN
|
97
|
-
- Ensure the token is correctly formatted and not expired
|
98
|
-
- Restart the proxy service after updating the token
|
99
|
-
|
100
|
-
2. **Manually set the token on the server**:
|
101
|
-
```bash
|
102
|
-
# On the server running the proxy service
|
103
|
-
export MODAL_TOKEN_ID=your_modal_token_here
|
104
|
-
modal token set your_modal_token_here
|
105
|
-
```
|
106
|
-
|
107
|
-
3. **Verify the token works directly on the server**:
|
108
|
-
```bash
|
109
|
-
# Test if the token works by listing Modal volumes
|
110
|
-
modal volume list
|
111
|
-
```
|
112
|
-
|
113
|
-
4. **Check the proxy service logs**:
|
114
|
-
- Look at `modal_proxy.log` on the server for detailed error messages
|
115
|
-
- Check for messages like "Modal token verification failed"
|
116
|
-
- Ensure the token is being properly passed to the Modal API
|
117
|
-
|
118
|
-
5. **Restart the proxy service**:
|
119
|
-
```bash
|
120
|
-
# Kill the existing process and restart
|
121
|
-
pkill -f modal_proxy_service.py
|
122
|
-
python modal_proxy_service.py
|
123
|
-
```
|
124
|
-
|
125
|
-
6. **Check ngrok connection**:
|
126
|
-
- Verify the ngrok tunnel is active and the URL is correct
|
127
|
-
- Ensure requests are being properly forwarded to the proxy service
|
128
|
-
|
129
|
-
### "Unauthorized" Error
|
130
|
-
|
131
|
-
If you see an "Unauthorized" error:
|
132
|
-
|
133
|
-
1. **When creating an API key**:
|
134
|
-
- Make sure you're including the correct admin key in the request header
|
135
|
-
- Example: `-H "X-Admin-Key: your_admin_key_here"`
|
136
|
-
|
137
|
-
2. **When using the API**:
|
138
|
-
- Make sure your client is configured with a valid API key
|
139
|
-
- Reconfigure with `./gitarsenal.py proxy configure`
|
140
|
-
|
141
|
-
## Security Considerations
|
142
|
-
|
143
|
-
- Keep your admin key and API keys secure
|
144
|
-
- Use HTTPS if exposing the service publicly (ngrok provides this automatically)
|
145
|
-
- Consider implementing additional authentication mechanisms for production use
|
package/python/README.md
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
# GitArsenal CLI Python Modules
|
2
|
-
|
3
|
-
This directory contains Python modules for the GitArsenal CLI.
|
4
|
-
|
5
|
-
## Modal Integration
|
6
|
-
|
7
|
-
The GitArsenal CLI integrates with Modal for creating sandboxes and SSH containers. The following modules are available:
|
8
|
-
|
9
|
-
- `modal_proxy_service.py`: A proxy service for Modal operations
|
10
|
-
- `test_modalSandboxScript.py`: Creates Modal sandboxes and SSH containers
|
11
|
-
- `setup_modal_token.py`: Sets up the Modal token in the environment
|
12
|
-
- `fetch_modal_tokens.py`: Fetches Modal tokens from the proxy server
|
13
|
-
|
14
|
-
## Security Features
|
15
|
-
|
16
|
-
### Modal Token Cleanup
|
17
|
-
|
18
|
-
For enhanced security, GitArsenal CLI now automatically cleans up Modal tokens after SSH containers are created. This ensures that your Modal token is not left in the environment or on disk after the container is started.
|
19
|
-
|
20
|
-
The cleanup process:
|
21
|
-
1. Removes Modal token environment variables (MODAL_TOKEN_ID, MODAL_TOKEN, MODAL_TOKEN_SECRET)
|
22
|
-
2. Deletes the ~/.modal.toml file which contains the authentication token
|
23
|
-
3. Runs automatically after SSH container creation
|
24
|
-
4. Runs on service shutdown via signal handlers
|
25
|
-
|
26
|
-
This simple but effective approach prevents potential token leakage when containers are shared or when the service is stopped, and ensures that users cannot continue to use Modal CLI commands like `modal shell` after the container is created.
|
27
|
-
|
28
|
-
## Usage
|
29
|
-
|
30
|
-
To use the GitArsenal CLI Python modules, you can import them directly or use the provided scripts.
|
31
|
-
|
32
|
-
### Creating a Modal SSH Container
|
33
|
-
|
34
|
-
```python
|
35
|
-
from test_modalSandboxScript import create_modal_ssh_container
|
36
|
-
|
37
|
-
result = create_modal_ssh_container(
|
38
|
-
gpu_type="A10G",
|
39
|
-
repo_url="https://github.com/user/repo",
|
40
|
-
repo_name="repo",
|
41
|
-
setup_commands=["pip install -r requirements.txt"],
|
42
|
-
timeout_minutes=60
|
43
|
-
)
|
44
|
-
|
45
|
-
# The Modal token is automatically cleaned up after the container is created
|
46
|
-
```
|
47
|
-
|
48
|
-
### Running the Modal Proxy Service
|
49
|
-
|
50
|
-
```bash
|
51
|
-
python modal_proxy_service.py
|
52
|
-
```
|
53
|
-
|
54
|
-
The service will automatically clean up Modal tokens on shutdown.
|
55
|
-
|
56
|
-
## Testing
|
57
|
-
|
58
|
-
To test the Modal token cleanup functionality:
|
59
|
-
|
60
|
-
```bash
|
61
|
-
python test_token_cleanup.py
|
62
|
-
```
|
63
|
-
|
64
|
-
This script verifies that the token cleanup process works correctly by:
|
65
|
-
1. Setting up a test Modal token
|
66
|
-
2. Verifying the token exists in environment and files
|
67
|
-
3. Cleaning up the token
|
68
|
-
4. Verifying the token has been removed
|
package/python/fix_commands.py
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Fix commands for Modal SSH container
|
4
|
-
This script fixes common issues with commands in the Modal SSH container
|
5
|
-
"""
|
6
|
-
|
7
|
-
import os
|
8
|
-
import sys
|
9
|
-
import subprocess
|
10
|
-
|
11
|
-
def fix_command(cmd):
|
12
|
-
"""Fix common issues with commands"""
|
13
|
-
# Replace 'source' with '.' for sh shell
|
14
|
-
if 'source' in cmd:
|
15
|
-
cmd = cmd.replace('source', '.')
|
16
|
-
print(f"ā
Fixed: Replaced 'source' with '.' for sh shell")
|
17
|
-
|
18
|
-
# Fix uv venv and activation in one command
|
19
|
-
if 'uv venv' in cmd and '&&' in cmd:
|
20
|
-
# The command is already trying to create and activate a venv
|
21
|
-
# Just need to make sure 'source' is replaced with '.'
|
22
|
-
pass
|
23
|
-
|
24
|
-
# Fix uv pip install without active venv
|
25
|
-
if 'uv pip install' in cmd and 'venv' not in cmd:
|
26
|
-
# Create and activate a venv first
|
27
|
-
cmd = f"uv venv .venv && . .venv/bin/activate && {cmd}"
|
28
|
-
print(f"ā
Fixed: Added venv creation and activation before pip install")
|
29
|
-
|
30
|
-
return cmd
|
31
|
-
|
32
|
-
def run_fixed_command(cmd):
|
33
|
-
"""Run the fixed command"""
|
34
|
-
fixed_cmd = fix_command(cmd)
|
35
|
-
print(f"\nš§ Running fixed command: {fixed_cmd}")
|
36
|
-
|
37
|
-
# Run the command
|
38
|
-
result = subprocess.run(fixed_cmd, shell=True, text=True, capture_output=True)
|
39
|
-
|
40
|
-
# Print the output
|
41
|
-
if result.stdout:
|
42
|
-
print(f"\n--- Output ---\n{result.stdout}")
|
43
|
-
if result.stderr:
|
44
|
-
print(f"\n--- Error ---\n{result.stderr}")
|
45
|
-
|
46
|
-
# Return the result
|
47
|
-
return result.returncode == 0
|
48
|
-
|
49
|
-
def main():
|
50
|
-
"""Main function"""
|
51
|
-
if len(sys.argv) < 2:
|
52
|
-
print("Usage: python fix_commands.py 'command to fix'")
|
53
|
-
return 1
|
54
|
-
|
55
|
-
# Get the command from command line
|
56
|
-
cmd = ' '.join(sys.argv[1:])
|
57
|
-
print(f"š Original command: {cmd}")
|
58
|
-
|
59
|
-
# Run the fixed command
|
60
|
-
success = run_fixed_command(cmd)
|
61
|
-
|
62
|
-
# Print the result
|
63
|
-
if success:
|
64
|
-
print("\nā
Command executed successfully")
|
65
|
-
else:
|
66
|
-
print("\nā Command failed")
|
67
|
-
|
68
|
-
return 0 if success else 1
|
69
|
-
|
70
|
-
if __name__ == "__main__":
|
71
|
-
sys.exit(main())
|
package/python/fixed_function.py
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
def get_setup_commands_from_local_api(repo_url, gitingest_data):
|
2
|
-
"""Try to get setup commands from the API."""
|
3
|
-
# Use only online endpoints
|
4
|
-
api_endpoints = [
|
5
|
-
"https://www.gitarsenal.dev/api/analyze-with-gitingest" # Working endpoint with www prefix
|
6
|
-
]
|
7
|
-
|
8
|
-
# Prepare the request payload
|
9
|
-
payload = {
|
10
|
-
"repoUrl": repo_url,
|
11
|
-
"gitingestData": gitingest_data,
|
12
|
-
"userRequest": "Setup and run the repository"
|
13
|
-
}
|
14
|
-
|
15
|
-
# Try each API endpoint
|
16
|
-
for api_url in api_endpoints:
|
17
|
-
# Use the retry mechanism for more reliable requests
|
18
|
-
response = make_api_request_with_retry(
|
19
|
-
url=api_url,
|
20
|
-
payload=payload,
|
21
|
-
max_retries=2,
|
22
|
-
timeout=180 # 3 minute timeout
|
23
|
-
)
|
24
|
-
|
25
|
-
if response and response.status_code == 200:
|
26
|
-
try:
|
27
|
-
data = response.json()
|
28
|
-
print(f"š Response size: {len(response.text)} bytes")
|
29
|
-
print(f"š Response URL: {response.url}")
|
30
|
-
if "setupInstructions" in data and "commands" in data["setupInstructions"]:
|
31
|
-
commands = data["setupInstructions"]["commands"]
|
32
|
-
print(f"ā
Successfully fetched {len(commands)} setup commands from API at {api_url}")
|
33
|
-
|
34
|
-
# Print the original commands
|
35
|
-
print("š Original commands from API:")
|
36
|
-
for i, cmd in enumerate(commands, 1):
|
37
|
-
print(f" {i}. {cmd}")
|
38
|
-
|
39
|
-
# Fix the commands
|
40
|
-
fixed_commands = fix_setup_commands(commands)
|
41
|
-
|
42
|
-
# Print the fixed commands
|
43
|
-
print("\nš Fixed commands:")
|
44
|
-
for i, cmd in enumerate(fixed_commands, 1):
|
45
|
-
print(f" {i}. {cmd}")
|
46
|
-
|
47
|
-
return fixed_commands
|
48
|
-
else:
|
49
|
-
print("ā ļø API response did not contain setupInstructions.commands field")
|
50
|
-
except json.JSONDecodeError:
|
51
|
-
print(f"ā Failed to parse API response as JSON")
|
52
|
-
elif response:
|
53
|
-
print(f"ā API request failed with status code: {response.status_code}")
|
54
|
-
else:
|
55
|
-
print(f"ā Failed to connect to {api_url}")
|
56
|
-
|
57
|
-
print("ā All API endpoints failed")
|
58
|
-
return None
|
@@ -1,119 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
GitArsenal Credentials Manager CLI
|
4
|
-
|
5
|
-
This script allows users to manage their API keys and tokens for GitArsenal CLI.
|
6
|
-
"""
|
7
|
-
|
8
|
-
import argparse
|
9
|
-
import sys
|
10
|
-
from credentials_manager import CredentialsManager
|
11
|
-
|
12
|
-
def main():
|
13
|
-
parser = argparse.ArgumentParser(description="Manage credentials for GitArsenal CLI")
|
14
|
-
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
15
|
-
|
16
|
-
# Setup command
|
17
|
-
setup_parser = subparsers.add_parser("setup", help="Set up all credentials")
|
18
|
-
|
19
|
-
# Set command
|
20
|
-
set_parser = subparsers.add_parser("set", help="Set a specific credential")
|
21
|
-
set_parser.add_argument("key", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key"],
|
22
|
-
help="The credential to set")
|
23
|
-
|
24
|
-
# Get command
|
25
|
-
get_parser = subparsers.add_parser("get", help="Get a specific credential")
|
26
|
-
get_parser.add_argument("key", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key"],
|
27
|
-
help="The credential to get")
|
28
|
-
|
29
|
-
# Clear command
|
30
|
-
clear_parser = subparsers.add_parser("clear", help="Clear credentials")
|
31
|
-
clear_parser.add_argument("key", nargs="?", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key", "all"],
|
32
|
-
default="all", help="The credential to clear (default: all)")
|
33
|
-
|
34
|
-
# List command
|
35
|
-
list_parser = subparsers.add_parser("list", help="List all saved credentials (shows only existence, not values)")
|
36
|
-
|
37
|
-
args = parser.parse_args()
|
38
|
-
|
39
|
-
# Create credentials manager
|
40
|
-
credentials_manager = CredentialsManager()
|
41
|
-
|
42
|
-
if args.command == "setup":
|
43
|
-
print("š Setting up all credentials for GitArsenal CLI")
|
44
|
-
print("You'll be prompted for each credential. Press Ctrl+C to skip any credential.")
|
45
|
-
|
46
|
-
try:
|
47
|
-
# OpenAI API key
|
48
|
-
print("\nš Setting up OpenAI API key")
|
49
|
-
credentials_manager.get_openai_api_key()
|
50
|
-
|
51
|
-
# Modal token
|
52
|
-
print("\nš Setting up Modal token")
|
53
|
-
credentials_manager.get_modal_token()
|
54
|
-
|
55
|
-
# Hugging Face token
|
56
|
-
print("\nš Setting up Hugging Face token")
|
57
|
-
credentials_manager.get_huggingface_token()
|
58
|
-
|
59
|
-
# Weights & Biases API key
|
60
|
-
print("\nš Setting up Weights & Biases API key")
|
61
|
-
credentials_manager.get_wandb_api_key()
|
62
|
-
|
63
|
-
print("\nā
Credentials setup complete!")
|
64
|
-
|
65
|
-
except KeyboardInterrupt:
|
66
|
-
print("\n\nā ļø Setup interrupted. Some credentials may not have been set.")
|
67
|
-
return 1
|
68
|
-
|
69
|
-
elif args.command == "set":
|
70
|
-
print(f"š Setting {args.key}")
|
71
|
-
if args.key == "openai_api_key":
|
72
|
-
credentials_manager.get_openai_api_key()
|
73
|
-
elif args.key == "modal_token":
|
74
|
-
credentials_manager.get_modal_token()
|
75
|
-
elif args.key == "huggingface_token":
|
76
|
-
credentials_manager.get_huggingface_token()
|
77
|
-
elif args.key == "wandb_api_key":
|
78
|
-
credentials_manager.get_wandb_api_key()
|
79
|
-
|
80
|
-
elif args.command == "get":
|
81
|
-
credentials = credentials_manager.load_credentials()
|
82
|
-
if args.key in credentials:
|
83
|
-
# Show only first and last few characters for security
|
84
|
-
value = credentials[args.key]
|
85
|
-
masked_value = value[:4] + "*" * (len(value) - 8) + value[-4:] if len(value) > 8 else "****"
|
86
|
-
print(f"{args.key}: {masked_value}")
|
87
|
-
else:
|
88
|
-
print(f"ā {args.key} not found in saved credentials")
|
89
|
-
return 1
|
90
|
-
|
91
|
-
elif args.command == "clear":
|
92
|
-
if args.key == "all":
|
93
|
-
credentials_manager.clear_all_credentials()
|
94
|
-
print("ā
All credentials cleared")
|
95
|
-
else:
|
96
|
-
if credentials_manager.clear_credential(args.key):
|
97
|
-
print(f"ā
{args.key} cleared")
|
98
|
-
else:
|
99
|
-
print(f"ā {args.key} not found in saved credentials")
|
100
|
-
return 1
|
101
|
-
|
102
|
-
elif args.command == "list":
|
103
|
-
credentials = credentials_manager.load_credentials()
|
104
|
-
if not credentials:
|
105
|
-
print("No credentials saved")
|
106
|
-
return 0
|
107
|
-
|
108
|
-
print("š Saved credentials:")
|
109
|
-
for key in credentials:
|
110
|
-
print(f"- {key}: {'*' * 8}")
|
111
|
-
|
112
|
-
else:
|
113
|
-
parser.print_help()
|
114
|
-
return 1
|
115
|
-
|
116
|
-
return 0
|
117
|
-
|
118
|
-
if __name__ == "__main__":
|
119
|
-
sys.exit(main())
|