Skip to content

Commit e980c1a

Browse files
docs: rewrite README with concise quickstart and binary build instructions; add Development.md with detailed dev, packaging, and build guidance\n\nCloses #19\n\nCo-authored-by: openhands <openhands@all-hands.dev> (#20)
Co-authored-by: openhands <openhands@all-hands.dev>
1 parent dc017cf commit e980c1a

File tree

2 files changed

+137
-122
lines changed

2 files changed

+137
-122
lines changed

Development.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Development Guide
2+
3+
Detailed guidance for contributors working on the OpenHands CLI.
4+
5+
## 1) Managing dependencies with Poetry/uv
6+
7+
This repo includes both pyproject sections for hatch/uv and Poetry for compatibility.
8+
9+
- Add a runtime dependency (using uv):
10+
```bash
11+
uv add <package>
12+
```
13+
- Add a dev dependency (linters, build tools, etc.):
14+
```bash
15+
uv add --dev <package>
16+
```
17+
- Sync environment:
18+
```bash
19+
uv sync --extra dev
20+
```
21+
22+
If you use Poetry instead of uv:
23+
```bash
24+
poetry add <package>
25+
poetry add --group dev <package>
26+
poetry install
27+
```
28+
29+
Commit the updated pyproject.toml (and lockfile if applicable) with your change.
30+
31+
## 2) Packaging with PyInstaller: spec file tips
32+
33+
PyInstaller uses a spec file (openhands-cli.spec) to describe what to include in the binary.
34+
Two common knobs when something is missing in the built executable:
35+
36+
- hiddenimports: Python modules that PyInstaller fails to detect automatically.
37+
Use when imports are dynamic or optional.
38+
Example in spec:
39+
```python
40+
hiddenimports=[
41+
'openhands_cli.tui',
42+
'openhands_cli.pt_style',
43+
*collect_submodules('prompt_toolkit'),
44+
*collect_submodules('openhands.core'),
45+
*collect_submodules('openhands.tools'),
46+
]
47+
```
48+
49+
- datas (a.k.a. data files): Non-Python files required at runtime (templates, config, etc.).
50+
Use collect_data_files to include them.
51+
Example in spec:
52+
```python
53+
datas=[
54+
*collect_data_files('tiktoken'),
55+
*collect_data_files('openhands.core.agent.codeact_agent', includes=['prompts/*.j2']),
56+
]
57+
```
58+
59+
Differences:
60+
- hiddenimports is for modules to be packaged as bytecode.
61+
- datas is for external resource files copied into the bundle.
62+
63+
If a library fails at runtime with "ModuleNotFoundError" inside the binary, add it to hiddenimports.
64+
If a library complains about missing template/config/resource files, add those paths to datas.
65+
66+
## 3) Build locally and test
67+
68+
- Quick build (recommended):
69+
```bash
70+
./build.sh --install-pyinstaller
71+
```
72+
This ensures PyInstaller is present via uv and then runs build.py.
73+
74+
- Manual build:
75+
```bash
76+
uv add --dev pyinstaller
77+
uv run pyinstaller openhands-cli.spec --clean
78+
```
79+
80+
- Test the binary:
81+
```bash
82+
./dist/openhands-cli # macOS/Linux
83+
# or dist/openhands-cli.exe # Windows
84+
```
85+
86+
If the binary fails to start:
87+
- Run the Python entrypoint to confirm the app itself works:
88+
```bash
89+
uv run openhands-cli
90+
```
91+
- Re-run build with --no-clean to inspect build artifacts, or add more hiddenimports/datas.
92+
93+
## 4) Linting and formatting
94+
95+
- Run all pre-commit hooks:
96+
```bash
97+
make lint
98+
```
99+
- Format code:
100+
```bash
101+
make format
102+
```
103+
104+
## 5) Notes on agent credentials
105+
106+
To actually converse with a model, export one of the supported keys before running the CLI/binary:
107+
```bash
108+
export OPENAI_API_KEY=... # or
109+
export LITELLM_API_KEY=...
110+
```

README.md

Lines changed: 27 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,45 @@
11
# OpenHands CLI
22

3-
A command-line interface for OpenHands AI Agent with Terminal User Interface (TUI) support.
3+
A lightweight CLI/TUI to interact with the OpenHands agent (powered by agent-sdk). Build and run locally or as a single executable.
44

5-
## Development
5+
## Quickstart
66

7-
### Setup
8-
9-
1. Install dependencies:
10-
```bash
11-
make install-dev
12-
```
13-
14-
2. Install pre-commit hooks:
15-
```bash
16-
make install-pre-commit-hooks
17-
```
18-
19-
### Code Quality
20-
21-
This project uses pre-commit hooks to ensure code quality. The following tools are configured:
22-
23-
- **Ruff**: Fast Python linter and formatter
24-
- **MyPy**: Static type checking
25-
- **Pre-commit hooks**: Various code quality checks
26-
27-
#### Running Linters
28-
29-
```bash
30-
# Run all pre-commit hooks
31-
make lint
32-
33-
# Format code
34-
make format # Format code with ruff
35-
```
36-
37-
#### Pre-commit Hooks
38-
39-
Pre-commit hooks will automatically run on every commit. To run them manually:
7+
- Prerequisites: Python 3.12+, curl
8+
- Install uv (package manager):
9+
```bash
10+
curl -LsSf https://astral.sh/uv/install.sh | sh
11+
# Restart your shell so "uv" is on PATH, or follow the installer hint
12+
```
4013

14+
### Run the CLI locally
4115
```bash
42-
# Run on all files
43-
uv run pre-commit run --all-files
44-
45-
# Run on staged files only
46-
uv run pre-commit run
47-
```
48-
49-
### Available Commands
50-
51-
Run `make help` to see all available commands:
52-
53-
```bash
54-
make help
55-
```
56-
57-
## Binary Packaging
58-
59-
The OpenHands CLI can be packaged into a standalone executable binary using PyInstaller. This allows distribution of the CLI without requiring users to install Python or dependencies.
60-
61-
### Building the Executable
62-
63-
#### Quick Build
16+
# Install dependencies (incl. dev tools)
17+
make install-dev
6418

65-
Use the provided build script to create a standalone executable:
19+
# Optional: install pre-commit hooks
20+
make install-pre-commit-hooks
6621

67-
```bash
68-
# Using shell script (recommended - handles installation automatically)
69-
./build.sh --install-pyinstaller
70-
71-
# Using Python script directly (requires PyInstaller to be pre-installed)
72-
uv run python build.py
22+
# Start the CLI
23+
make run
24+
# or
25+
uv run openhands-cli
7326
```
7427

75-
#### Manual Build
76-
77-
You can also build manually using PyInstaller with uv:
78-
28+
Tip: Set your model key (one of) so the agent can talk to an LLM:
7929
```bash
80-
# Install PyInstaller as dev dependency
81-
uv add --dev pyinstaller
82-
83-
# Build using the spec file
84-
uv run pyinstaller openhands-cli.spec --clean
30+
export OPENAI_API_KEY=...
31+
# or
32+
export LITELLM_API_KEY=...
8533
```
8634

87-
### Build Options
88-
89-
The build script supports several options:
90-
35+
### Build a standalone executable
9136
```bash
92-
# Install PyInstaller and build (shell script handles installation)
37+
# Build (installs PyInstaller if needed)
9338
./build.sh --install-pyinstaller
9439

95-
# Build without testing the executable
96-
./build.sh --install-pyinstaller --no-test
97-
98-
# Build without cleaning previous artifacts
99-
./build.sh --install-pyinstaller --no-clean
100-
101-
# Use a custom spec file
102-
./build.sh --install-pyinstaller --spec custom.spec
103-
104-
# Show help
105-
./build.sh --help
40+
# The binary will be in dist/
41+
./dist/openhands-cli # macOS/Linux
42+
# dist/openhands-cli.exe # Windows
10643
```
10744

108-
**Note:** The shell script (`build.sh`) automatically handles PyInstaller installation when using the `--install-pyinstaller` flag. The Python script (`build.py`) can be used directly but requires PyInstaller to be pre-installed.
109-
110-
### Output
111-
112-
The build process creates:
113-
- `dist/openhands-cli` - The standalone executable
114-
- `build/` - Temporary build files (automatically cleaned)
115-
116-
The executable is typically 10-15 MB and includes all necessary dependencies.
117-
118-
### Testing the Executable
119-
120-
The build script automatically tests the executable, but you can also test manually:
121-
122-
```bash
123-
# Run the executable
124-
./dist/openhands-cli
125-
126-
# Check that it displays the CLI interface
127-
```
128-
129-
### Packaging Configuration
130-
131-
The packaging is configured through:
132-
- `openhands-cli.spec` - PyInstaller specification file
133-
- `build.py` - Build automation script
134-
- `build.sh` - Shell wrapper script
135-
136-
The spec file is optimized for:
137-
- Single-file executable
138-
- Minimal size through exclusions
139-
- All required dependencies included
140-
- Console application mode
45+
For advanced development (adding deps, updating the spec file, debugging builds), see Development.md.

0 commit comments

Comments
 (0)