cua-cli 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,214 @@
1
+ **/image/setup.iso
2
+ # Byte-compiled / optimized / DLL files
3
+ __pycache__/
4
+ *.py[cod]
5
+ *$py.class
6
+ # C extensions
7
+ *.so
8
+ node_modules/*
9
+ */node_modules
10
+ **/node_modules
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ !libs/lume/scripts/build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/*
21
+ !libs/lumier/src/lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+ # Django stuff:
58
+ *.log
59
+ local_settings.py
60
+ db.sqlite3
61
+ db.sqlite3-journal
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+ # Scrapy stuff:
66
+ .scrapy
67
+ # Sphinx documentation
68
+ docs/_build/
69
+ # PyBuilder
70
+ .pybuilder/
71
+ target/
72
+ # Jupyter Notebook
73
+ .ipynb_checkpoints
74
+ # IPython
75
+ profile_default/
76
+ ipython_config.py
77
+ .pdm.toml
78
+ .pdm-python
79
+ .pdm-build/
80
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
81
+ __pypackages__/
82
+ # Celery stuff
83
+ celerybeat-schedule
84
+ celerybeat.pid
85
+ # SageMath parsed files
86
+ *.sage.py
87
+ # Environments
88
+ .env
89
+ .venv
90
+ env/
91
+ venv/
92
+ ENV/
93
+ env.bak/
94
+ venv.bak/
95
+ # Git worktrees
96
+ .worktrees/
97
+ # Spyder project settings
98
+ .spyderproject
99
+ .spyproject
100
+ # Rope project settings
101
+ .ropeproject
102
+ # mkdocs documentation
103
+ /site
104
+ # mypy
105
+ .mypy_cache/
106
+ .dmypy.json
107
+ dmypy.json
108
+ # Scripts
109
+ server/scripts/
110
+ # Pyre type checker
111
+ .pyre/
112
+ # pytype static type analyzer
113
+ .pytype/
114
+ # Cython debug symbols
115
+ cython_debug/
116
+ # Ruff stuff:
117
+ .ruff_cache/
118
+ # PyPI configuration file
119
+ .pypirc
120
+ # Conda
121
+ .conda/
122
+ # Local environment
123
+ .env.local
124
+ # macOS DS_Store
125
+ .DS_Store
126
+ weights/
127
+ weights/icon_detect/
128
+ weights/icon_detect/model.pt
129
+ weights/icon_detect/model.pt.zip
130
+ weights/icon_detect/model.pt.zip.part*
131
+ libs/python/omniparser/weights/icon_detect/model.pt
132
+ # Example test data and output
133
+ examples/test_data/
134
+ examples/output/
135
+ /screenshots/
136
+ /experiments/
137
+ /logs/
138
+ # Xcode
139
+ #
140
+ # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
141
+ ## User settings
142
+ xcuserdata/
143
+ ## Obj-C/Swift specific
144
+ *.hmap
145
+ ## App packaging
146
+ *.ipa
147
+ *.dSYM.zip
148
+ *.dSYM
149
+ ## Playgrounds
150
+ timeline.xctimeline
151
+ playground.xcworkspace
152
+ # Swift Package Manager
153
+ #
154
+ # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
155
+ # Packages/
156
+ # Package.pins
157
+ # Package.resolved
158
+ # *.xcodeproj
159
+ #
160
+ # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
161
+ # hence it is not needed unless you have added a package configuration file to your project
162
+ .swiftpm/
163
+ .build/
164
+ # CocoaPods
165
+ #
166
+ # We recommend against adding the Pods directory to your .gitignore. However
167
+ # you should judge for yourself, the pros and cons are mentioned at:
168
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
169
+ #
170
+ # Pods/
171
+ #
172
+ # Add this line if you want to avoid checking in source code from the Xcode workspace
173
+ # *.xcworkspace
174
+ # Carthage
175
+ #
176
+ # Add this line if you want to avoid checking in source code from Carthage dependencies.
177
+ # Carthage/Checkouts
178
+ Carthage/Build/
179
+ # fastlane
180
+ #
181
+ # It is recommended to not store the screenshots in the git repo.
182
+ # Instead, use fastlane to re-generate the screenshots whenever they are needed.
183
+ # For more information about the recommended setup visit:
184
+ # https://docs.fastlane.tools/best-practices/source-control/#source-control
185
+ fastlane/report.xml
186
+ fastlane/Preview.html
187
+ fastlane/screenshots/**/*.png
188
+ fastlane/test_output
189
+ # Ignore folder
190
+ ignore
191
+ # .release
192
+ .release/
193
+ # Shared folder
194
+ shared
195
+ # Trajectories
196
+ trajectories/
197
+ # Installation ID Storage
198
+ .storage/
199
+ # Gradio settings
200
+ .gradio_settings.json
201
+ # Lumier Storage
202
+ storage/
203
+ # Trashes
204
+ .Trashes
205
+ .Trash-1000/
206
+ post-provision
207
+ # Local secrets for act
208
+ .secrets
209
+
210
+ # Link checker scripts (dev tools)
211
+ scripts/check-repo-md-links.py
212
+ docs/scripts/check-links.py
213
+ docs/scripts/check-all-links.py
214
+ docs/scripts/check-mdx-links.py
cua_cli-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: cua-cli
3
+ Version: 0.1.1
4
+ Summary: Unified CLI for CUA - Computer-Use Agents
5
+ Project-URL: Homepage, https://github.com/trycua/cua
6
+ Project-URL: Documentation, https://docs.trycua.com
7
+ Project-URL: Repository, https://github.com/trycua/cua
8
+ Project-URL: Issues, https://github.com/trycua/cua/issues
9
+ Author-email: TryCua <hello@trycua.com>
10
+ License-Expression: MIT
11
+ Keywords: agents,cli,cloud,computer-use,sandbox
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: <3.14,>=3.11
21
+ Requires-Dist: aiohttp>=3.9.0
22
+ Requires-Dist: cua-computer>=0.4.0
23
+ Requires-Dist: cua-core>=0.1.0
24
+ Requires-Dist: pillow>=10.0.0
25
+ Requires-Dist: rich>=13.0.0
26
+ Requires-Dist: websockets>=12.0
27
+ Provides-Extra: all
28
+ Requires-Dist: fastmcp>=2.0; extra == 'all'
29
+ Requires-Dist: litellm>=1.74.0; extra == 'all'
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
33
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
34
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
35
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
36
+ Provides-Extra: mcp
37
+ Requires-Dist: fastmcp>=2.0; extra == 'mcp'
38
+ Provides-Extra: skills
39
+ Requires-Dist: litellm>=1.74.0; extra == 'skills'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # CUA CLI
43
+
44
+ Unified command-line interface for CUA (Computer-Use Agents).
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install cua-cli
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ ```bash
55
+ # Authentication
56
+ cua auth login # Authenticate via browser
57
+ cua auth login --api-key # Authenticate with API key
58
+ cua auth logout # Clear credentials
59
+ cua auth env # Export API key to .env file
60
+
61
+ # Sandbox Management
62
+ cua sb list # List all sandboxes
63
+ cua sb create --os linux --size medium --region north-america
64
+ cua sb get <name> # Get sandbox details
65
+ cua sb start <name> # Start a stopped sandbox
66
+ cua sb stop <name> # Stop a running sandbox
67
+ cua sb restart <name> # Restart a sandbox
68
+ cua sb suspend <name> # Suspend a sandbox
69
+ cua sb delete <name> # Delete a sandbox
70
+ cua sb vnc <name> # Open sandbox in browser
71
+
72
+ # Image Management
73
+ cua image list # List cloud images
74
+ cua image list --local # List local images
75
+ cua image push <name> # Upload image to cloud
76
+ cua image pull <name> # Download image from cloud
77
+ cua image delete <name> # Delete cloud image
78
+
79
+ # Skills Management
80
+ cua skills list # List recorded skills
81
+ cua skills read <name> # Read a skill's content
82
+ cua skills record <name> # Record a new skill
83
+ cua skills replay <name> # Replay a skill
84
+ cua skills delete <name> # Delete a skill
85
+ cua skills clean # Delete all skills
86
+
87
+ # MCP Server (for AI assistants)
88
+ cua serve-mcp # Start MCP server with all permissions
89
+ cua serve-mcp --permissions sandbox:all,computer:readonly
90
+ ```
91
+
92
+ ## Installation Options
93
+
94
+ ```bash
95
+ # Basic installation
96
+ pip install cua-cli
97
+
98
+ # With MCP server support
99
+ pip install cua-cli[mcp]
100
+
101
+ # With skills recording (VLM captioning)
102
+ pip install cua-cli[skills]
103
+
104
+ # Full installation
105
+ pip install cua-cli[all]
106
+ ```
107
+
108
+ ## MCP Integration
109
+
110
+ To use CUA with Claude Code or other MCP-compatible AI assistants:
111
+
112
+ ```bash
113
+ # Add CUA as an MCP server
114
+ claude mcp add cua -- cua serve-mcp
115
+
116
+ # With specific permissions
117
+ claude mcp add cua -- cua serve-mcp --permissions sandbox:all,computer:readonly
118
+
119
+ # With a default sandbox
120
+ claude mcp add cua -- cua serve-mcp --sandbox my-sandbox
121
+ ```
122
+
123
+ ### Available Permissions
124
+
125
+ - `all` - All permissions
126
+ - `sandbox:all` - Full sandbox management
127
+ - `sandbox:readonly` - List and get sandboxes only
128
+ - `computer:all` - Full computer control
129
+ - `computer:readonly` - Screenshots only
130
+ - `skills:all` - Full skills management
131
+ - `skills:readonly` - List and read skills only
132
+
133
+ Individual permissions: `sandbox:list`, `sandbox:create`, `sandbox:delete`, `sandbox:start`, `sandbox:stop`, `sandbox:restart`, `sandbox:suspend`, `sandbox:get`, `sandbox:vnc`, `computer:screenshot`, `computer:click`, `computer:type`, `computer:key`, `computer:scroll`, `computer:drag`, `computer:hotkey`, `computer:clipboard`, `computer:file`, `computer:shell`, `computer:window`, `skills:list`, `skills:read`, `skills:record`, `skills:delete`
134
+
135
+ ## Environment Variables
136
+
137
+ - `CUA_API_KEY`: API key for authentication
138
+ - `CUA_API_BASE`: API base URL (default: https://api.cua.ai)
139
+ - `CUA_WEBSITE_URL`: Website URL for OAuth (default: https://cua.ai)
140
+ - `CUA_MCP_PERMISSIONS`: Default MCP permissions (comma-separated)
141
+ - `CUA_SANDBOX`: Default sandbox name for computer commands
@@ -0,0 +1,100 @@
1
+ # CUA CLI
2
+
3
+ Unified command-line interface for CUA (Computer-Use Agents).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install cua-cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ # Authentication
15
+ cua auth login # Authenticate via browser
16
+ cua auth login --api-key # Authenticate with API key
17
+ cua auth logout # Clear credentials
18
+ cua auth env # Export API key to .env file
19
+
20
+ # Sandbox Management
21
+ cua sb list # List all sandboxes
22
+ cua sb create --os linux --size medium --region north-america
23
+ cua sb get <name> # Get sandbox details
24
+ cua sb start <name> # Start a stopped sandbox
25
+ cua sb stop <name> # Stop a running sandbox
26
+ cua sb restart <name> # Restart a sandbox
27
+ cua sb suspend <name> # Suspend a sandbox
28
+ cua sb delete <name> # Delete a sandbox
29
+ cua sb vnc <name> # Open sandbox in browser
30
+
31
+ # Image Management
32
+ cua image list # List cloud images
33
+ cua image list --local # List local images
34
+ cua image push <name> # Upload image to cloud
35
+ cua image pull <name> # Download image from cloud
36
+ cua image delete <name> # Delete cloud image
37
+
38
+ # Skills Management
39
+ cua skills list # List recorded skills
40
+ cua skills read <name> # Read a skill's content
41
+ cua skills record <name> # Record a new skill
42
+ cua skills replay <name> # Replay a skill
43
+ cua skills delete <name> # Delete a skill
44
+ cua skills clean # Delete all skills
45
+
46
+ # MCP Server (for AI assistants)
47
+ cua serve-mcp # Start MCP server with all permissions
48
+ cua serve-mcp --permissions sandbox:all,computer:readonly
49
+ ```
50
+
51
+ ## Installation Options
52
+
53
+ ```bash
54
+ # Basic installation
55
+ pip install cua-cli
56
+
57
+ # With MCP server support
58
+ pip install cua-cli[mcp]
59
+
60
+ # With skills recording (VLM captioning)
61
+ pip install cua-cli[skills]
62
+
63
+ # Full installation
64
+ pip install cua-cli[all]
65
+ ```
66
+
67
+ ## MCP Integration
68
+
69
+ To use CUA with Claude Code or other MCP-compatible AI assistants:
70
+
71
+ ```bash
72
+ # Add CUA as an MCP server
73
+ claude mcp add cua -- cua serve-mcp
74
+
75
+ # With specific permissions
76
+ claude mcp add cua -- cua serve-mcp --permissions sandbox:all,computer:readonly
77
+
78
+ # With a default sandbox
79
+ claude mcp add cua -- cua serve-mcp --sandbox my-sandbox
80
+ ```
81
+
82
+ ### Available Permissions
83
+
84
+ - `all` - All permissions
85
+ - `sandbox:all` - Full sandbox management
86
+ - `sandbox:readonly` - List and get sandboxes only
87
+ - `computer:all` - Full computer control
88
+ - `computer:readonly` - Screenshots only
89
+ - `skills:all` - Full skills management
90
+ - `skills:readonly` - List and read skills only
91
+
92
+ Individual permissions: `sandbox:list`, `sandbox:create`, `sandbox:delete`, `sandbox:start`, `sandbox:stop`, `sandbox:restart`, `sandbox:suspend`, `sandbox:get`, `sandbox:vnc`, `computer:screenshot`, `computer:click`, `computer:type`, `computer:key`, `computer:scroll`, `computer:drag`, `computer:hotkey`, `computer:clipboard`, `computer:file`, `computer:shell`, `computer:window`, `skills:list`, `skills:read`, `skills:record`, `skills:delete`
93
+
94
+ ## Environment Variables
95
+
96
+ - `CUA_API_KEY`: API key for authentication
97
+ - `CUA_API_BASE`: API base URL (default: https://api.cua.ai)
98
+ - `CUA_WEBSITE_URL`: Website URL for OAuth (default: https://cua.ai)
99
+ - `CUA_MCP_PERMISSIONS`: Default MCP permissions (comma-separated)
100
+ - `CUA_SANDBOX`: Default sandbox name for computer commands
@@ -0,0 +1,3 @@
1
+ """CUA CLI - Unified command-line interface for Computer-Use Agents."""
2
+
3
+ __version__ = "0.1.1"
@@ -0,0 +1 @@
1
+ """API client module for CUA CLI."""
@@ -0,0 +1,142 @@
1
+ """HTTP API client for CUA cloud services."""
2
+
3
+ import hashlib
4
+ import os
5
+ from pathlib import Path
6
+ from typing import Any, Optional
7
+ from urllib.parse import quote
8
+
9
+ import aiohttp
10
+ from cua_cli.auth.store import require_api_key
11
+
12
+ DEFAULT_API_BASE = "https://api.cua.ai"
13
+
14
+
15
+ def get_api_base() -> str:
16
+ """Get the API base URL."""
17
+ return os.environ.get("CUA_API_BASE", DEFAULT_API_BASE).rstrip("/")
18
+
19
+
20
+ class CloudAPIClient:
21
+ """HTTP client for CUA cloud API."""
22
+
23
+ def __init__(self, api_key: Optional[str] = None, api_base: Optional[str] = None):
24
+ self.api_key = api_key or require_api_key()
25
+ self.api_base = api_base or get_api_base()
26
+
27
+ def _headers(self) -> dict[str, str]:
28
+ return {
29
+ "Authorization": f"Bearer {self.api_key}",
30
+ "Accept": "application/json",
31
+ }
32
+
33
+ async def _request(
34
+ self,
35
+ method: str,
36
+ path: str,
37
+ json: Optional[dict] = None,
38
+ timeout: int = 30,
39
+ ) -> tuple[int, Any]:
40
+ """Make an HTTP request to the API.
41
+
42
+ Returns:
43
+ Tuple of (status_code, response_data)
44
+ """
45
+ url = f"{self.api_base}{path}"
46
+ headers = self._headers()
47
+
48
+ if json is not None:
49
+ headers["Content-Type"] = "application/json"
50
+
51
+ async with aiohttp.ClientSession() as session:
52
+ timeout_obj = aiohttp.ClientTimeout(total=timeout)
53
+ async with session.request(
54
+ method, url, headers=headers, json=json, timeout=timeout_obj
55
+ ) as resp:
56
+ try:
57
+ data = await resp.json(content_type=None)
58
+ except Exception:
59
+ data = await resp.text()
60
+ return resp.status, data
61
+
62
+ # Image API methods
63
+
64
+ async def list_images(self) -> list[dict[str, Any]]:
65
+ """List all images in the workspace."""
66
+ status, data = await self._request("GET", "/v1/images")
67
+ if status == 200 and isinstance(data, list):
68
+ return data
69
+ return []
70
+
71
+ async def initiate_upload(
72
+ self,
73
+ name: str,
74
+ tag: str,
75
+ image_type: str,
76
+ size_bytes: int,
77
+ checksum_sha256: str,
78
+ ) -> tuple[int, dict[str, Any]]:
79
+ """Initiate a multi-part upload session.
80
+
81
+ Returns:
82
+ Tuple of (status_code, session_data)
83
+ """
84
+ path = f"/v1/images/{quote(name, safe='')}/upload"
85
+ body = {
86
+ "tag": tag,
87
+ "image_type": image_type,
88
+ "size_bytes": size_bytes,
89
+ "checksum_sha256": checksum_sha256,
90
+ }
91
+ return await self._request("POST", path, json=body)
92
+
93
+ async def get_upload_part_url(
94
+ self, name: str, upload_id: str, part_number: int
95
+ ) -> tuple[int, dict[str, Any]]:
96
+ """Get a signed URL for uploading a part."""
97
+ path = f"/v1/images/{quote(name, safe='')}/upload/{upload_id}/part/{part_number}"
98
+ return await self._request("GET", path)
99
+
100
+ async def complete_upload(
101
+ self, name: str, upload_id: str, parts: list[dict[str, Any]]
102
+ ) -> tuple[int, dict[str, Any]]:
103
+ """Complete a multi-part upload."""
104
+ path = f"/v1/images/{quote(name, safe='')}/upload/{upload_id}/complete"
105
+ return await self._request("POST", path, json={"parts": parts})
106
+
107
+ async def abort_upload(self, name: str, upload_id: str) -> tuple[int, Any]:
108
+ """Abort an upload session."""
109
+ path = f"/v1/images/{quote(name, safe='')}/upload/{upload_id}"
110
+ return await self._request("DELETE", path)
111
+
112
+ async def get_download_url(self, name: str, tag: str) -> tuple[int, dict[str, Any]]:
113
+ """Get a signed URL for downloading an image."""
114
+ path = f"/v1/images/{quote(name, safe='')}/download?tag={quote(tag, safe='')}"
115
+ return await self._request("GET", path)
116
+
117
+ async def delete_image(self, name: str, tag: str) -> tuple[int, Any]:
118
+ """Delete an image version."""
119
+ path = f"/v1/images/{quote(name, safe='')}?tag={quote(tag, safe='')}"
120
+ return await self._request("DELETE", path)
121
+
122
+
123
+ def calculate_file_hash(file_path: Path) -> str:
124
+ """Calculate SHA256 hash of a file."""
125
+ sha256 = hashlib.sha256()
126
+ with open(file_path, "rb") as f:
127
+ for chunk in iter(lambda: f.read(8192), b""):
128
+ sha256.update(chunk)
129
+ return sha256.hexdigest()
130
+
131
+
132
+ def format_bytes(size_bytes: int) -> str:
133
+ """Format bytes in human-readable format."""
134
+ if size_bytes == 0:
135
+ return "0 B"
136
+ units = ["B", "KB", "MB", "GB", "TB"]
137
+ k = 1024
138
+ i = 0
139
+ while size_bytes >= k and i < len(units) - 1:
140
+ size_bytes /= k
141
+ i += 1
142
+ return f"{size_bytes:.2f} {units[i]}"
@@ -0,0 +1,5 @@
1
+ """Authentication module for CUA CLI."""
2
+
3
+ from .store import CredentialStore, clear_credentials, get_api_key, save_api_key
4
+
5
+ __all__ = ["CredentialStore", "get_api_key", "save_api_key", "clear_credentials"]