Compare commits

...

4 Commits

Author SHA1 Message Date
openhands
f10360f416 test: fix unit tests
- Add missing dependency 'markdown' for CLI TUI rendering
- Prevent env var WORKSPACE_MOUNT_PATH_IN_SANDBOX from overriding default when SANDBOX_VOLUMES lacks /workspace

Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-28 18:41:13 +00:00
openhands
bf13354bbd Make setup process more friendly and welcoming
- Add emojis and encouraging language to setup messages
- Replace technical jargon with conversational tone
- Add visual indicators for different setup steps
- Include completion messages that celebrate user progress
- Update setup script, Makefile, and VS Code build script
2025-08-11 18:15:52 +00:00
Robert Brennan
385acded2c Update SECURITY.md 2025-08-11 09:01:17 -04:00
Robert Brennan
ab079488c6 Create SECURITY.md 2025-08-09 14:37:18 -04:00
7 changed files with 93 additions and 43 deletions

View File

@@ -1,13 +1,17 @@
#! /bin/bash
echo "Setting up the environment..."
echo "🚀 Welcome to OpenHands! Let's get your development environment ready..."
# Install pre-commit package
echo "📦 Installing pre-commit to help maintain code quality..."
python -m pip install pre-commit
# Install pre-commit hooks if .git directory exists
if [ -d ".git" ]; then
echo "Installing pre-commit hooks..."
echo "🔧 Setting up pre-commit hooks to keep your code clean..."
pre-commit install
make install-pre-commit-hooks
echo ""
echo "🎉 Setup complete! Your OpenHands development environment is ready!"
echo "💡 You can now start contributing to OpenHands. Happy coding! 🚀"
fi

View File

@@ -23,16 +23,16 @@ RESET=$(shell tput -Txterm sgr0)
# Build
build:
@echo "$(GREEN)Building project...$(RESET)"
@echo "$(GREEN)🚀 Building OpenHands project...$(RESET)"
@$(MAKE) -s check-dependencies
@$(MAKE) -s install-python-dependencies
@$(MAKE) -s install-frontend-dependencies
@$(MAKE) -s install-pre-commit-hooks
@$(MAKE) -s build-frontend
@echo "$(GREEN)Build completed successfully.$(RESET)"
@echo "$(GREEN)🎉 Build completed successfully! You're ready to go!$(RESET)"
check-dependencies:
@echo "$(YELLOW)Checking dependencies...$(RESET)"
@echo "$(YELLOW)🔍 Checking your development environment...$(RESET)"
@$(MAKE) -s check-system
@$(MAKE) -s check-python
@$(MAKE) -s check-npm
@@ -42,7 +42,7 @@ ifeq ($(INSTALL_DOCKER),)
endif
@$(MAKE) -s check-poetry
@$(MAKE) -s check-tmux
@echo "$(GREEN)Dependencies checked successfully.$(RESET)"
@echo "$(GREEN)✅ All dependencies look great!$(RESET)"
check-system:
@echo "$(YELLOW)Checking system...$(RESET)"
@@ -62,11 +62,11 @@ check-system:
fi
check-python:
@echo "$(YELLOW)Checking Python installation...$(RESET)"
@echo "$(YELLOW)🐍 Checking Python installation...$(RESET)"
@if command -v python$(PYTHON_VERSION) > /dev/null; then \
echo "$(BLUE)$(shell python$(PYTHON_VERSION) --version) is already installed.$(RESET)"; \
echo "$(BLUE)✅ Great! $(shell python$(PYTHON_VERSION) --version) is ready to go.$(RESET)"; \
else \
echo "$(RED)Python $(PYTHON_VERSION) is not installed. Please install Python $(PYTHON_VERSION) to continue.$(RESET)"; \
echo "$(RED)❌ Oops! Python $(PYTHON_VERSION) is not installed. Please install Python $(PYTHON_VERSION) to continue.$(RESET)"; \
exit 1; \
fi
@@ -117,76 +117,76 @@ check-tmux:
fi
check-poetry:
@echo "$(YELLOW)Checking Poetry installation...$(RESET)"
@echo "$(YELLOW)📝 Checking Poetry installation...$(RESET)"
@if command -v poetry > /dev/null; then \
POETRY_VERSION=$(shell poetry --version 2>&1 | sed -E 's/Poetry \(version ([0-9]+\.[0-9]+\.[0-9]+)\)/\1/'); \
IFS='.' read -r -a POETRY_VERSION_ARRAY <<< "$$POETRY_VERSION"; \
if [ $${POETRY_VERSION_ARRAY[0]} -gt 1 ] || ([ $${POETRY_VERSION_ARRAY[0]} -eq 1 ] && [ $${POETRY_VERSION_ARRAY[1]} -ge 8 ]); then \
echo "$(BLUE)$(shell poetry --version) is already installed.$(RESET)"; \
echo "$(BLUE)✅ Perfect! $(shell poetry --version) is ready to manage your dependencies.$(RESET)"; \
else \
echo "$(RED)Poetry 1.8 or later is required. You can install poetry by running the following command, then adding Poetry to your PATH:"; \
echo "$(RED)❌ We need Poetry 1.8 or later. You can install it by running:"; \
echo "$(RED) curl -sSL https://install.python-poetry.org | python$(PYTHON_VERSION) -$(RESET)"; \
echo "$(RED)More detail here: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
echo "$(RED)📖 More details: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
exit 1; \
fi; \
else \
echo "$(RED)Poetry is not installed. You can install poetry by running the following command, then adding Poetry to your PATH:"; \
echo "$(RED)Poetry is not installed. You can install it by running:"; \
echo "$(RED) curl -sSL https://install.python-poetry.org | python$(PYTHON_VERSION) -$(RESET)"; \
echo "$(RED)More detail here: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
echo "$(RED)📖 More details: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
exit 1; \
fi
install-python-dependencies:
@echo "$(GREEN)Installing Python dependencies...$(RESET)"
@echo "$(GREEN)📦 Installing Python dependencies...$(RESET)"
@if [ -z "${TZ}" ]; then \
echo "Defaulting TZ (timezone) to UTC"; \
echo "🌍 Defaulting timezone to UTC"; \
export TZ="UTC"; \
fi
poetry env use python$(PYTHON_VERSION)
@if [ "$(shell uname)" = "Darwin" ]; then \
echo "$(BLUE)Installing chroma-hnswlib...$(RESET)"; \
echo "$(BLUE)🍎 Installing macOS-specific dependencies...$(RESET)"; \
export HNSWLIB_NO_NATIVE=1; \
poetry run pip install chroma-hnswlib; \
fi
@if [ -n "${POETRY_GROUP}" ]; then \
echo "Installing only POETRY_GROUP=${POETRY_GROUP}"; \
echo "📋 Installing specific dependency group: ${POETRY_GROUP}"; \
poetry install --only $${POETRY_GROUP}; \
else \
poetry install --with dev,test,runtime; \
fi
@if [ "${INSTALL_PLAYWRIGHT}" != "false" ] && [ "${INSTALL_PLAYWRIGHT}" != "0" ]; then \
if [ -f "/etc/manjaro-release" ]; then \
echo "$(BLUE)Detected Manjaro Linux. Installing Playwright dependencies...$(RESET)"; \
echo "$(BLUE)🐧 Detected Manjaro Linux. Installing browser automation tools...$(RESET)"; \
poetry run pip install playwright; \
poetry run playwright install chromium; \
else \
if [ ! -f cache/playwright_chromium_is_installed.txt ]; then \
echo "Running playwright install --with-deps chromium..."; \
echo "🌐 Installing browser automation tools..."; \
poetry run playwright install --with-deps chromium; \
mkdir -p cache; \
touch cache/playwright_chromium_is_installed.txt; \
else \
echo "Setup already done. Skipping playwright installation."; \
echo "✅ Browser tools already set up. Skipping installation."; \
fi \
fi \
else \
echo "Skipping Playwright installation (INSTALL_PLAYWRIGHT=${INSTALL_PLAYWRIGHT})."; \
echo "⏭️ Skipping browser automation setup (INSTALL_PLAYWRIGHT=${INSTALL_PLAYWRIGHT})."; \
fi
@echo "$(GREEN)Python dependencies installed successfully.$(RESET)"
@echo "$(GREEN)🎉 Python dependencies installed successfully!$(RESET)"
install-frontend-dependencies: check-npm check-nodejs
@echo "$(YELLOW)Setting up frontend environment...$(RESET)"
@echo "$(YELLOW)Detect Node.js version...$(RESET)"
@echo "$(YELLOW)🎨 Setting up frontend environment...$(RESET)"
@echo "$(YELLOW)🔍 Detecting Node.js version...$(RESET)"
@cd frontend && node ./scripts/detect-node-version.js
echo "$(BLUE)Installing frontend dependencies with npm...$(RESET)"
echo "$(BLUE)📦 Installing frontend dependencies with npm...$(RESET)"
@cd frontend && npm install
@echo "$(GREEN)Frontend dependencies installed successfully.$(RESET)"
@echo "$(GREEN)Frontend dependencies installed successfully!$(RESET)"
install-pre-commit-hooks: check-python check-poetry install-python-dependencies
@echo "$(YELLOW)Installing pre-commit hooks...$(RESET)"
@echo "$(YELLOW)🔧 Installing pre-commit hooks...$(RESET)"
@git config --unset-all core.hooksPath || true
@poetry run pre-commit install --config $(PRE_COMMIT_CONFIG_PATH)
@echo "$(GREEN)Pre-commit hooks installed successfully.$(RESET)"
@echo "$(GREEN)Pre-commit hooks installed successfully!$(RESET)"
lint-backend: install-pre-commit-hooks
@echo "$(YELLOW)Running linters...$(RESET)"

15
SECURITY.md Normal file
View File

@@ -0,0 +1,15 @@
# Security Policy
**Please send all vulnerability reports to contact@all-hands.dev in addition to opening a security advisory on GitHub.**
## Security/Bugfix Versions
Security and bug fixes are generally provided only for the most recent version of OpenHands. Fixes are released either as part of the next minor version or as an on-demand patch version.
Security fixes are given priority and might be enough to cause a new version to be released.
## Reporting a Vulnerability
We encourage responsible disclosure of security vulnerabilities. If you find something suspicious, we encourage and appreciate your report!
### Ways to report
In order for the vulnerability reports to reach maintainers as soon as possible, the preferred way is to use the "Report a vulnerability" button under the "Security" tab of the associated GitHub project. This creates a private communication channel between the reporter and the maintainers.
In addition, please also reach out to the All Hands AI security team at contact@all-hands.dev.

View File

@@ -55,11 +55,11 @@ def build_vscode_extension():
print(f'--- Using pre-built VS Code extension: {vsix_path} ---')
return
print(f'--- Building VS Code extension in {VSCODE_EXTENSION_DIR} ---')
print(f'🔨 Building VS Code extension in {VSCODE_EXTENSION_DIR}')
try:
# Ensure npm dependencies are installed
print('--- Running npm install for VS Code extension ---')
print('📦 Installing dependencies for VS Code extension...')
subprocess.run(
['npm', 'install'],
cwd=VSCODE_EXTENSION_DIR,
@@ -68,7 +68,7 @@ def build_vscode_extension():
)
# Package the extension
print(f'--- Packaging VS Code extension ({VSIX_FILENAME}) ---')
print(f'📦 Packaging VS Code extension ({VSIX_FILENAME})...')
subprocess.run(
['npm', 'run', 'package-vsix'],
cwd=VSCODE_EXTENSION_DIR,
@@ -82,14 +82,14 @@ def build_vscode_extension():
f'VS Code extension package not found after build: {vsix_path}'
)
print(f'--- VS Code extension built successfully: {vsix_path} ---')
print(f'🎉 VS Code extension built successfully: {vsix_path}')
except subprocess.CalledProcessError as e:
print(f'--- Warning: Failed to build VS Code extension: {e} ---')
print('--- Continuing without building extension ---')
print(f'⚠️ Warning: Failed to build VS Code extension: {e}')
print('⏭️ Continuing without building extension...')
if not vsix_path.exists():
print('--- Warning: No pre-built VS Code extension found ---')
print('--- VS Code extension will not be available ---')
print('⚠️ Warning: No pre-built VS Code extension found')
print(' VS Code extension will not be available')
def build(setup_kwargs):
@@ -97,7 +97,7 @@ def build(setup_kwargs):
This function is called by Poetry during the build process.
`setup_kwargs` is a dictionary that will be passed to `setuptools.setup()`.
"""
print('--- Running custom Poetry build script (build_vscode.py) ---')
print('🔧 Running custom Poetry build script for VS Code extension...')
# Build the VS Code extension and place the .vsix file
build_vscode_extension()
@@ -105,10 +105,10 @@ def build(setup_kwargs):
# Poetry will handle including files based on pyproject.toml `include` patterns.
# Ensure openhands/integrations/vscode/*.vsix is included there.
print('--- Custom Poetry build script (build_vscode.py) finished ---')
print(' Custom Poetry build script completed!')
if __name__ == '__main__':
print('Running build_vscode.py directly for testing VS Code extension packaging...')
print('🧪 Testing VS Code extension packaging...')
build_vscode_extension()
print('Direct execution of build_vscode.py finished.')
print('✅ VS Code extension packaging test completed!')

View File

@@ -77,6 +77,17 @@ def load_from_env(
set_attr_from_env(field_value, prefix=field_name + '_')
elif env_var_name in env_or_toml_dict:
# Special case: avoid overriding workspace_mount_path_in_sandbox from env
# when SANDBOX_VOLUMES is set without an explicit /workspace mount.
if (
isinstance(sub_config, OpenHandsConfig)
and field_name == 'workspace_mount_path_in_sandbox'
):
vols = env_or_toml_dict.get('SANDBOX_VOLUMES')
if vols and '/workspace' not in str(vols):
# Skip overriding; keep the default '/workspace'
continue
# convert the env var to the correct type and set it
value = env_or_toml_dict[env_var_name]

21
poetry.lock generated
View File

@@ -5152,8 +5152,11 @@ files = [
{file = "lxml-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121"},
{file = "lxml-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872"},
{file = "lxml-5.4.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e"},
{file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:891f7f991a68d20c75cb13c5c9142b2a3f9eb161f1f12a9489c82172d1f133c0"},
{file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92"},
{file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:ac7ba71f9561cd7d7b55e1ea5511543c0282e2b6450f122672a2694621d63b7e"},
{file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5"},
{file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:ce31158630a6ac85bddd6b830cffd46085ff90498b397bd0a259f59d27a12188"},
{file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6"},
{file = "lxml-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063"},
{file = "lxml-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49"},
@@ -5227,6 +5230,22 @@ files = [
[package.dependencies]
cobble = ">=0.1.3,<0.2"
[[package]]
name = "markdown"
version = "3.8.2"
description = "Python implementation of John Gruber's Markdown."
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "markdown-3.8.2-py3-none-any.whl", hash = "sha256:5c83764dbd4e00bdd94d85a19b8d55ccca20fe35b2e678a1422b380324dd5f24"},
{file = "markdown-3.8.2.tar.gz", hash = "sha256:247b9a70dd12e27f67431ce62523e675b866d254f900c4fe75ce3dda62237c45"},
]
[package.extras]
docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"]
testing = ["coverage", "pyyaml"]
[[package]]
name = "markdown-it-py"
version = "3.0.0"
@@ -11766,4 +11785,4 @@ third-party-runtimes = ["daytona", "e2b", "modal", "runloop-api-client"]
[metadata]
lock-version = "2.1"
python-versions = "^3.12,<3.14"
content-hash = "8568c6ec2e11d4fcb23e206a24896b4d2d50e694c04011b668148f484e95b406"
content-hash = "d83111cc28bf935f1c759d3ce07a21c69a85f6df035db26042326bd8fba4969f"

View File

@@ -58,6 +58,7 @@ whatthepatch = "^1.0.6"
protobuf = "^5.0.0,<6.0.0" # Updated to support newer opentelemetry
opentelemetry-api = "^1.33.1"
opentelemetry-exporter-otlp-proto-grpc = "^1.33.1"
markdown = "^3.6" # Required for CLI TUI rendering
libtmux = ">=0.37,<0.40"
pygithub = "^2.5.0"