* Add recommended automations marketplace flow
Co-authored-by: openhands <openhands@all-hands.dev>
* Update GitHub MCP QA findings
Co-authored-by: openhands <openhands@all-hands.dev>
* Polish MCP and automation marketplace UI
Add a shared MCP logo badge, make marketplace cards more compact, and show required MCP logos prominently on recommended automation cards. Update the extensions package lock to the per-entry catalog split and save QA screenshots/results in .pr/.
Co-authored-by: openhands <openhands@all-hands.dev>
* Align recommended automations styling
Remove the custom gradient treatment and match the recommended automation cards and setup modal to the existing Automations and MCP page surfaces, spacing, borders, and typography.
Co-authored-by: openhands <openhands@all-hands.dev>
* Show existing automations before recommendations
Move the recommended automations section below the current automation list and creation guidance so the page prioritizes the user existing automation state.
Co-authored-by: openhands <openhands@all-hands.dev>
* Add recommendations to onboarding
Show recommended automations below the Say Hello input so new users can launch a curated automation from the final onboarding step.
Co-authored-by: openhands <openhands@all-hands.dev>
* Use extensions MCP marketplace exports
Remove the local MCP marketplace wrapper and consume MCP catalog data plus logo mappings directly from @openhands/extensions/mcps.
Co-authored-by: openhands <openhands@all-hands.dev>
* Archive previous PR QA and add refreshed artifacts
Co-authored-by: openhands <openhands@all-hands.dev>
* Add scheduled automation QA evidence
Co-authored-by: openhands <openhands@all-hands.dev>
* Streamline recommended automation launch
Co-authored-by: openhands <openhands@all-hands.dev>
* Refresh QA evidence and remove old artifacts
Co-authored-by: openhands <openhands@all-hands.dev>
* Ensure canvas tools are on Python path
* Require MCP installs before launching recommendations
* Remove archived PR artifacts
* Drop redundant PYTHONPATH launcher changes
* Inline recommended automation catalog
* Point extensions dependency at main
* Augment recommended automation prompts with explicit API instructions
When a recommended automation is selected, the pre-filled prompt now
includes backend-specific API instructions so the agent calls the
correct endpoint:
- Local backends: directs the agent to use the local automation API
from <RUNTIME_SERVICES> with $OPENHANDS_AUTOMATION_API_KEY auth,
and explicitly tells it NOT to call the cloud API at app.all-hands.dev.
- Cloud backends: directs the agent to use the OpenHands Cloud
Automations API at app.all-hands.dev with Bearer $OPENHANDS_API_KEY.
The buildAutomationPrompt() helper is exported for testability.
Three new unit tests cover both backend kinds and prompt preservation.
Co-authored-by: openhands <openhands@all-hands.dev>
* Fix recommended automation launch regressions
Co-authored-by: openhands <openhands@all-hands.dev>
* Expose local automation API key to agent terminals
Co-authored-by: openhands <openhands@all-hands.dev>
* Stabilize conversation panel stop menu test
Co-authored-by: openhands <openhands@all-hands.dev>
* chore: Remove PR-only artifacts
* fix: pin @openhands/extensions to specific commit for reproducibility
Updates the dependency from #main to the exact commit SHA
(3bba8e3b) that contains the MCP and automation catalogs
added in extensions#237.
This ensures reproducible builds since npm ci will use the
locked SHA instead of potentially picking up a newer main.
* Address final automation marketplace review comments
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: allhands-bot <allhands-bot@users.noreply.github.com>
* feat(ingress): route /docs to the agent server
Add /docs to the list of prefixes proxied to the agent-server in:
- vite.config.ts (Vite dev server proxy)
- scripts/dev-with-automation.mjs (ingress + static-server fallback)
- scripts/dev-static.mjs (ingress + static-server fallback)
Update the explanatory comment in scripts/static-server.mjs to match.
This exposes the agent-server's FastAPI Swagger UI at `/docs` on the
ingress port, alongside the automation backend's existing
`/api/automation/docs`.
Co-authored-by: openhands <openhands@all-hands.dev>
* feat(ingress): also route /redoc and /openapi.json to the agent server
Without /openapi.json, the Swagger UI page served at /docs (added in the
previous commit) renders but fails to load any spec. /redoc is the
FastAPI-served ReDoc alternative and benefits from the same fix.
Routes are added everywhere /docs already is:
- vite.config.ts (Vite dev server proxy)
- scripts/dev-with-automation.mjs (ingress + static-server fallback)
- scripts/dev-static.mjs (ingress + static-server fallback)
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
* fix: move TMUX_TMPDIR to /tmp to avoid socket errors on mounted volumes
Some filesystems (NFS, CIFS, certain FUSE/overlay mounts used by Docker
bind-mounts) do not support Unix domain sockets. When TMUX_TMPDIR pointed
to ~/.openhands/agent-canvas/tmux/ inside a container, tmux failed with:
error connecting to .../tmux-10001/openhands (Operation not supported)
Move tmux socket directory to /tmp/openhands-agent-canvas-tmux which is
always on a local/tmpfs filesystem that supports Unix sockets. Tmux
sockets are ephemeral and don't need persistence across restarts.
Co-authored-by: openhands <openhands@all-hands.dev>
* refactor: drop explicit TMUX_TMPDIR from dev-docker.mjs, use system default
Per review feedback — the container's default TMUX_TMPDIR (/tmp) already
supports Unix domain sockets, so there's no need to set it explicitly.
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
* feat: add dynamic port allocation with preferred port fallback
Implement dynamic port allocation for dev entrypoint scripts to gracefully
handle port conflicts. When a preferred port is busy, the system automatically
finds an alternative available port.
Changes:
- Add findFreePort() and findFreePorts() utilities to dev-safe.mjs
- Add buildSafeDevConfigAsync() for async config with dynamic allocation
- Update dev-with-automation.mjs to use async buildConfig with dynamic ports
- Update dev-static.mjs to use async buildConfig
- Add strictPort: true to vite.config.ts to fail-fast on conflicts
- Update tests for async buildConfig
The utilities try the preferred/default ports first, falling back to
OS-assigned ports only when needed. This preserves predictable defaults
while gracefully handling port conflicts.
Closes#222
* fix: address review feedback - add max retry, document race condition, improve tests
- Add max retry count (100 attempts) to port allocation loop to prevent
infinite loops
- Fix findFreePort to handle preferredPort=0 correctly by skipping the
port check and going straight to OS assignment
- Document race condition limitation in findFreePort JSDoc (accepted
limitation with guidance on handling EADDRINUSE)
- Clarify JSDoc for buildSafeDevConfig vs buildSafeDevConfigAsync with
clear guidance on when to use each
- Remove misleading 'must be after prereq check' comment
- Add comprehensive tests for findFreePort, findFreePorts, and
buildSafeDevConfigAsync using actual port blocking
- Improve buildConfig tests with port uniqueness verification and
fallback tests using high ports
- Use high ports (19xxx range) in tests to avoid conflicts with
system services
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
Mirrors the dev:automation backend stack (agent-server + automation +
ingress) but serves a production frontend build through a small static
server instead of Vite. Designed for use over flaky / high-RTT links
where Vite's ~1000 ESM module fetches make full reloads painfully slow:
hashed assets are now sent with public/immutable cache headers, so an
SPA reload is ~1 round-trip (304 on index.html) and zero asset fetches.
scripts/static-server.mjs: combined static-file server + reverse proxy.
A drop-in for sirv-cli that additionally proxies the same prefixes Vite
proxies in dev (/api, /api/automation, /sockets, /server_info, /alive,
/health, /ready) so hitting :3001 directly behaves like Vite's dev
server — without it, sirv-cli's --single fallback turns /server_info
into the SPA shell whenever a tunnel exposes the static port instead of
the ingress port. Caches /assets/* immutable, index.html no-cache,
weak ETags.
scripts/dev-static.mjs: orchestrator that builds the frontend, then
spawns agent-server, automation, static-server, and the existing
ingress with the same route table as dev-with-automation.
scripts/dev-safe.mjs: add isPortBusy() and
releaseStaleConversationLeases() helpers. The agent-server tags each
conversation directory with an owner_lease.json keyed to a per-process
owner_instance_id (45 s TTL, heartbeat-renewed) and skip-loads any
conversation whose lease is held by a different instance. If the
previous agent-server died ungracefully — or you restart inside the
TTL window — every existing conversation becomes invisible to the new
instance until the leases age out. dev:static now port-checks for a
live agent-server (aborts on conflict), then unlinks stale leases so
conversations created by npm run dev are immediately visible.
Co-authored-by: openhands <openhands@all-hands.dev>