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 CHANGED
@@ -1 +1 @@
1
- {"created":"2025-08-13T05:23:55.166Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.9.59",
3
+ "version": "1.9.61",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -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
@@ -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
- try:
13
- credentials_file = Path.home() / ".gitarsenal" / "credentials.json"
14
- if credentials_file.exists():
15
- with open(credentials_file, 'r') as f:
16
- return json.load(f)
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", "openai")
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 = ["openai", "anthropic", "groq", "openrouter"]
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
- if stdout_text:
317
- print(f"✅ Output: {stdout_text}")
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