gitarsenal-cli 1.9.59 → 1.9.61
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 +1 -1
- package/lib/sandbox.js +6 -4
- package/package.json +1 -1
- package/python/__pycache__/auth_manager.cpython-312.pyc +0 -0
- package/python/__pycache__/fetch_modal_tokens.cpython-312.pyc +0 -0
- package/python/command_manager.py +4 -0
- package/python/llm_debugging.py +9 -11
- package/python/shell.py +9 -3
- package/python/test_modalSandboxScript.py +4 -4
package/.venv_status.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"created":"2025-08-
|
|
1
|
+
{"created":"2025-08-13T13:27:56.009Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
|
package/lib/sandbox.js
CHANGED
|
@@ -72,8 +72,9 @@ async function runContainer(options) {
|
|
|
72
72
|
|
|
73
73
|
// Run the Python script with show examples flag
|
|
74
74
|
const pythonExecutable = process.env.PYTHON_EXECUTABLE || 'python';
|
|
75
|
-
const pythonProcess = spawn(pythonExecutable, args, {
|
|
76
|
-
stdio: 'inherit' // Inherit stdio to show real-time output
|
|
75
|
+
const pythonProcess = spawn(pythonExecutable, ['-u', ...args], {
|
|
76
|
+
stdio: 'inherit', // Inherit stdio to show real-time output
|
|
77
|
+
env: { ...process.env, PYTHONUNBUFFERED: '1' } // Force unbuffered output
|
|
77
78
|
});
|
|
78
79
|
|
|
79
80
|
return new Promise((resolve, reject) => {
|
|
@@ -138,8 +139,9 @@ async function runContainer(options) {
|
|
|
138
139
|
try {
|
|
139
140
|
// Run the Python script
|
|
140
141
|
const pythonExecutable = process.env.PYTHON_EXECUTABLE || 'python';
|
|
141
|
-
const pythonProcess = spawn(pythonExecutable, args, {
|
|
142
|
-
stdio: 'inherit' // Inherit stdio to show real-time output
|
|
142
|
+
const pythonProcess = spawn(pythonExecutable, ['-u', ...args], {
|
|
143
|
+
stdio: 'inherit', // Inherit stdio to show real-time output
|
|
144
|
+
env: { ...process.env, PYTHONUNBUFFERED: '1' } // Force unbuffered output
|
|
143
145
|
});
|
|
144
146
|
|
|
145
147
|
// Handle process completion
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -382,6 +382,8 @@ class CommandListManager:
|
|
|
382
382
|
prompt = f"""
|
|
383
383
|
I need to determine if an original command should be skipped after a successful fix command.
|
|
384
384
|
|
|
385
|
+
ENVIRONMENT: All commands are running on a Unix/Linux environment (bash shell), so only suggest Unix-compatible commands.
|
|
386
|
+
|
|
385
387
|
Original command (failed): {original_command}
|
|
386
388
|
Fix command (succeeded): {fix_command}
|
|
387
389
|
|
|
@@ -520,6 +522,8 @@ class CommandListManager:
|
|
|
520
522
|
I need you to analyze and optimize this command list. Some commands have been executed,
|
|
521
523
|
and some are still pending. Based on what has already been executed, I need you to:
|
|
522
524
|
|
|
525
|
+
ENVIRONMENT: All commands are running on a Unix/Linux environment (bash shell), so only suggest Unix-compatible commands. Do not suggest Windows-specific commands or PowerShell commands.
|
|
526
|
+
|
|
523
527
|
1. Identify any pending commands that are now redundant or unnecessary
|
|
524
528
|
2. Identify any pending commands that should be modified based on previous command results
|
|
525
529
|
3. Suggest any new commands that should be added
|
package/python/llm_debugging.py
CHANGED
|
@@ -9,15 +9,11 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
def get_stored_credentials():
|
|
11
11
|
"""Load stored credentials from ~/.gitarsenal/credentials.json"""
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return {}
|
|
18
|
-
except Exception as e:
|
|
19
|
-
print(f"⚠️ Error loading stored credentials: {e}")
|
|
20
|
-
return {}
|
|
12
|
+
credentials_file = Path.home() / ".gitarsenal" / "credentials.json"
|
|
13
|
+
if credentials_file.exists():
|
|
14
|
+
with open(credentials_file, 'r') as f:
|
|
15
|
+
return json.load(f)
|
|
16
|
+
return {}
|
|
21
17
|
|
|
22
18
|
|
|
23
19
|
def generate_auth_context(stored_credentials):
|
|
@@ -35,7 +31,7 @@ def generate_auth_context(stored_credentials):
|
|
|
35
31
|
|
|
36
32
|
def get_current_debug_model():
|
|
37
33
|
"""Get the currently configured debugging model preference"""
|
|
38
|
-
return os.environ.get("GITARSENAL_DEBUG_MODEL", "
|
|
34
|
+
return os.environ.get("GITARSENAL_DEBUG_MODEL", "anthropic")
|
|
39
35
|
|
|
40
36
|
|
|
41
37
|
def _to_str(maybe_bytes):
|
|
@@ -536,7 +532,7 @@ def make_groq_request(api_key, prompt, retries=2):
|
|
|
536
532
|
|
|
537
533
|
def get_provider_rotation_order(preferred=None):
|
|
538
534
|
"""Return provider rotation order starting with preferred if valid."""
|
|
539
|
-
default_order = ["
|
|
535
|
+
default_order = ["anthropic", "openai", "groq", "openrouter"]
|
|
540
536
|
if preferred and preferred in default_order:
|
|
541
537
|
return [preferred] + [p for p in default_order if p != preferred]
|
|
542
538
|
return default_order
|
|
@@ -614,6 +610,8 @@ def call_llm_for_batch_debug(failed_commands, api_key=None, current_dir=None, sa
|
|
|
614
610
|
# Create batch prompt once
|
|
615
611
|
prompt = f"""You are a debugging assistant analyzing multiple failed commands.
|
|
616
612
|
|
|
613
|
+
ENVIRONMENT: All commands are running on a Unix/Linux environment (bash shell), so only suggest Unix-compatible commands. Do not suggest Windows-specific commands or PowerShell commands.
|
|
614
|
+
|
|
617
615
|
Context:
|
|
618
616
|
{chr(10).join(context_parts)}
|
|
619
617
|
|
package/python/shell.py
CHANGED
|
@@ -180,7 +180,7 @@ class PersistentShell:
|
|
|
180
180
|
self.command_counter += 1
|
|
181
181
|
marker = f"CMD_DONE_{self.command_counter}_{uuid.uuid4().hex[:8]}"
|
|
182
182
|
|
|
183
|
-
print(f"🔧 Executing: {command}")
|
|
183
|
+
print(f"🔧 Executing: {command}", flush=True)
|
|
184
184
|
|
|
185
185
|
# Clear any existing output
|
|
186
186
|
self._clear_lines()
|
|
@@ -266,6 +266,8 @@ class PersistentShell:
|
|
|
266
266
|
command_stdout.append(line)
|
|
267
267
|
elif line.strip() and not line.startswith("$"): # Skip empty lines and prompt lines
|
|
268
268
|
command_stdout.append(line)
|
|
269
|
+
# Print line immediately for real-time streaming
|
|
270
|
+
print(line, flush=True)
|
|
269
271
|
|
|
270
272
|
if found_marker:
|
|
271
273
|
break
|
|
@@ -278,6 +280,8 @@ class PersistentShell:
|
|
|
278
280
|
for line in current_stderr:
|
|
279
281
|
if line.strip(): # Skip empty lines
|
|
280
282
|
command_stderr.append(line)
|
|
283
|
+
# Print stderr immediately for real-time streaming
|
|
284
|
+
print(f"{line}", flush=True)
|
|
281
285
|
|
|
282
286
|
# Check if command is waiting for user input
|
|
283
287
|
if not found_marker and time.time() - start_time > 5: # Wait at least 5 seconds before checking
|
|
@@ -313,8 +317,8 @@ class PersistentShell:
|
|
|
313
317
|
success = exit_code == 0 if exit_code is not None else len(command_stderr) == 0
|
|
314
318
|
|
|
315
319
|
if success:
|
|
316
|
-
|
|
317
|
-
|
|
320
|
+
# Don't print the summary output since we already streamed it line by line
|
|
321
|
+
pass
|
|
318
322
|
# Track virtual environment activation
|
|
319
323
|
if command.strip().startswith("source ") and "/bin/activate" in command:
|
|
320
324
|
venv_path = command.replace("source ", "").replace("/bin/activate", "").strip()
|
|
@@ -475,6 +479,8 @@ class PersistentShell:
|
|
|
475
479
|
prompt = f"""
|
|
476
480
|
The command '{command}' appears to be waiting for user input.
|
|
477
481
|
|
|
482
|
+
ENVIRONMENT: All commands are running on a Unix/Linux environment (bash shell), so only suggest Unix-compatible commands. Do not suggest Windows-specific commands or PowerShell commands.
|
|
483
|
+
|
|
478
484
|
Current directory: {current_dir}
|
|
479
485
|
|
|
480
486
|
Last stdout output:
|
|
@@ -1316,8 +1316,8 @@ def make_api_request_with_retry(url, payload, max_retries=2, timeout=180):
|
|
|
1316
1316
|
if attempt > 0:
|
|
1317
1317
|
print(f"🔄 Retry attempt {attempt}/{max_retries}...")
|
|
1318
1318
|
|
|
1319
|
-
print(f"🌐 Making POST request to: {url}")
|
|
1320
|
-
print(f"⏳ Waiting up to {timeout//60} minutes for response...")
|
|
1319
|
+
# print(f"🌐 Making POST request to: {url}")
|
|
1320
|
+
# print(f"⏳ Waiting up to {timeout//60} minutes for response...")
|
|
1321
1321
|
|
|
1322
1322
|
# Set allow_redirects=True to follow redirects automatically
|
|
1323
1323
|
response = requests.post(
|
|
@@ -1471,7 +1471,7 @@ def get_setup_commands_from_gitingest(repo_url):
|
|
|
1471
1471
|
# Try each API endpoint
|
|
1472
1472
|
for api_url in api_endpoints:
|
|
1473
1473
|
try:
|
|
1474
|
-
print(f"Trying API endpoint: {api_url}")
|
|
1474
|
+
# print(f"Trying API endpoint: {api_url}")
|
|
1475
1475
|
|
|
1476
1476
|
# Load stored credentials
|
|
1477
1477
|
stored_credentials = get_stored_credentials()
|
|
@@ -2166,7 +2166,7 @@ if __name__ == "__main__":
|
|
|
2166
2166
|
|
|
2167
2167
|
# Use gitingest by default unless --no-gitingest is set
|
|
2168
2168
|
if args.repo_url and (args.use_gitingest and not args.no_gitingest):
|
|
2169
|
-
print("🔄 Using gitingest approach to fetch setup commands (default)")
|
|
2169
|
+
# print("🔄 Using gitingest approach to fetch setup commands (default)")
|
|
2170
2170
|
api_commands = get_setup_commands_from_gitingest(args.repo_url)
|
|
2171
2171
|
if api_commands:
|
|
2172
2172
|
setup_commands = api_commands
|