diff --git a/docs/content/docs/agent-sdk/prompt-caching.mdx b/docs/content/docs/agent-sdk/prompt-caching.mdx index 5049b4bb..721895c5 100644 --- a/docs/content/docs/agent-sdk/prompt-caching.mdx +++ b/docs/content/docs/agent-sdk/prompt-caching.mdx @@ -25,7 +25,9 @@ agent = ComputerAgent( When using Anthropic-based CUAs (Claude models), setting `use_prompt_caching=True` will automatically add `{ "cache_control": "ephemeral" }` to your messages. This enables prompt caching for the session and can speed up repeated runs with the same prompt. -> **Note:** This argument is only required for Anthropic CUAs. For other providers, it is ignored. + +This argument is only required for Anthropic CUAs. For other providers, it is ignored. + ## OpenAI Provider diff --git a/docs/content/docs/libraries/lume/cli-reference.mdx b/docs/content/docs/libraries/lume/cli-reference.mdx index 4837d154..5afcc7fe 100644 --- a/docs/content/docs/libraries/lume/cli-reference.mdx +++ b/docs/content/docs/libraries/lume/cli-reference.mdx @@ -3,46 +3,7 @@ title: Lume CLI Reference description: Command Line Interface reference for Lume --- -Lume is a lightweight Command Line Interface and local API server for creating, running and managing **macOS and Linux virtual machines** with near-native performance on Apple Silicon, using Apple's [Virtualization.Framework](https://developer.apple.com/documentation/virtualization). - -## Quick Start - -Install and run a prebuilt macOS VM in two commands: - -```bash -# Install Lume -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" -# Pull & start a macOS image -lume run macos-sequoia-vanilla:latest -``` - -> **Security Note**: All prebuilt images use the default password `lume`. Change this immediately after your first login using the `passwd` command. - -**System Requirements**: -- Apple Silicon Mac (M1, M2, M3, etc.) -- macOS 13.0 or later -- At least 8GB of RAM (16GB recommended) -- At least 50GB of free disk space - -## Install - -Install with a single command: - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" -``` - -By default, Lume is installed as a background service that starts automatically on login. If you prefer to start the Lume API service manually when needed, you can use the `--no-background-service` option: - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh) --no-background-service" -``` - -> **Note:** With this option, you'll need to manually start the Lume API service by running `lume serve` in your terminal whenever you need to use tools or libraries that rely on the Lume API (such as the Computer-Use Agent). - -You can also download the `lume.pkg.tar.gz` archive from the [latest release](https://github.com/trycua/cua/releases?q=lume&expanded=true), extract it, and install the package manually. - -## Using Lume +import { Callout } from 'fumadocs-ui/components/callout'; Once installed, you can start using Lume with these common workflows: @@ -56,7 +17,9 @@ lume run macos-sequoia-vanilla:latest lume run ubuntu-noble-vanilla:latest ``` -> We provide prebuilt VM images in our [ghcr registry](https://github.com/orgs/trycua/packages). + +We provide [prebuilt VM images](../lume/prebuilt-images) in our [ghcr registry](https://github.com/orgs/trycua/packages). + ### Create a Custom VM @@ -68,4 +31,179 @@ lume create my-macos-vm --cpu 4 --memory 8GB --disk-size 50GB lume create my-linux-vm --os linux --cpu 2 --memory 4GB ``` -> **Disk Space**: The actual disk space used by sparse images will be much lower than the logical size listed. You can resize VM disks after creation using `lume set --disk-size `. + +The actual disk space used by sparse images will be much lower than the logical size listed. You can resize VM disks after creation using `lume set --disk-size `. + + +## VM Management + + lume create <name> +Create a new macOS or Linux virtual machine. + +**Options:** +- `--os ` - Operating system to install (macOS or linux, default: macOS) +- `--cpu ` - Number of CPU cores (default: 4) +- `--memory ` - Memory size, e.g., 8GB (default: 4GB) +- `--disk-size ` - Disk size, e.g., 50GB (default: 40GB) +- `--display ` - Display resolution (default: 1024x768) +- `--ipsw ` - Path to IPSW file or 'latest' for macOS VMs +- `--storage ` - VM storage location to use + +**Examples:** +```bash +# Create macOS VM with custom specs +lume create my-mac --cpu 6 --memory 16GB --disk-size 100GB + +# Create Linux VM +lume create my-ubuntu --os linux --cpu 2 --memory 8GB + +# Create macOS VM with latest IPSW +lume create my-sequoia --ipsw latest +``` + + lume run <name> +Start and run a virtual machine. + +**Options:** +- `--no-display` - Do not start the VNC client app +- `--shared-dir ` - Share directory with VM (format: path[:ro|rw]) +- `--mount ` - For Linux VMs only, attach a read-only disk image +- `--registry ` - Container registry URL (default: ghcr.io) +- `--organization ` - Organization to pull from (default: trycua) +- `--vnc-port ` - Port to use for the VNC server (default: 0 for auto-assign) +- `--recovery-mode ` - For macOS VMs only, start VM in recovery mode (default: false) +- `--storage ` - VM storage location to use + +**Examples:** +```bash +# Run VM with shared directory +lume run my-vm --shared-dir /path/to/share:rw + +# Run VM without display (headless) +lume run my-vm --no-display + +# Run macOS VM in recovery mode +lume run my-mac --recovery-mode true +``` + + lume stop <name> +Stop a running virtual machine. + +**Options:** +- `--storage ` - VM storage location to use + +### lume delete <name> +Delete a virtual machine and its associated files. + +**Options:** +- `--force` - Force deletion without confirmation +- `--storage ` - VM storage location to use + +### lume clone <name> <new-name> +Create a copy of an existing virtual machine. + +**Options:** +- `--source-storage ` - Source VM storage location +- `--dest-storage ` - Destination VM storage location + +## VM Information and Configuration + +### lume ls +List all virtual machines and their status. + +### lume get <name> +Get detailed information about a specific virtual machine. + +**Options:** +- `-f, --format ` - Output format (json|text) +- `--storage ` - VM storage location to use + +### lume set <name> +Modify virtual machine configuration. + +**Options:** +- `--cpu ` - New number of CPU cores (e.g., 4) +- `--memory ` - New memory size (e.g., 8192MB or 8GB) +- `--disk-size ` - New disk size (e.g., 40960MB or 40GB) +- `--display ` - New display resolution in format WIDTHxHEIGHT (e.g., 1024x768) +- `--storage ` - VM storage location to use + +**Examples:** +```bash +# Increase VM memory +lume set my-vm --memory 16GB + +# Change display resolution +lume set my-vm --display 1920x1080 + +# Add more CPU cores +lume set my-vm --cpu 8 +``` + +## Image Management + +### lume images +List available macOS images in local cache. + +### lume pull <image> +Download a VM image from a container registry. + +**Options:** +- `--registry ` - Container registry URL (default: ghcr.io) +- `--organization ` - Organization to pull from (default: trycua) +- `--storage ` - VM storage location to use + +### lume push <name> <image:tag> +Upload a VM image to a container registry. + +**Options:** +- `--additional-tags ` - Additional tags to push the same image to +- `--registry ` - Container registry URL (default: ghcr.io) +- `--organization ` - Organization/user to push to (default: trycua) +- `--storage ` - VM storage location to use +- `--chunk-size-mb ` - Chunk size for disk image upload in MB (default: 512) +- `--verbose` - Enable verbose logging +- `--dry-run` - Prepare files and show plan without uploading +- `--reassemble` - Verify integrity by reassembling chunks (requires --dry-run) + +### lume ipsw +Get the latest macOS restore image URL. + +### lume prune +Remove cached images to free up disk space. + +## Configuration + +### lume config +Manage Lume configuration settings. + +**Subcommands:** + +##### Storage Management +- `lume config storage add ` - Add a new VM storage location +- `lume config storage remove ` - Remove a VM storage location +- `lume config storage list` - List all VM storage locations +- `lume config storage default ` - Set the default VM storage location + +##### Cache Management +- `lume config cache get` - Get current cache directory +- `lume config cache set ` - Set cache directory + +##### Image Caching +- `lume config caching get` - Show current caching status +- `lume config caching set ` - Enable or disable image caching + +## API Server + +### lume serve +Start the Lume API server for programmatic access. + +**Options:** +- `--port ` - Port to listen on (default: 7777) + +## Global Options + +These options are available for all commands: + +- `--help` - Show help information +- `--version` - Show version number \ No newline at end of file diff --git a/libs/lume/docs/FAQ.md b/docs/content/docs/libraries/lume/faq.md similarity index 99% rename from libs/lume/docs/FAQ.md rename to docs/content/docs/libraries/lume/faq.md index 21d0d287..98d6b766 100644 --- a/libs/lume/docs/FAQ.md +++ b/docs/content/docs/libraries/lume/faq.md @@ -1,4 +1,6 @@ -# FAQs +--- +title: FAQ +--- ### Where are the VMs stored? diff --git a/docs/content/docs/libraries/lume/http-api.mdx b/docs/content/docs/libraries/lume/http-api.mdx index 5191119c..04792f26 100644 --- a/docs/content/docs/libraries/lume/http-api.mdx +++ b/docs/content/docs/libraries/lume/http-api.mdx @@ -1,9 +1,10 @@ --- title: HTTP Server API -description: Lume exposes a local HTTP API server that listens at localhost for programatic management of VMs. +description: Lume exposes a local HTTP API server that listens at localhost for programmatic management of VMs. --- import { Tabs, Tab } from 'fumadocs-ui/components/tabs'; +import { Callout } from 'fumadocs-ui/components/callout'; ## Default URL @@ -19,11 +20,13 @@ http://localhost:7777 ## Endpoints +--- + ### Create VM Create a new virtual machine. -`POST: /vms` +`POST: /lume/vms` #### Parameters @@ -86,32 +89,34 @@ print(r.json()) ```typescript const payload = { - name: "lume_vm", - os: "macOS", + name: 'lume_vm', + os: 'macOS', cpu: 2, - memory: "4GB", - diskSize: "64GB", - display: "1024x768", - ipsw: "latest", - storage: "ssd" -} + memory: '4GB', + diskSize: '64GB', + display: '1024x768', + ipsw: 'latest', + storage: 'ssd', +}; const res = await fetch('http://localhost:7777/lume/vms', { - methdo: 'POST' - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), }); -console.log(await res.json()) +console.log(await res.json()); ``` +--- + ### Run VM Run a virtual machine instance. -`POST: /vms/:name/run` +`POST: /lume/vms/:name/run` #### Parameters @@ -181,7 +186,7 @@ print(r.json()) ```typescript // Basic run -const res = await fetch('http://localhost:7777/lume/vms/my-vm-name/run', { +let res = await fetch('http://localhost:7777/lume/vms/my-vm-name/run', { method: 'POST', }); console.log(await res.json()); @@ -193,22 +198,24 @@ const payload = { recoveryMode: false, storage: 'ssd', }; -const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm/run', { +res = await fetch('http://localhost:7777/lume/vms/lume_vm/run', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); -console.log(await res2.json()); +console.log(await res.json()); ``` +--- + ### List VMs List all virtual machines. -`GET: /vms` +`GET: /lume/vms` #### Example Request @@ -263,11 +270,13 @@ console.log(await res.json()); ] ``` +--- + ### Get VM Details Get details for a specific virtual machine. -`GET: /vms/:name` +`GET: /lume/vms/:name` #### Parameters @@ -312,12 +321,12 @@ print(details.json()) ```typescript // Basic get -const res = await fetch('http://localhost:7777/lume/vms/lume_vm'); +let res = await fetch('http://localhost:7777/lume/vms/lume_vm'); console.log(await res.json()); // Get with specific storage -const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd'); -console.log(await res2.json()); +res = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd'); +console.log(await res.json()); ``` @@ -344,11 +353,13 @@ console.log(await res2.json()); } ``` +--- + ### Update VM Configuration Update the configuration of a virtual machine. -`PUT: /vms/:name` +`PATCH: /lume/vms/:name` #### Parameters @@ -368,7 +379,7 @@ Update the configuration of a virtual machine. ```bash curl --connect-timeout 6000 \ --max-time 5000 \ - -X PUT \ + -X PATCH \ -H "Content-Type: application/json" \ -d '{ "cpu": 4, @@ -393,7 +404,7 @@ payload = { "display": "1920x1080", "storage": "ssd" } -r = requests.put("http://localhost:7777/lume/vms/lume_vm", json=payload, timeout=50) +r = requests.patch("http://localhost:7777/lume/vms/lume_vm", json=payload, timeout=50) print(r.json()) ``` @@ -409,7 +420,7 @@ const payload = { storage: 'ssd', }; const res = await fetch('http://localhost:7777/lume/vms/lume_vm', { - method: 'PUT', + method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); @@ -419,11 +430,19 @@ console.log(await res.json()); +--- + ### Stop VM Stop a running virtual machine. -`POST: /vms/:name/stop` +`POST: /lume/vms/:name/stop` + +#### Parameters + +| Name | Type | Required | Description | +| ------- | ------ | -------- | -------------------------- | +| storage | string | No | Storage type (`ssd`, etc.) | #### Example Request @@ -431,10 +450,17 @@ Stop a running virtual machine. ```bash +# Basic stop curl --connect-timeout 6000 \ --max-time 5000 \ -X POST \ http://localhost:7777/lume/vms/lume_vm/stop + +# Stop with storage location specified +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + http://localhost:7777/lume/vms/lume_vm/stop?storage=ssd ``` @@ -443,15 +469,27 @@ curl --connect-timeout 6000 \ ```python import requests +# Basic stop r = requests.post("http://localhost:7777/lume/vms/lume_vm/stop", timeout=50) print(r.json()) + +# Stop with storage location specified +r = requests.post("http://localhost:7777/lume/vms/lume_vm/stop", params={"storage": "ssd"}, timeout=50) +print(r.json()) ``` ```typescript -const res = await fetch('http://localhost:7777/lume/vms/lume_vm/stop', { +// Basic stop +let res = await fetch('http://localhost:7777/lume/vms/lume_vm/stop', { + method: 'POST', +}); +console.log(await res.json()); + +// Stop with storage location specified +res = await fetch('http://localhost:7777/lume/vms/lume_vm/stop?storage=ssd', { method: 'POST', }); console.log(await res.json()); @@ -460,11 +498,13 @@ console.log(await res.json()); +--- + ### Delete VM Delete a virtual machine instance. -`DELETE: /vms/:name` +`DELETE: /lume/vms/:name` #### Parameters @@ -511,34 +551,110 @@ print(r.status_code) ```typescript // Basic delete -const res = await fetch('http://localhost:7777/lume/vms/lume_vm', { +let res = await fetch('http://localhost:7777/lume/vms/lume_vm', { method: 'DELETE', }); console.log(res.status); // Delete with specific storage -const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd', { +res = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd', { method: 'DELETE', }); -console.log(res2.status); +console.log(res.status); ``` +--- + +### Clone VM + +Clone an existing virtual machine. + +`POST: /lume/vms/clone` + +#### Parameters + +| Name | Type | Required | Description | +| -------------- | ------ | -------- | ----------------------------------- | +| name | string | Yes | Source VM name | +| newName | string | Yes | New VM name | +| sourceLocation | string | No | Source storage location (`default`) | +| destLocation | string | No | Destination storage location | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "name": "source-vm", + "newName": "cloned-vm", + "sourceLocation": "default", + "destLocation": "ssd" + }' \ + http://localhost:7777/lume/vms/clone +``` + + + + +```python +import requests + +payload = { + "name": "source-vm", + "newName": "cloned-vm", + "sourceLocation": "default", + "destLocation": "ssd" +} +r = requests.post("http://localhost:7777/lume/vms/clone", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + name: 'source-vm', + newName: 'cloned-vm', + sourceLocation: 'default', + destLocation: 'ssd', +}; +const res = await fetch('http://localhost:7777/lume/vms/clone', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + + +--- + ### Pull VM Image Pull a VM image from a registry. -`POST: /images/pull` +`POST: /lume/pull` #### Parameters | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------- | | image | string | Yes | Image name (e.g. `macos-sequoia-...`) | -| registry | string | Yes | Registry host (e.g. `ghcr.io`) | -| organization | string | Yes | Organization name | +| name | string | No | VM name for the pulled image | +| registry | string | No | Registry host (e.g. `ghcr.io`) | +| organization | string | No | Organization name | | storage | string | No | Storage type (`ssd`, etc.) | #### Example Request @@ -553,11 +669,12 @@ curl --connect-timeout 6000 \ -H "Content-Type: application/json" \ -d '{ "image": "macos-sequoia-vanilla:latest", + "name": "my-vm-name", "registry": "ghcr.io", "organization": "trycua", "storage": "ssd" }' \ - http://localhost:7777/lume/images/pull + http://localhost:7777/lume/pull ``` @@ -568,11 +685,12 @@ import requests payload = { "image": "macos-sequoia-vanilla:latest", + "name": "my-vm-name", "registry": "ghcr.io", "organization": "trycua", "storage": "ssd" } -r = requests.post("http://localhost:7777/lume/images/pull", json=payload, timeout=50) +r = requests.post("http://localhost:7777/lume/pull", json=payload, timeout=50) print(r.json()) ``` @@ -582,11 +700,12 @@ print(r.json()) ```typescript const payload = { image: 'macos-sequoia-vanilla:latest', + name: 'my-vm-name', registry: 'ghcr.io', organization: 'trycua', storage: 'ssd', }; -const res = await fetch('http://localhost:7777/lume/images/pull', { +const res = await fetch('http://localhost:7777/lume/pull', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), @@ -596,3 +715,553 @@ console.log(await res.json()); + +--- + +### Push VM Image + +Push a VM to a registry as an image (asynchronous operation). + +`POST: /lume/vms/push` + +#### Parameters + +| Name | Type | Required | Description | +| ------------ | ------------ | -------- | ----------------------------------------------- | +| name | string | Yes | Local VM name to push | +| imageName | string | Yes | Image name in registry | +| tags | array | Yes | Image tags (e.g. `["latest", "v1"]`) | +| organization | string | Yes | Organization name | +| registry | string | No | Registry host (e.g. `ghcr.io`) | +| chunkSizeMb | integer | No | Chunk size in MB for upload | +| storage | string/null | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "name": "my-local-vm", + "imageName": "my-image", + "tags": ["latest", "v1"], + "organization": "my-org", + "registry": "ghcr.io", + "chunkSizeMb": 512, + "storage": null + }' \ + http://localhost:7777/lume/vms/push +``` + + + + +```python +import requests + +payload = { + "name": "my-local-vm", + "imageName": "my-image", + "tags": ["latest", "v1"], + "organization": "my-org", + "registry": "ghcr.io", + "chunkSizeMb": 512, + "storage": None +} +r = requests.post("http://localhost:7777/lume/vms/push", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + name: 'my-local-vm', + imageName: 'my-image', + tags: ['latest', 'v1'], + organization: 'my-org', + registry: 'ghcr.io', + chunkSizeMb: 512, + storage: null, +}; +const res = await fetch('http://localhost:7777/lume/vms/push', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + + +**Response (202 Accepted):** + +```json +{ + "message": "Push initiated in background", + "name": "my-local-vm", + "imageName": "my-image", + "tags": [ + "latest", + "v1" + ] +} +``` + +--- + +### List Images + +List available VM images. + +`GET: /lume/images` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/images +``` + + + + +```python +import requests + +r = requests.get("http://localhost:7777/lume/images", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/images'); +console.log(await res.json()); +``` + + + + +```json +{ + "local": [ + "macos-sequoia-xcode:latest", + "macos-sequoia-vanilla:latest" + ] +} +``` + +--- + +### Prune Images + +Remove unused VM images to free up disk space. + +`POST: /lume/prune` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + http://localhost:7777/lume/prune +``` + + + + +```python +import requests + +r = requests.post("http://localhost:7777/lume/prune", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/prune', { + method: 'POST', +}); +console.log(await res.json()); +``` + + + + +--- + +### Get Latest IPSW URL + +Get the URL for the latest macOS IPSW file. + +`GET: /lume/ipsw` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/ipsw +``` + + + + +```python +import requests + +r = requests.get("http://localhost:7777/lume/ipsw", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/ipsw'); +console.log(await res.json()); +``` + + + + +--- + +## Configuration Management + +### Get Configuration + +Get current Lume configuration settings. + +`GET: /lume/config` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/config +``` + + + + +```python +import requests + +r = requests.get("http://localhost:7777/lume/config", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/config'); +console.log(await res.json()); +``` + + + + +```json +{ + "homeDirectory": "~/.lume", + "cacheDirectory": "~/.lume/cache", + "cachingEnabled": true +} +``` + +### Update Configuration + +Update Lume configuration settings. + +`POST: /lume/config` + +#### Parameters + +| Name | Type | Required | Description | +| --------------- | ------- | -------- | -------------------------------- | +| homeDirectory | string | No | Lume home directory path | +| cacheDirectory | string | No | Cache directory path | +| cachingEnabled | boolean | No | Enable or disable caching | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "homeDirectory": "~/custom/lume", + "cacheDirectory": "~/custom/lume/cache", + "cachingEnabled": true + }' \ + http://localhost:7777/lume/config +``` + + + + +```python +import requests + +payload = { + "homeDirectory": "~/custom/lume", + "cacheDirectory": "~/custom/lume/cache", + "cachingEnabled": True +} +r = requests.post("http://localhost:7777/lume/config", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + homeDirectory: '~/custom/lume', + cacheDirectory: '~/custom/lume/cache', + cachingEnabled: true, +}; +const res = await fetch('http://localhost:7777/lume/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + + +--- + +## Storage Location Management + +### Get VM Storage Locations + +List all configured VM storage locations. + +`GET: /lume/config/locations` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/config/locations +``` + + + + +```python +import requests + +r = requests.get("http://localhost:7777/lume/config/locations", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/config/locations'); +console.log(await res.json()); +``` + + + + +```json +[ + { + "name": "default", + "path": "~/.lume/vms", + "isDefault": true + }, + { + "name": "ssd", + "path": "/Volumes/SSD/lume/vms", + "isDefault": false + } +] +``` + +### Add VM Storage Location + +Add a new VM storage location. + +`POST: /lume/config/locations` + +#### Parameters + +| Name | Type | Required | Description | +| ---- | ------ | -------- | ---------------------------- | +| name | string | Yes | Storage location name | +| path | string | Yes | File system path for storage | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "name": "ssd", + "path": "/Volumes/SSD/lume/vms" + }' \ + http://localhost:7777/lume/config/locations +``` + + + + +```python +import requests + +payload = { + "name": "ssd", + "path": "/Volumes/SSD/lume/vms" +} +r = requests.post("http://localhost:7777/lume/config/locations", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + name: 'ssd', + path: '/Volumes/SSD/lume/vms', +}; +const res = await fetch('http://localhost:7777/lume/config/locations', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + + +### Remove VM Storage Location + +Remove a VM storage location. + +`DELETE: /lume/config/locations/:name` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X DELETE \ + http://localhost:7777/lume/config/locations/ssd +``` + + + + +```python +import requests + +r = requests.delete("http://localhost:7777/lume/config/locations/ssd", timeout=50) +print(r.status_code) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/config/locations/ssd', { + method: 'DELETE', +}); +console.log(res.status); +``` + + + + +### Set Default VM Storage Location + +Set a storage location as the default. + +`POST: /lume/config/locations/default/:name` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + http://localhost:7777/lume/config/locations/default/ssd +``` + + + + +```python +import requests + +r = requests.post("http://localhost:7777/lume/config/locations/default/ssd", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/config/locations/default/ssd', { + method: 'POST', +}); +console.log(await res.json()); +``` + + + diff --git a/docs/content/docs/libraries/lume/index.mdx b/docs/content/docs/libraries/lume/index.mdx index 28080bff..d62c80e0 100644 --- a/docs/content/docs/libraries/lume/index.mdx +++ b/docs/content/docs/libraries/lume/index.mdx @@ -5,6 +5,4 @@ github: - https://github.com/trycua/cua/tree/main/libs/lume --- -## Overview - -The Lume CLI provides command line tools for managing virtual machines with Lume. +Lume is a lightweight Command Line Interface and local API server for creating, running and managing **macOS and Linux virtual machines** with near-native performance on Apple Silicon, using Apple's [Virtualization.Framework](https://developer.apple.com/documentation/virtualization). \ No newline at end of file diff --git a/docs/content/docs/libraries/lume/installation.mdx b/docs/content/docs/libraries/lume/installation.mdx new file mode 100644 index 00000000..161e48e0 --- /dev/null +++ b/docs/content/docs/libraries/lume/installation.mdx @@ -0,0 +1,47 @@ +--- +title: Installation +description: Installation instructions for the current version of the Lume CLI. +--- + +## Quickstart + +Install and run a prebuilt macOS VM in two commands: + +```bash +# Install Lume +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +# Pull & start a macOS image +lume run macos-sequoia-vanilla:latest +``` + + +All prebuilt images use the default password `lume`. Change this immediately after your first login using the `passwd` command. + + +**System Requirements**: +- Apple Silicon Mac (M1, M2, M3, etc.) +- macOS 13.0 or later +- At least 8GB of RAM (16GB recommended) +- At least 50GB of free disk space + +## Install with Script + +Install with a single command: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +``` + +### Manual Start (No Background Service) +By default, Lume is installed as a background service that starts automatically on login. If you prefer to start the Lume API service manually when needed, you can use the `--no-background-service` option: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh) --no-background-service" +``` + + +With this option, you'll need to manually start the Lume API service by running `lume serve` in your terminal whenever you need to use tools or libraries that rely on the Lume API (such as the Computer-Use Agent). + + +## Manual Download and Installation +You can also download the `lume.pkg.tar.gz` archive from the [latest release](https://github.com/trycua/cua/releases?q=lume&expanded=true), extract it, and install the package manually. \ No newline at end of file diff --git a/docs/content/docs/libraries/lume/meta.json b/docs/content/docs/libraries/lume/meta.json new file mode 100644 index 00000000..5f4d907a --- /dev/null +++ b/docs/content/docs/libraries/lume/meta.json @@ -0,0 +1,9 @@ +{ + "pages": [ + "installation", + "prebuilt-images", + "cli-reference", + "http-api", + "faq" + ] +} diff --git a/docs/content/docs/libraries/lume/prebuilt-images.mdx b/docs/content/docs/libraries/lume/prebuilt-images.mdx new file mode 100644 index 00000000..0120af43 --- /dev/null +++ b/docs/content/docs/libraries/lume/prebuilt-images.mdx @@ -0,0 +1,20 @@ +--- +title: Prebuilt Images +--- + +Pre-built images are available in the registry [ghcr.io/trycua](https://github.com/orgs/trycua/packages). + +**Important Note (v0.2.0+):** Images are being re-uploaded with sparse file system optimizations enabled, resulting in significantly lower actual disk usage. Older images (without the `-sparse` suffix) are now **deprecated**. The last version of `lume` fully supporting the non-sparse images was `v0.1.x`. Starting from `v0.2.0`, lume will automatically pull images optimized with sparse file system support. + +These images come with an SSH server pre-configured and auto-login enabled. + +For the security of your VM, change the default password `lume` immediately after your first login. + +| Image | Tag | Description | Logical Size | +|-------|------------|-------------|------| +| `macos-sequoia-vanilla` | `latest`, `15.2` | macOS Sequoia 15.2 image | 20GB | +| `macos-sequoia-xcode` | `latest`, `15.2` | macOS Sequoia 15.2 image with Xcode command line tools | 22GB | +| `macos-sequoia-cua` | `latest`, `15.3` | macOS Sequoia 15.3 image compatible with the Computer interface | 24GB | +| `ubuntu-noble-vanilla` | `latest`, `24.04.1` | [Ubuntu Server for ARM 24.04.1 LTS](https://ubuntu.com/download/server/arm) with Ubuntu Desktop | 20GB | + +For additional disk space, resize the VM disk after pulling the image using the `lume set --disk-size ` command. Note that the actual disk space used by sparse images will be much lower than the logical size listed. \ No newline at end of file diff --git a/libs/lume/docs/Development.md b/libs/lume/Development.md similarity index 76% rename from libs/lume/docs/Development.md rename to libs/lume/Development.md index cbaa4df5..0ddf8c5e 100644 --- a/libs/lume/docs/Development.md +++ b/libs/lume/Development.md @@ -10,6 +10,14 @@ Lume development requires: - macOS Sequoia 15.2 or higher - (Optional) VS Code with Swift extension +If you're working on Lume in the context of the Cua monorepo, we recommend using the dedicated VS Code workspace configuration: + +```bash +# Open VS Code workspace from the root of the monorepo +code .vscode/lume.code-workspace +``` +This workspace is preconfigured with Swift language support, build tasks, and debug configurations. + ## Setting Up the Repository Locally 1. **Fork the Repository**: Create your own fork of lume diff --git a/libs/lume/README.md b/libs/lume/README.md index ac4257e0..c90c250a 100644 --- a/libs/lume/README.md +++ b/libs/lume/README.md @@ -23,174 +23,42 @@ lume cli - ```bash lume run macos-sequoia-vanilla:latest ``` -## Development Environment +## Quickstart -If you're working on Lume in the context of the CUA monorepo, we recommend using the dedicated VS Code workspace configuration: - -```bash -# Open VS Code workspace from the root of the monorepo -code .vscode/lume.code-workspace -``` -This workspace is preconfigured with Swift language support, build tasks, and debug configurations. - -## Usage - -```bash -lume - -Commands: - lume create Create a new macOS or Linux VM - lume run Run a VM - lume ls List all VMs - lume get Get detailed information about a VM - lume set Modify VM configuration - lume stop Stop a running VM - lume delete Delete a VM - lume pull Pull a macOS image from container registry - lume push Push a VM image to a container registry - lume clone Clone an existing VM - lume config Get or set lume configuration - lume images List available macOS images in local cache - lume ipsw Get the latest macOS restore image URL - lume prune Remove cached images - lume serve Start the API server - -Options: - --help Show help [boolean] - --version Show version number [boolean] - -Command Options: - create: - --os Operating system to install (macOS or linux, default: macOS) - --cpu Number of CPU cores (default: 4) - --memory Memory size, e.g., 8GB (default: 4GB) - --disk-size Disk size, e.g., 50GB (default: 40GB) - --display Display resolution (default: 1024x768) - --ipsw Path to IPSW file or 'latest' for macOS VMs - --storage VM storage location to use - - run: - --no-display Do not start the VNC client app - --shared-dir Share directory with VM (format: path[:ro|rw]) - --mount For Linux VMs only, attach a read-only disk image - --registry Container registry URL (default: ghcr.io) - --organization Organization to pull from (default: trycua) - --vnc-port Port to use for the VNC server (default: 0 for auto-assign) - --recovery-mode For MacOS VMs only, start VM in recovery mode (default: false) - --storage VM storage location to use - - set: - --cpu New number of CPU cores (e.g., 4) - --memory New memory size (e.g., 8192MB or 8GB) - --disk-size New disk size (e.g., 40960MB or 40GB) - --display New display resolution in format WIDTHxHEIGHT (e.g., 1024x768) - --storage VM storage location to use - - delete: - --force Force deletion without confirmation - --storage VM storage location to use - - pull: - --registry Container registry URL (default: ghcr.io) - --organization Organization to pull from (default: trycua) - --storage VM storage location to use - - push: - --additional-tags Additional tags to push the same image to - --registry Container registry URL (default: ghcr.io) - --organization Organization/user to push to (default: trycua) - --storage VM storage location to use - --chunk-size-mb Chunk size for disk image upload in MB (default: 512) - --verbose Enable verbose logging - --dry-run Prepare files and show plan without uploading - --reassemble Verify integrity by reassembling chunks (requires --dry-run) - - get: - -f, --format Output format (json|text) - --storage VM storage location to use - - stop: - --storage VM storage location to use - - clone: - --source-storage Source VM storage location - --dest-storage Destination VM storage location - - config: - get Get current configuration - storage Manage VM storage locations - add Add a new VM storage location - remove Remove a VM storage location - list List all VM storage locations - default Set the default VM storage location - cache Manage cache settings - get Get current cache directory - set Set cache directory - caching Manage image caching settings - get Show current caching status - set Enable or disable image caching - - serve: - --port Port to listen on (default: 7777) -``` - -## Install - -Install with a single command: +Install and run a prebuilt macOS VM in two commands: ```bash +# Install Lume /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +# Pull & start a macOS image +lume run macos-sequoia-vanilla:latest ``` -By default, Lume is installed as a background service that starts automatically on login. If you prefer to start the Lume API service manually when needed, you can use the `--no-background-service` option: + +All prebuilt images use the default password `lume`. Change this immediately after your first login using the `passwd` command. + -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh) --no-background-service" -``` +**System Requirements**: +- Apple Silicon Mac (M1, M2, M3, etc.) +- macOS 13.0 or later +- At least 8GB of RAM (16GB recommended) +- At least 50GB of free disk space -**Note:** With this option, you'll need to manually start the Lume API service by running `lume serve` in your terminal whenever you need to use tools or libraries that rely on the Lume API (such as the Computer-Use Agent). +## Development -You can also download the `lume.pkg.tar.gz` archive from the [latest release](https://github.com/trycua/lume/releases), extract it, and install the package manually. - -## Prebuilt Images - -Pre-built images are available in the registry [ghcr.io/trycua](https://github.com/orgs/trycua/packages). - -**Important Note (v0.2.0+):** Images are being re-uploaded with sparse file system optimizations enabled, resulting in significantly lower actual disk usage. Older images (without the `-sparse` suffix) are now **deprecated**. The last version of `lume` fully supporting the non-sparse images was `v0.1.x`. Starting from `v0.2.0`, lume will automatically pull images optimized with sparse file system support. - -These images come with an SSH server pre-configured and auto-login enabled. - -For the security of your VM, change the default password `lume` immediately after your first login. - -| Image | Tag | Description | Logical Size | -|-------|------------|-------------|------| -| `macos-sequoia-vanilla` | `latest`, `15.2` | macOS Sequoia 15.2 image | 20GB | -| `macos-sequoia-xcode` | `latest`, `15.2` | macOS Sequoia 15.2 image with Xcode command line tools | 22GB | -| `macos-sequoia-cua` | `latest`, `15.3` | macOS Sequoia 15.3 image compatible with the Computer interface | 24GB | -| `ubuntu-noble-vanilla` | `latest`, `24.04.1` | [Ubuntu Server for ARM 24.04.1 LTS](https://ubuntu.com/download/server/arm) with Ubuntu Desktop | 20GB | - -For additional disk space, resize the VM disk after pulling the image using the `lume set --disk-size ` command. Note that the actual disk space used by sparse images will be much lower than the logical size listed. - -## Local API Server - -`lume` exposes a local HTTP API server that listens on `http://localhost:7777/lume`, enabling automated management of VMs. - -```bash -lume serve -``` - -For detailed API documentation, please refer to [API Reference](docs/API-Reference.md). +To get set up with Lume for development, read [these instructions](Development.md). ## Docs -- [API Reference](docs/API-Reference.md) -- [Development](docs/Development.md) -- [FAQ](docs/FAQ.md) +- [Installation](https://trycua.com/docs/libraries/lume/installation) +- [Prebuilt Images](https://trycua.com/docs/libraries/lume/prebuilt-images) +- [CLI Reference](https://trycua.com/docs/libraries/lume/cli-reference) +- [HTTP API](https://trycua.com/docs/libraries/lume/http-api) +- [FAQ](https://trycua.com/docs/libraries/lume/faq) ## Contributing diff --git a/libs/lume/docs/API-Reference.md b/libs/lume/docs/API-Reference.md deleted file mode 100644 index 5af09cdf..00000000 --- a/libs/lume/docs/API-Reference.md +++ /dev/null @@ -1,387 +0,0 @@ -## API Reference - -
-Create VM - POST /vms - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "name": "lume_vm", - "os": "macOS", - "cpu": 2, - "memory": "4GB", - "diskSize": "64GB", - "display": "1024x768", - "ipsw": "latest", - "storage": "ssd" - }' \ - http://localhost:7777/lume/vms -``` -
- -
-Run VM - POST /vms/:name/run - -```bash -# Basic run -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - http://localhost:7777/lume/vms/my-vm-name/run - -# Run with VNC client started and shared directory -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "noDisplay": false, - "sharedDirectories": [ - { - "hostPath": "~/Projects", - "readOnly": false - } - ], - "recoveryMode": false, - "storage": "ssd" - }' \ - http://localhost:7777/lume/vms/lume_vm/run -``` -
- -
-List VMs - GET /vms - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/vms -``` -``` -[ - { - "name": "my-vm", - "state": "stopped", - "os": "macOS", - "cpu": 2, - "memory": "4GB", - "diskSize": "64GB" - }, - { - "name": "my-vm-2", - "state": "stopped", - "os": "linux", - "cpu": 2, - "memory": "4GB", - "diskSize": "64GB" - } -] -``` -
- -
-Get VM Details - GET /vms/:name - -```bash -# Basic get -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/vms/lume_vm - -# Get with storage location specified -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/vms/lume_vm?storage=ssd -``` -``` -{ - "name": "lume_vm", - "state": "running", - "os": "macOS", - "cpu": 2, - "memory": "4GB", - "diskSize": "64GB" -} -``` -
- -
-Update VM Settings - PATCH /vms/:name - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X PATCH \ - -H "Content-Type: application/json" \ - -d '{ - "cpu": 4, - "memory": "8GB", - "diskSize": "128GB", - "storage": "ssd" - }' \ - http://localhost:7777/lume/vms/my-vm-name -``` -
- -
-Stop VM - POST /vms/:name/stop - -```bash -# Basic stop -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - http://localhost:7777/lume/vms/my-vm-name/stop - -# Stop with storage location specified -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - http://localhost:7777/lume/vms/my-vm-name/stop?storage=ssd -``` -
- -
-Delete VM - DELETE /vms/:name - -```bash -# Basic delete -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X DELETE \ - http://localhost:7777/lume/vms/my-vm-name - -# Delete with storage location specified -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X DELETE \ - http://localhost:7777/lume/vms/my-vm-name?storage=ssd -``` -
- -
-Pull Image - POST /pull - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "image": "macos-sequoia-vanilla:latest", - "name": "my-vm-name", - "registry": "ghcr.io", - "organization": "trycua", - "storage": "ssd" - }' \ - http://localhost:7777/lume/pull -``` - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "image": "macos-sequoia-vanilla:15.2", - "name": "macos-sequoia-vanilla" - }' \ - http://localhost:7777/lume/pull -``` -
- -
-Push Image (Async) - POST /vms/push - -```bash -# Push VM 'my-local-vm' to 'my-org/my-image:latest' and 'my-org/my-image:v1' -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "name": "my-local-vm", - "imageName": "my-image", - "tags": ["latest", "v1"], - "organization": "my-org", - "registry": "ghcr.io", - "chunkSizeMb": 512, - "storage": null - }' \ - http://localhost:7777/lume/vms/push -``` - -**Response (202 Accepted):** - -```json -{ - "message": "Push initiated in background", - "name": "my-local-vm", - "imageName": "my-image", - "tags": [ - "latest", - "v1" - ] -} -``` -
- -
-Clone VM - POST /vms/:name/clone - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "name": "source-vm", - "newName": "cloned-vm", - "sourceLocation": "default", - "destLocation": "ssd" - }' \ - http://localhost:7777/lume/vms/clone -``` -
- -
-Get Latest IPSW URL - GET /ipsw - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/ipsw -``` -
- -
-List Images - GET /images - -```bash -# List images with default organization (trycua) -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/images -``` - -```json -{ - "local": [ - "macos-sequoia-xcode:latest", - "macos-sequoia-vanilla:latest" - ] -} -``` -
- -
-Prune Images - POST /lume/prune - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - http://localhost:7777/lume/prune -``` -
- -
-Get Configuration - GET /lume/config - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/config -``` - -```json -{ - "homeDirectory": "~/.lume", - "cacheDirectory": "~/.lume/cache", - "cachingEnabled": true -} -``` -
- -
-Update Configuration - POST /lume/config - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "homeDirectory": "~/custom/lume", - "cacheDirectory": "~/custom/lume/cache", - "cachingEnabled": true - }' \ - http://localhost:7777/lume/config -``` -
- -
-Get VM Storage Locations - GET /lume/config/locations - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - http://localhost:7777/lume/config/locations -``` - -```json -[ - { - "name": "default", - "path": "~/.lume/vms", - "isDefault": true - }, - { - "name": "ssd", - "path": "/Volumes/SSD/lume/vms", - "isDefault": false - } -] -``` -
- -
-Add VM Storage Location - POST /lume/config/locations - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{ - "name": "ssd", - "path": "/Volumes/SSD/lume/vms" - }' \ - http://localhost:7777/lume/config/locations -``` -
- -
-Remove VM Storage Location - DELETE /lume/config/locations/:name - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X DELETE \ - http://localhost:7777/lume/config/locations/ssd -``` -
- -
-Set Default VM Storage Location - POST /lume/config/locations/default/:name - -```bash -curl --connect-timeout 6000 \ - --max-time 5000 \ - -X POST \ - http://localhost:7777/lume/config/locations/default/ssd -``` -