@trycua/cua 0.2.0
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.
- package/README.md +121 -0
- package/bin/cua.js +37 -0
- package/browser/cua_sdk-ffi.d.ts +6 -0
- package/browser/cua_sdk-ffi.js +3 -0
- package/browser/cua_sdk-ffi.ts +14 -0
- package/browser/cua_sdk.d.ts +2237 -0
- package/browser/cua_sdk.js +2607 -0
- package/browser/cua_sdk.ts +3644 -0
- package/browser/cyclops_sdk_schema-ffi.d.ts +6 -0
- package/browser/cyclops_sdk_schema-ffi.js +3 -0
- package/browser/cyclops_sdk_schema-ffi.ts +14 -0
- package/browser/cyclops_sdk_schema.d.ts +996 -0
- package/browser/cyclops_sdk_schema.js +2194 -0
- package/browser/cyclops_sdk_schema.ts +2934 -0
- package/browser/fleet_sdk-ffi.d.ts +28 -0
- package/browser/fleet_sdk-ffi.js +3 -0
- package/browser/fleet_sdk-ffi.ts +35 -0
- package/browser/fleet_sdk.d.ts +3056 -0
- package/browser/fleet_sdk.js +5088 -0
- package/browser/fleet_sdk.ts +6830 -0
- package/browser/index.d.ts +2 -0
- package/browser/index.js +18 -0
- package/browser/index.web.ts +34 -0
- package/browser/tsconfig.json +20 -0
- package/browser/wasm-bindgen/index.d.ts +2346 -0
- package/browser/wasm-bindgen/index.js +6642 -0
- package/browser/wasm-bindgen/index_bg.wasm +0 -0
- package/browser/wasm-bindgen/index_bg.wasm.d.ts +1154 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +207 -0
- package/dist/mcp.d.ts +33 -0
- package/dist/mcp.js +41 -0
- package/dist/native/cua_sdk-ffi.d.ts +1038 -0
- package/dist/native/cua_sdk-ffi.js +5095 -0
- package/dist/native/cua_sdk.d.ts +15906 -0
- package/dist/native/cua_sdk.js +27061 -0
- package/dist/native/index.d.ts +7 -0
- package/dist/native/index.js +12 -0
- package/dist/native/node-runtime.d.ts +72 -0
- package/dist/native/node-runtime.js +35 -0
- package/dist/spaces/cursorArt.d.ts +27 -0
- package/dist/spaces/cursorArt.js +59 -0
- package/dist/spaces/errors.d.ts +81 -0
- package/dist/spaces/errors.js +102 -0
- package/dist/spaces/events.d.ts +154 -0
- package/dist/spaces/events.js +182 -0
- package/dist/spaces/groups.d.ts +130 -0
- package/dist/spaces/groups.js +275 -0
- package/dist/spaces/host.d.ts +71 -0
- package/dist/spaces/host.js +154 -0
- package/dist/spaces/index.d.ts +48 -0
- package/dist/spaces/index.js +44 -0
- package/dist/spaces/pip.d.ts +128 -0
- package/dist/spaces/pip.js +250 -0
- package/dist/spaces/presence.d.ts +187 -0
- package/dist/spaces/presence.js +449 -0
- package/dist/spaces/presenceTypes.check.d.ts +12 -0
- package/dist/spaces/presenceTypes.check.js +1 -0
- package/dist/spaces/presenceTypes.d.ts +47 -0
- package/dist/spaces/presenceTypes.js +7 -0
- package/dist/spaces/routines.d.ts +158 -0
- package/dist/spaces/routines.js +339 -0
- package/dist/spaces/thread.d.ts +147 -0
- package/dist/spaces/thread.js +285 -0
- package/dist/spaces/transport/http.d.ts +51 -0
- package/dist/spaces/transport/http.js +113 -0
- package/dist/spaces/transport/index.d.ts +19 -0
- package/dist/spaces/transport/index.js +19 -0
- package/dist/spaces/transport/session.d.ts +120 -0
- package/dist/spaces/transport/session.js +188 -0
- package/dist/spaces/transport/tauri.d.ts +50 -0
- package/dist/spaces/transport/tauri.js +90 -0
- package/dist/spaces/transport/types.d.ts +123 -0
- package/dist/spaces/transport/types.js +59 -0
- package/dist/teleport/controller.d.ts +34 -0
- package/dist/teleport/controller.js +107 -0
- package/dist/teleport/drop.d.ts +62 -0
- package/dist/teleport/drop.js +138 -0
- package/dist/teleport/dropZone.d.ts +59 -0
- package/dist/teleport/dropZone.js +166 -0
- package/dist/teleport/element.d.ts +28 -0
- package/dist/teleport/element.js +340 -0
- package/dist/teleport/index.d.ts +32 -0
- package/dist/teleport/index.js +32 -0
- package/dist/teleport/install.d.ts +31 -0
- package/dist/teleport/install.js +65 -0
- package/dist/teleport/model.d.ts +245 -0
- package/dist/teleport/model.js +334 -0
- package/dist/teleport/windowDrag.d.ts +86 -0
- package/dist/teleport/windowDrag.js +71 -0
- package/package.json +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @trycua/cua
|
|
2
|
+
|
|
3
|
+
The cua SDK for Node (and, via `@trycua/cua/browser`, the browser): a thin,
|
|
4
|
+
generated binding over the Rust `cua-sdk` crate. Sandboxes (Fleet, local,
|
|
5
|
+
direct), cua-spacesd (typed calls plus `callJson` for every
|
|
6
|
+
`cua.env.v1` RPC), media sessions with `FrameSink`/`AudioSink` callbacks,
|
|
7
|
+
Fleet pools/claims/images, and local runtimes, embedded or through a
|
|
8
|
+
`cua daemon`.
|
|
9
|
+
|
|
10
|
+
Native payloads ship as optional per-platform packages
|
|
11
|
+
(`@trycua/cua-darwin-arm64`, `-linux-x64-gnu`, ...), assembled by
|
|
12
|
+
`libs/cua/scripts/build-npm-packages.mjs`. `src/native` is generated by
|
|
13
|
+
`libs/cua/scripts/generate-uniffi-bindings.mjs` and checked with `--check`.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd libs/cua && cargo build --release -p cua-sdk
|
|
17
|
+
scripts/build-test-fixtures.sh
|
|
18
|
+
cd typescript && npm ci && npm run stage:uniffi && npm test
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Sandboxes: any image, local or cloud
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { embedded, http, CloudOptions, HttpHeader, SandboxCreateOptions } from "@trycua/cua"
|
|
25
|
+
|
|
26
|
+
const sb = await embedded().sandboxes().create(SandboxCreateOptions.create({
|
|
27
|
+
on: "local", // or "cloud": same options
|
|
28
|
+
image: "python:3.12-slim",
|
|
29
|
+
command: ["python", "-m", "my_mcp", "--port", "8765"],
|
|
30
|
+
env: new Map([["FOO", "bar"]]),
|
|
31
|
+
services: new Map([["mcp", 8765]]),
|
|
32
|
+
waitFor: [http("mcp", "/health")], // or tcp("mcp")
|
|
33
|
+
cloud: CloudOptions.create({ warm: true }), // optional, ignored locally
|
|
34
|
+
}))
|
|
35
|
+
const svc = sb.service("mcp")
|
|
36
|
+
const r = await svc.request("POST", "/mcp", body, undefined,
|
|
37
|
+
[HttpHeader.create({ name: "accept", value: "application/json, text/event-stream" })])
|
|
38
|
+
const url = await svc.url() // usable from this machine
|
|
39
|
+
const share = await sb.publicUrl("mcp", 3600, undefined) // shareable, expires
|
|
40
|
+
const fwd = await sb.forward(8765) // loopback URL: fwd.url()
|
|
41
|
+
const info = sb.info() // id, phase, location, services, expiresAtUnix, providerDetails
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`publicUrl` is a signed URL in the cloud and a loopback URL with its own token
|
|
45
|
+
locally, served by the `cua daemon` (started on demand; `CUA_BIN` names the
|
|
46
|
+
CLI).
|
|
47
|
+
|
|
48
|
+
`Image.linux()` / `Image.windows()` / `Image.macos()` return the canonical
|
|
49
|
+
refs (`ghcr.io/trycua/linux:24.04`, ...). MCP servers in a sandbox use the
|
|
50
|
+
official SDK (`npm install @modelcontextprotocol/client`), no cua-spacesd:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { connectMcp, registrySecret, sidecar } from "@trycua/cua"
|
|
54
|
+
|
|
55
|
+
const client = await connectMcp(await sb.mcpConfig("mcp", undefined))
|
|
56
|
+
const result = await client.callTool({ name: "add", arguments: { a: 2, b: 3 } })
|
|
57
|
+
|
|
58
|
+
// Sidecars share the sandbox's network namespace; a private image takes credentials.
|
|
59
|
+
SandboxCreateOptions.create({
|
|
60
|
+
on: "local",
|
|
61
|
+
image: "ghcr.io/acme/app:1",
|
|
62
|
+
registrySecret: registrySecret.fromEnv(),
|
|
63
|
+
sidecars: [sidecar("redis:7-alpine", { ports: [6379] })],
|
|
64
|
+
services: new Map([["db", 6379]]),
|
|
65
|
+
runtime: "runc", // local sidecars need runc
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The sandbox reaches a sidecar at its name (`redis:6379` here) and a sidecar
|
|
70
|
+
reaches the sandbox at `main`, locally and in the cloud (gVisor and KubeVirt).
|
|
71
|
+
Cloud `env` and registry secrets work too; cloud image layers (a remote build)
|
|
72
|
+
are not available yet and fail with a clear error. Docs: [Sandboxes](https://cua.ai/docs/cua-sdk).
|
|
73
|
+
|
|
74
|
+
## Spaces (`@trycua/cua/spaces`)
|
|
75
|
+
|
|
76
|
+
The Rust `cua-spaces` runtime (embedded, or in `cua daemon`), typed:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { embedded } from "@trycua/cua"
|
|
80
|
+
import { approve, startThread, SpaceSendFileOptions } from "@trycua/cua/spaces"
|
|
81
|
+
|
|
82
|
+
const spaces = embedded().spaces() // or connect().spaces()
|
|
83
|
+
const info = await spaces.add("http://10.0.0.5:3211", token, "dev")
|
|
84
|
+
const space = await spaces.space(info.id)
|
|
85
|
+
await space.bash("uname -a", undefined)
|
|
86
|
+
await space.sendFile("./report.pdf", SpaceSendFileOptions.create({}))
|
|
87
|
+
await space.teleport("firefox", undefined, approve((m) => ask(m))) // consent callback
|
|
88
|
+
const bot = await startThread(spaces, {
|
|
89
|
+
agent: "claude-code", prompt: "summarise the open PRs",
|
|
90
|
+
placement: { type: "shared", space, acknowledgeNoIsolation: true },
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`Spaces` (create / add / list / resolve / delete_ / remove / space /
|
|
95
|
+
callToolJson), `Space` (bash, write, upload, download,
|
|
96
|
+
sendFile, listTools, callTool, windows, openStream, streamSession,
|
|
97
|
+
joinPresence, teleportManifest, teleport, start/stop/hotspotStatus, agent*),
|
|
98
|
+
plus `Thread`, `SpacesError` (`toSpacesError` maps `CuaError`) and the
|
|
99
|
+
transcript adapter. `@trycua/cua/spaces/host` drives the desktop app's
|
|
100
|
+
control server (PiP, viewer). `@trycua/cua/spaces/pip` is picture-in-picture
|
|
101
|
+
of the desktop or one window in a browser or webview: `PictureInPicture`
|
|
102
|
+
(Document Picture-in-Picture, falling back to video PiP) and, for a shell's
|
|
103
|
+
own always-on-top window, `pipWindowLabel` and `encodePipRoute` /
|
|
104
|
+
`parsePipRoute`. `@trycua/cua/teleport` has the one drop zone,
|
|
105
|
+
`<cua-drop-zone>` ("Drop a file or window", Send file…, Teleport an app…).
|
|
106
|
+
Three more need no native library: `@trycua/cua/spaces/presence`
|
|
107
|
+
(`PresenceRoster`, the other participants' cursors as data, and
|
|
108
|
+
`waitForPresence`), `@trycua/cua/spaces/routines` (`RoutineStore`: a Bot's
|
|
109
|
+
recurring prompts, their clock and a `RoutineRunner`) and
|
|
110
|
+
`@trycua/cua/spaces/groups` (`GroupChatStore`: two to six Bots in one thread
|
|
111
|
+
over a `GroupMessenger`). The saved routine list is the same JSON the Rust
|
|
112
|
+
(`cua_spaces::routines`) and Swift SDKs write.
|
|
113
|
+
|
|
114
|
+
Webviews and browsers cannot load the native binding; they use
|
|
115
|
+
`@trycua/cua/spaces/transport`: `McpSession` over `McpHttpTransport` (the
|
|
116
|
+
daemon's loopback `/mcp`, bearer = its loopback token) or `TauriTransport`
|
|
117
|
+
(`invoke`). Same Spaces contract tools either way.
|
|
118
|
+
|
|
119
|
+
Tests: `node --test test/spaces-unit.test.mjs test/pip.test.mjs test/routines.test.mjs` (no native library needed) and
|
|
120
|
+
`node --test test/spaces.test.mjs` (needs `cua-test-fixtures` and, for the
|
|
121
|
+
daemon case, the `cua` CLI in `../target/debug`).
|
package/bin/cua.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The `cua` command: runs the Rust CLI shipped in the matching
|
|
3
|
+
// @trycua/cua-<platform> package.
|
|
4
|
+
import { spawnSync } from "node:child_process"
|
|
5
|
+
import { existsSync } from "node:fs"
|
|
6
|
+
import { createRequire } from "node:module"
|
|
7
|
+
import { dirname, join } from "node:path"
|
|
8
|
+
|
|
9
|
+
const arch = process.arch
|
|
10
|
+
const triple =
|
|
11
|
+
process.platform === "linux"
|
|
12
|
+
? `linux-${arch}-gnu`
|
|
13
|
+
: process.platform === "win32"
|
|
14
|
+
? `win32-${arch}-msvc`
|
|
15
|
+
: `${process.platform}-${arch}`
|
|
16
|
+
const exe = process.platform === "win32" ? "cua.exe" : "cua"
|
|
17
|
+
const require = createRequire(import.meta.url)
|
|
18
|
+
|
|
19
|
+
let binary
|
|
20
|
+
try {
|
|
21
|
+
binary = join(dirname(require.resolve(`@trycua/cua-${triple}/package.json`)), exe)
|
|
22
|
+
} catch {
|
|
23
|
+
binary = undefined
|
|
24
|
+
}
|
|
25
|
+
if (!binary || !existsSync(binary)) {
|
|
26
|
+
console.error(
|
|
27
|
+
`cua: no CLI binary for ${triple}; install @trycua/cua on a supported platform, ` +
|
|
28
|
+
"or build it with `cargo install --locked --path libs/cua/crates/cua-cli`.",
|
|
29
|
+
)
|
|
30
|
+
process.exit(127)
|
|
31
|
+
}
|
|
32
|
+
const r = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" })
|
|
33
|
+
if (r.error) {
|
|
34
|
+
console.error(`cua: ${r.error.message}`)
|
|
35
|
+
process.exit(127)
|
|
36
|
+
}
|
|
37
|
+
process.exit(r.status ?? 1)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type UniffiRustFutureContinuationCallback = (data: bigint, pollResult: number) => void;
|
|
2
|
+
export type UniffiForeignFutureDroppedCallback = (handle: bigint) => void;
|
|
3
|
+
export type UniffiForeignFutureDroppedCallbackStruct = {
|
|
4
|
+
handle: bigint;
|
|
5
|
+
free: UniffiForeignFutureDroppedCallback;
|
|
6
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// This file was autogenerated by some hot garbage in the `uniffi-bindgen-react-native` crate.
|
|
2
|
+
// Trust me, you don't want to mess with it!
|
|
3
|
+
|
|
4
|
+
/* tslint:disable */
|
|
5
|
+
/* eslint-disable */
|
|
6
|
+
// @ts-nocheck
|
|
7
|
+
|
|
8
|
+
// Structs and function types for calling back into Typescript from Rust.
|
|
9
|
+
export type UniffiRustFutureContinuationCallback = (data: bigint, pollResult: number) => void;
|
|
10
|
+
export type UniffiForeignFutureDroppedCallback = (handle: bigint) => void;
|
|
11
|
+
export type UniffiForeignFutureDroppedCallbackStruct = {
|
|
12
|
+
handle: bigint;
|
|
13
|
+
free: UniffiForeignFutureDroppedCallback;
|
|
14
|
+
};
|