pnpm run build --if-present passes --if-present as an arg to the
build script (tsc), causing TS5023. The correct syntax is
pnpm run --if-present build.
Each package is now bumped independently. Dependent packages use
version ranges (e.g. cua-computer>=0.4.0) and pip resolves the
latest at install time.
Changes:
- Remove cascade bump steps (core→computer→agent, som→agent, npm/core→npm/computer)
- Simplify tag collection to HEAD only (single tag per bump)
- Simplify version capture conditions to match only own service
- Remove cascade dedup from release-on-merge.yml
* feat: auto-release on PR merge with required release labels
- Add CI check that requires a release label (release:patch, release:minor,
release:major, or no-release) on PRs that change publishable packages
- Add workflow that triggers release-bump-version on merge based on label
- Cascade dedup prevents double-bumping (e.g., core change won't also
separately bump computer/agent since the cascade handles it)
* refactor: use per-package release labels instead of global bump labels
- release:pypi/cli, release:pypi/agent, etc. for each service
- bump:minor / bump:major modifiers (default patch)
- no-release covers all packages as opt-out
- CI check verifies each affected package has its own label
- Merge workflow reads release:<service> labels and triggers bumps
* refactor: drop blocking CI check, add Slack reminder for unreleased packages
- Remove ci-require-release-label.yml (no longer blocks merge)
- Release labels are now opt-in: add release:<service> to auto-publish on merge
- Unlabeled affected packages trigger a Slack alert via AlertManager (am.cua.ai)
- no-release label still skips everything
* feat: daily Slack digest for unreleased package changes
Runs Mon-Fri at 9am UTC. For each package, compares latest tag to HEAD
and counts commits in the package directory. Posts a summary to Slack
via AlertManager listing packages with unreleased changes.
Also supports manual trigger via workflow_dispatch.
* chore: change unreleased digest schedule to 8pm PT
* feat: non-blocking CI check that reminds about publishable package changes
Posts a PR comment listing affected packages as a checklist.
Packages with release:<service> labels show as checked.
Updates on each push and label change. Never blocks merge.
* refactor: remove per-merge Slack alert, rely on daily digest instead
* fix: suppress noisy telemetry logs and redact passwords from JSON output
- Set default log level to WARNING so INFO-level telemetry/module_init
messages from computer and core.telemetry don't spam stderr
- Redact password and vnc_url from JSON output in `cua sb list --json`
and `cua sb get --json` unless --show-passwords is explicitly passed
(table view already did this correctly)
* fix: return exit code 1 for not_found in JSON mode for sb get
* fix: use Rich markup instead of raw ANSI codes in platform list
The platform list was using raw ANSI escape codes (\033[91m etc.) for
colored status text, but the rest of the CLI uses Rich Console. This
caused the escape codes to render as literal text. Switch to Rich
markup ([red], [green], [dim], [yellow]) for consistent output.
* fix: explicitly silence noisy loggers by name
basicConfig alone doesn't work because the computer and core.telemetry
modules configure their own handlers at import time. Explicitly set
WARNING level on those specific loggers.
* fix: sb get overwrites valid status with not_found from direct probe
When get_vm() probe returns not_found (e.g. VM still booting), it was
overwriting the correct status from list_vms(). Now only merge the
probe status if it's a real status, not not_found.
* fix: always construct VNC URL from host instead of using API vnc_url
The API returns vnc_url with the stale domain containers.cloud.trycua.com
while host uses the correct sandbox.cua.ai domain. Always build the VNC
URL from the host field.
* fix: ANSI escape codes and --json flag in image list --local
- Replace raw ANSI escape codes with Rich markup in local image list
- Fix --json flag being ignored (was checking args.format instead of args.json)
* fix: isort formatting for local_image imports
The cua-cli Python package had a CD workflow (cd-py-cli.yml) and
bumpversion config but was missing from the release-bump-version.yml
dropdown, making it impossible to trigger a release from the UI.
Replace min-w-[5.5rem] with whitespace-nowrap on the site name span.
The min-width was added to prevent layout shift but caused too much
gap for short names like "Cua". whitespace-nowrap achieves the same
shift prevention without forcing extra width.
* fix: remove message filtering that was causing variable reference error
Removed filterEmptyMessages call and use messages directly. This fixes
the build error where filteredMessages was undefined after previous
partial changes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Claude auto-fix CI workflow
Adds a GitHub Actions workflow that automatically attempts to fix CI
failures on PRs labeled with "auto-fix". Uses Claude Code with sandbox
runtime to analyze failure logs and push fixes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: only trigger auto-fix on pull_request labeled event
Remove the workflow_run trigger that fired on every CI failure.
The workflow now only runs when the 'auto-fix' label is added to a PR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* change back
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Add computer property to draftChat in Playground.tsx to fix
"Please select a computer" error when sending messages from empty state
- Prefer running computers, fall back to first available
- Make baseUrl optional in InferenceConfig type since computer server
has a default inference endpoint (https://inference.cua.ai/v1)
Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* feat: auto-generated SDK docs, Python CLI, and docs improvements
- Add auto-generated SDK reference pages (computer-sdk, agent-sdk) with version selector
- Add Python CLI package (cua-cli) with auth, sandbox, image, MCP commands
- Deprecate TypeScript CLI in favor of Python CLI
- Add versioned docs (agent-sdk v0.3-v0.7, computer-sdk v0.3-v0.5)
- Rename cloud-cli to cli in docs
- Add mobile header fix with sidebar toggle
- Restructure guide pages (quickstart, self-hosted-sandboxes)
- Add redirects for old /api URLs
- Update workflows, lume docs, cuabench docs, desktop sandbox docs
* refactor: auto-generate CLI index page like computer/agent SDKs
Change CLI docs to use the same auto-generated index.mdx pattern as
computer-sdk and agent-sdk. Removes hand-written index page that could
become stale, and deletes the separate api.mdx.
* fix: rename "Cua Bench API Reference" to "API Reference" in menu
* fix: update lume examples to macos-tahoe-vanilla and shorten page titles
- Replace macos-sequoia-vanilla:latest with macos-tahoe-vanilla:latest
in lume docs and generator
- Rename "Lume CLI Reference" to "CLI Reference"
- Rename "Lume HTTP API Reference" to "API Reference"
* feat: rename CuaBot to Cua-Bot and add to dropdown selector
- Rename CuaBot to Cua-Bot in docs meta.json and content pages
- Add Cua-Bot entry to the header dropdown selector
* refactor: restructure Cua-Bot docs to match Cua/Cua-Bench pattern
Reorganize cuabot docs from flat structure into guide/getting-started/
hierarchy matching other collections:
- cuabot.mdx → guide/getting-started/introduction.mdx
- install.mdx → guide/getting-started/installation.mdx
- Add meta.json files with proper icons and structure
- Update dropdown selector href to new path
* feat(docs): add auto-generated API reference, changelog, and versioning for Cua-Bot
Add TypeScript SDK doc generator (regex-based, no compiler dependency) and
configure cuabot for changelog generation and versioned docs snapshots.
* feat(ci): add cuabot to docs drift check and improve failure message
Wire cuabot into CI path triggers, runner config, and changed-file
detection. Add --check mode to typescript-sdk.ts for drift comparison.
Update failure banner with per-library and versioning commands.
* fix: resolve Python lint issues (black, ruff)
Run black formatting on 12 files, fix ruff F841 (unused variables) in
tests, and add TYPE_CHECKING import for FastMCP forward references.
* fix: resolve TS typecheck and Lume Swift 6 CI failures
- typescript-typecheck.js: build @trycua/core before running typecheck
so its dist/ type declarations are available for @trycua/computer
- SSHClient.swift: avoid crossing Sendable boundary with NIOSSHHandler
by keeping handler access + createChannel within flatMap on the event
loop, fixing Swift 6 strict concurrency errors
* fix: TS typecheck pnpm version strict mode and Lume mock conformance
- Set COREPACK_ENABLE_STRICT=0 in typecheck script to allow pnpm 9.x
to run commands in workspace packages declaring pnpm 10.x
- Update MockVNCService.sendText signature to match protocol (add
delayMs parameter)
* fix: run prettier formatting and ignore auto-generated docs files
Format all files to pass prettier 3.8.1 check. Add docs/.source/ and
docs/next-env.d.ts to .prettierignore (auto-generated, not editable).
* fix: restore MDX comment syntax broken by prettier
Prettier 3.8.1 converts {/* */} to {/_ _/} in MDX files, which breaks
the acorn parser. Restore all comments and add *.mdx to .prettierignore.
* fix: regenerate docs to pass drift check after prettier revert
* fix: CI docs check fetch-depth, regenerate Lume docs, fix header layout shift
- Use fetch-depth: 0 in CI checkout so git tags are available for
version discovery (was using fetch-depth: 2, causing version fallback)
- Regenerate Lume docs from local Swift build (0.2.75 → 0.2.76)
- Fix header product selector layout shift with consistent icon/text sizing
* fix: format custom-header.tsx with prettier
* fix: use arch-agnostic JAVA_HOME for arm64 Docker build
The openjdk package writes the arch-specific path (e.g. java-17-openjdk-amd64)
to /etc/environment, which sdkmanager sources, overriding the Dockerfile ENV.
Create an arch-agnostic symlink and re-export JAVA_HOME in the sdkmanager RUN
step to ensure it works on both amd64 and arm64.
* fix: skip emulator package on arm64 (not available for that arch)
The Android emulator SDK package is only published for amd64.
Conditionally install it based on dpkg --print-architecture.
* ci: retrigger cuabot docker build
* Fix model selection state propagation and persistence
- Update chatStateRef synchronously during render instead of in useEffect
to prevent stale closure issues when user changes model picker
- Use ref in sendAgentRequest to always get latest model/computer
- Add user-friendly error messages when model or computer is not selected
- Persist model/computer picker changes to storage for existing chats
- Fix type errors: use status check directly instead of isVM for ComputerInfo
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* Fix new chat creation to include computer
When creating a new chat from the sidebar, include the selected computer
so the chat can be used immediately without manually selecting a sandbox.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* Prefer running VM when initializing playground
When no VM is explicitly selected, prefer the first running VM over
the first VM in the list. This ensures the iframe displays a usable VM.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* Fix VM status banner to use selected computer from dropdown
Pass the currently selected computer from the dropdown to the VM status
banner, so it updates immediately when user selects an offline sandbox.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* Improve ReplayTrajectoryModal UI for compact states
Use smaller modal size when showing loading, empty, or no-screenshot
states instead of always using the large viewer size.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* Fix empty state and existing chat model/computer propagation
- Pass model and computer from empty state picker to chat creation
- Sync computer from global state when chat doesn't have one stored
- Ensures existing chats without stored computer use the currently
selected computer from the dropdown
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Update FastMCP transport from "sse" to "streamable-http" in main.py
- Update all client integration URLs from /sse to /mcp endpoint
- Update CopilotKit MCP server config to use streamable-http type
- Update documentation for Cursor, Claude Code, Claude Desktop,
Windsurf, Cline, GitHub Copilot, and generic MCP clients
https://claude.ai/code/session_012FZDqv4rbviQN2dTY6wPNA
Co-authored-by: Claude <noreply@anthropic.com>
* feat(kasm): add cua-agent dependency and enable computer-server and
agent auto-update on startup
* feat(xfce): add agent dependency & enable computer-server and agent
auto-update on startup
* feat(qemu-android): add agent dependency & enable computer-server and agent auto-update on startup
* feat(qemu-linux): add agent dependency & enable auto-update on startup
* feat(qemu-windows): add agent dependency & enable auto-update on startup
* fix(xfce): use sudo for package upgrades
* perf(kasm): optimize startup time by installing packages after HOME switch
- Move uv and package installation to after HOME=/home/kasm-user switch - Clean up uv cache (~8GB) after installation to prevent profile bloat
- Add sudo to auto-update command in startup script
- Only chown .cache directory instead of all files to avoid bus errors
This prevents packages from polluting kasm-default-profile, making
container startup 67% faster while maintaining auto-update functionality.
* fix(playground): respect model picker selection in agent server
The playground server was reusing a pre-configured agent instance
regardless of which model was selected in the UI. This caused the
wrong model to be used when switching between models.
Now checks if the pre-configured agent's model matches the requested
model before reusing it. If the model differs, creates a new agent
with the correct model.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* fix(playground): sync iframe VM when switching between chats
The VNC iframe was stuck showing the first VM instead of switching
to show the correct VM for each chat. This happened because
currentComputerId (global state) wasn't syncing with each chat's
associated computer (per-chat state).
Added an effect that automatically updates currentComputerId when
the active chat changes, ensuring the iframe displays the correct
VM for each chat.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* fix(playground): prevent starting chats with stopped VMs in empty state
Users could start a chat from the empty state even when the selected
VM was stopped, causing requests to fail when hitting the computer
server.
Added validation to check VM status before creating a chat with a
first message. Shows a toast notification explaining the VM needs
to be started first.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* fix(playground): prevent creating chats with stopped VMs from sidebar
Users could click the "New Chat" button when the VM was stopped,
creating a chat that would fail when trying to send messages.
Added validation to check VM status before creating a new chat from
the sidebar. Shows a toast notification explaining the VM needs to
be started first.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* fix(playground): respect selected VM when creating chats
Chat creation was ignoring the user's VM selection (currentComputerId)
and always using the first available or first running VM instead. This
caused a state inconsistency where selecting VM 2 in the dropdown would
still create chats on VM 1.
The auto-sync effect would then "correct" the global state to match the
chat's VM, overriding the user's selection and switching the iframe.
Updated chat creation logic to prioritize currentComputerId (the user's
selection) before falling back to running/first VM. This ensures the
selected VM is respected when creating new chats.
Changes:
- PlaygroundContent: Use currentComputerId first when creating chats
- ChatSidebar: Use currentComputerId first when creating empty chats
- Added currentComputerId to useCallback dependencies
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* fix(playground): restore chat area scrolling
The chat messages area was not scrollable due to incorrect component
structure. ChatContent was adding an extra wrapper div that broke the
flexbox scroll layout.
Fixed by matching the main branch structure:
- ChatContent now returns a fragment instead of a wrapper div
- ChatArea has min-h-0 to allow shrinking below content height
- This allows overflow-y-auto to work correctly in the flex layout
The proper hierarchy is:
motion.div (overflow-hidden)
└─ ChatProvider
└─ Fragment (from ChatContent)
├─ ChatArea (flex-1 min-h-0 overflow-y-auto)
└─ Input (flex-shrink-0)
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* add cuabot screenshot
* Simplify cuabot system prompt, add npx skills for agent-browser and agent-device, add lazy installation and caching of android images
* fix missing line in bump workflow
* add cuabot screenshot
* Simplify cuabot system prompt, add npx skills for agent-browser and agent-device, add lazy installation and caching of android images
* feat(playground): add package foundation and type definitions
Set up @trycua/playground package structure with:
- package.json with React peer deps and build tooling
- tsconfig.json and tsdown.config.ts for TypeScript/bundling
- Type definitions copied from cloud repo (Chat, Computer, etc.)
- Adapter interface contracts (PlaygroundAdapters, PersistenceAdapter,
ComputerAdapter, InferenceAdapter)
- Re-exports of message types from @trycua/agent
This establishes the foundation for the playground migration,
enabling Agents B, C, D to build adapters, components, and hooks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): implement local and cloud adapters
Add adapter implementations for the playground package:
Local adapter (src/adapters/local.ts):
- LocalPersistenceAdapter: localStorage-based chat persistence
- LocalComputerAdapter: user-provided computer URLs with health checks
- LocalInferenceAdapter: user-provided API keys (Anthropic, OpenAI)
- createLocalAdapter() factory function
Cloud adapter (src/adapters/cloud.ts):
- CloudPersistenceAdapter: CUA API calls to /v1/playground/*
- CloudComputerAdapter: CUA API calls to /v1/vms
- CloudInferenceAdapter: cloud-managed API keys with /v1/models
- createCloudAdapter() factory function
Also includes:
- localStorage utilities copied from cloud repo (verbatim)
- Barrel exports for adapters and utilities
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): add primitive UI components
Add reusable primitive components copied from cloud repo:
- ChatMessage: renders user/assistant messages with tool call display
- ChatInput: textarea with model/computer selectors
- ToolCallsGroup: expandable tool call viewer with screenshots
- VNCViewer: memoized iframe for VNC display
- ThinkingIndicator: animated thinking state with scrambled text
- ThinkingCompleteAnimation: completion animation
- ScrambledText: typewriter effect component
Also add utilities:
- cn: tailwind class merging (clsx + tailwind-merge)
- processMessagesForRendering: groups messages and tool calls
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): add state management, hooks, and composed components
Add context providers, hooks, and composed components for the playground:
Context:
- PlaygroundContext: Global state types and context definitions
- PlaygroundProvider: Manages chats, computers, models via adapters
- ChatProvider: Per-chat state with message processing
Hooks:
- usePlayground: Access playground context (adapters, state, dispatch)
- useChat/useChatDispatch: Per-chat state access
- useAgentRequest: Agent loop with abort/retry handling
- Helper hooks: useActiveChat, useIsChatGenerating, etc.
Composed Components:
- ChatPanel: Main chat interface with model/computer selection
- ChatList: Chat sidebar with create/delete functionality
- ComputerList: Computer sidebar with status display
Modals:
- SettingsModal: Placeholder settings dialog
- CustomComputerModal: Add custom computer dialog
Main Component:
- Playground: Composition component with slot support for customization
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): add link:global convenience script
Adds a convenience script for developers to register the playground
package globally for cross-repo development with the cloud repo.
Usage: pnpm link:global
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): add trajectory viewer, modals, and telemetry
Add components for viewing and exporting agent trajectories:
- TrajectoryViewer: Replay agent actions with cursor animations
- ExportTrajectoryModal: Export trajectories as ZIP files
- ReplayTrajectoryModal: In-browser trajectory replay
- Modal and Button UI components
Add telemetry integration:
- TelemetryProvider with PostHog
- usePlaygroundTelemetry hook for tracking events
Add trajectory utilities:
- inferRuns: Extract runs from message arrays
- TrajectoryRun type definitions
New dependencies: posthog-js, @radix-ui/react-slot, class-variance-authority
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(playground): add cloud-compatible components and local example
Components:
- Add PlaygroundContent and PlaygroundLayout for cloud integration
- Add ChatContent, ChatArea, ChatSidebar components
- Add VMStatusBanner, VNCOverlayPanel, DeferredChatsLoader
- Add UI primitives: dialog, dropdown-menu, select, tooltip, skeleton
- Add CountdownTimer for request timing display
Local example:
- Add examples/local with Vite setup for standalone testing
- Support API key configuration via settings modal
- Enable local development without cloud infrastructure
Improvements:
- Export ChatProvider for nested usage in cloud route
- Add proper TypeScript exports for all new components
- Update telemetry provider with simplified interface
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
* ci(playground): add npm release automation
Add release infrastructure for @trycua/playground:
- .bumpversion.cfg for version management
- cd-ts-playground.yml workflow triggered by npm-playground-v* tags
- Add npm/playground to release-bump-version.yml options
To publish:
1. First release: manually trigger cd-ts-playground workflow
2. Future releases: use bump version workflow with npm/playground
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix api key issues, toast errors, improve telemetry callbacks
* fix(playground): fix VNC iframe not updating when VM changes
The VNC iframe was not updating when switching VMs from the dropdown due to
three issues:
1. Iframe not remounting: Browsers don't always reload iframe content when
only the src attribute changes. Added key={src} to force React to remount
the iframe when the URL changes.
2. State sync mismatch: The Select dropdown used selectedComputer from chat
state while the VNC viewer used currentComputerId from playground state.
Updated ChatContent to prefer currentComputerId from playground state as
the source of truth, ensuring both stay in sync.
3. Missing state dispatch: ChatPanel and EmptyState weren't dispatching
SET_CURRENT_COMPUTER to playground state when the computer changed.
Added the dispatch calls to keep playground state updated.
Changes:
- Add key={src} to iframe elements in VNCIframe and VNCViewer
- Sync Select dropdown with playground state's currentComputerId
- Dispatch SET_CURRENT_COMPUTER in ChatPanel and EmptyState handlers
* feat(playground): add renderThemeToggle prop for animated theme switching
- Add renderThemeToggle prop to PlaygroundLayout and PlaygroundContent
- Allows consumers to provide custom animated theme toggle buttons
- Falls back to default button if not provided
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add CloudV2 provider with new cua.sh domain format
- Add CLOUDV2 to VMProviderType enum
- Create CloudV2Provider class using {name}-api.cua.sh:443 for API
and {name}-vnc.cua.sh:443 for VNC endpoints
- Update VMProviderFactory to support cloudv2 provider type
- Update Computer class to handle cloudv2 provider with proper
api_key handling and port 443 default
- Fix provider_type string to enum normalization to ensure
consistent comparisons for cloud providers
https://claude.ai/code/session_01BDyNF14Hq8eidGCpZAKPUY
* Fix playwright_exec to use _api_port instead of hardcoded port
The playwright_exec method was hardcoding port 8443 for HTTPS connections,
but cloudv2 provider uses port 443. This fix uses the _api_port attribute
when set, falling back to the previous behavior for backwards compatibility.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix Python lint and test failures in CI
- Fix isort import ordering issues across 6 files
- Fix black formatting across 18 files (some pre-existing issues)
- Fix ruff E741 ambiguous variable name in overlay-cursor.py
- Fix ruff F841 unused variable warning in adobe_photoshop.py
- Fix test_tool_resolution.py tests that were checking deferred behavior:
- Tests now properly call _resolve_tools() since tool resolution is
async and deferred to _initialize_computers()
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Onboarding was being skipped when telemetry hadn't been configured yet.
Added isTelemetryConfigured() check to ensure users are prompted for
telemetry preference before the agent starts.
* Add Docker image pull to onboarding flow
Pre-pull trycua/cuabot:latest during onboarding so users don't hit
a timeout on first run. The image is ~2GB and can take a while to
download, which was causing the server startup to appear stuck.
Changes:
- Add checkDockerImage() and pullDockerImage() to utils.ts
- Add "Docker Image" check to onboarding after Docker check
- Show pull progress in the onboarding UI
* Fix xattr command for macOS Xpra quarantine removal
* Fix xattr command - remove invalid -r flag
* fix: always check dependencies before skipping onboarding
Previously, onboarding was only shown when no default agent was set
or alias needed setup. This allowed the CLI to skip onboarding and
try to run the agent even when critical dependencies (Docker, Xpra,
Playwright, Docker Image) were missing.
Now checkDependencies() is called before deciding to skip onboarding,
and also updated to check Playwright and Docker Image in addition
to Docker and Xpra.