* feat: add first-use telemetry tracking with consent - Add telemetry service with consent management (src/services/telemetry.ts) - Add useTelemetry React hook for easy integration (src/hooks/use-telemetry.ts) - Add TelemetryConsentBanner component with i18n support - Add local development server for testing (scripts/telemetry-dev-server.mjs) - Add comprehensive tests for telemetry service and hook - Export telemetry utilities from library index - Respect DO_NOT_TRACK environment variable for privacy - Uses localhost:8080 endpoint for development Co-authored-by: openhands <openhands@all-hands.dev> * fix: address PR review feedback - Make TELEMETRY_ENDPOINT configurable via VITE_TELEMETRY_ENDPOINT env var - Make POSTHOG_API_KEY configurable via VITE_POSTHOG_API_KEY env var - Add validation to skip telemetry if API key not configured (except localhost) - Fix DO_NOT_TRACK to work in browser environments using VITE_DO_NOT_TRACK - Also respect browser's navigator.doNotTrack standard - Update consent banner hint text to reference correct env var - Add documentation comments for all configuration options Co-authored-by: openhands <openhands@all-hands.dev> * feat: hardcode PostHog credentials for centralized telemetry - Use OpenHands PostHog project API key for all library users - Use PostHog US Cloud endpoint (https://us.i.posthog.com/capture) - Remove environment variable configuration for endpoint/API key - Telemetry now automatically sends to centralized project when consent granted - Users can still opt out via UI, VITE_DO_NOT_TRACK, or browser DNT setting Co-authored-by: openhands <openhands@all-hands.dev> * feat: use separate PostHog API keys for dev and production - Dev environment: phc_kBtz5nKmxVRRQ7HtPwr2QX9eMC5j65zE86QKocVNwb4U - Production: phc_BgzfxKdgsYMLFTmJqt424ZoyVHvKFfrwttLimzdYTKFK - Automatically selects key based on import.meta.env.DEV Co-authored-by: openhands <openhands@all-hands.dev> * chore: use single production PostHog API key everywhere Simplify by using the same API key for all environments. Co-authored-by: openhands <openhands@all-hands.dev> * chore: rename telemetry events - library_first_use → canvas_install - library_session_start → canvas_new_session Co-authored-by: openhands <openhands@all-hands.dev> * feat: migrate telemetry to PostHog SDK Replace raw HTTP requests with PostHog SDK for: - Automatic event batching - Built-in retry logic with exponential backoff - Offline support (queues events, sends when back online) - Automatic session tracking - Better device/browser info enrichment Benefits: - More reliable event delivery - Reduced network requests - Cleaner code with less manual state management - Future-proof for feature flags, session replay, etc. Co-authored-by: openhands <openhands@all-hands.dev> * refactor: remove redundant hasTrackedFirstUse state in hook The trackFirstUse() function already has built-in deduplication via localStorage, so the local React state was unnecessary. Simplified the hook and added a comment explaining the deduplication mechanism. Co-authored-by: openhands <openhands@all-hands.dev> * chore: remove obsolete telemetry dev server The local dev server was used when telemetry used raw HTTP requests to a configurable endpoint. Now that we use the PostHog SDK with the real PostHog endpoint, this is no longer needed. Co-authored-by: openhands <openhands@all-hands.dev> * fix: remove trailing comma in package.json Co-authored-by: openhands <openhands@all-hands.dev> * fix: address PR review feedback - Make POSTHOG_API_KEY configurable via VITE_POSTHOG_API_KEY env var - Make POSTHOG_HOST configurable via VITE_POSTHOG_HOST env var - Add session deduplication using sessionStorage to prevent duplicate canvas_new_session events from multiple hook instances - Clear sessionStorage in clearTelemetryData() Co-authored-by: openhands <openhands@all-hands.dev> * fix: use dynamic imports for PostHog SSR compatibility - Convert top-level posthog-js import to dynamic import for SSR safety - Add getPostHog() lazy loader that only imports in browser context - Make setTelemetryConsent, clearTelemetryData, getPostHogInstance async - Update documentation to clarify default telemetry destination - Update tests for async function signatures This ensures the library works correctly in SSR frameworks (Next.js, Remix, etc.) that might import this module server-side. Co-authored-by: openhands <openhands@all-hands.dev> * feat: add telemetry consent banner to app layout The consent banner now appears on all pages until the user explicitly accepts or declines telemetry. This ensures users are always prompted for consent on their first visit regardless of which page they land on. Co-authored-by: openhands <openhands@all-hands.dev> * refactor: update telemetry consent banner to modal style - Changed from bottom banner to centered modal overlay (matching OpenHands) - Uses ModalBackdrop, ModalBody, BaseModalTitle, BaseModalDescription - Single checkbox with 'Confirm preferences' button pattern - Full-screen overlay blocks interaction until user makes a choice - Added i18n keys: TELEMETRY$SEND_ANONYMOUS_DATA, TELEMETRY$CONFIRM_PREFERENCES Co-authored-by: openhands <openhands@all-hands.dev> * fix: ensure PostHog is initialized before tracking events - Made grantConsent/denyConsent in useTelemetry hook async to ensure PostHog initialization completes before state update triggers tracking - Updated tests for async consent functions - This fixes a race condition where trackFirstUse() could be called before PostHog's opt_in_capturing() had been executed Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev>
agent-canvas
Warning
This project is in an early incubator phase. It may be vibecoded, untested, or out of date. OpenHands takes no responsibility for the code or its support. Learn more.
Quickstart
This repository is a near-direct port of the OpenHands frontend adapted to talk directly to software-agent-sdk / agent_server without the usual OpenHands app backend.
Prerequisites
- Node.js 22.12.x or later
npmuv(for running the agent server viauvx)
1. Clone and install the frontend
git clone https://github.com/OpenHands/agent-canvas.git
cd agent-canvas
npm install
2. Install uv
If you do not already have uv installed, install it first (OpenHands SDK recommends uv 0.8.13+):
curl -LsSf https://astral.sh/uv/install.sh | sh
Need Windows or another install method? See the official uv installation guide: https://docs.astral.sh/uv/getting-started/installation/
If ~/.local/bin is not already on your PATH, add it:
export PATH="$HOME/.local/bin:$PATH"
command -v uvx
The npm run dev command uses uvx to automatically download and run the agent server, so no separate installation step is needed.
3. Optional: create a .env file
If you need to change the backend URL, frontend port, session API key, or working directory, copy the sample file:
cp .env.sample .env
Then edit the values you need.
4. Start the app
npm run dev
This starts the full stack:
- Agent server (via uvx)
- Automation backend (via uvx)
- Vite dev server
- Ingress proxy (routes traffic to all backends)
Access the UI at http://localhost:8000
Environment Variables
| Variable | Description | Default |
|---|---|---|
PORT |
Ingress port | 8000 |
OH_AUTOMATION_GIT_REF |
Git ref for automation backend | main |
OH_AGENT_SERVER_GIT_REF |
Git ref for agent-server | main |
5. First-run sanity check
After the page opens:
/should load without errors/settingsshould load- configure a working LLM model + API key under
Settings > LLMbefore running the first live task - you should be able to open or create a conversation
/api/automation/docsshould show the automation API docs
Alternative: Minimal Mode (without Automation)
To run without the automation service:
npm run dev:minimal
This runs only agent-server + Vite (no automation backend or ingress).
Access at http://localhost:3001/
More documentation
For contributor and developer workflows, including frontend-only mode, mock mode, environment variables, and build/test commands, see DEVELOPMENT.md.