@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.
Files changed (91) hide show
  1. package/README.md +121 -0
  2. package/bin/cua.js +37 -0
  3. package/browser/cua_sdk-ffi.d.ts +6 -0
  4. package/browser/cua_sdk-ffi.js +3 -0
  5. package/browser/cua_sdk-ffi.ts +14 -0
  6. package/browser/cua_sdk.d.ts +2237 -0
  7. package/browser/cua_sdk.js +2607 -0
  8. package/browser/cua_sdk.ts +3644 -0
  9. package/browser/cyclops_sdk_schema-ffi.d.ts +6 -0
  10. package/browser/cyclops_sdk_schema-ffi.js +3 -0
  11. package/browser/cyclops_sdk_schema-ffi.ts +14 -0
  12. package/browser/cyclops_sdk_schema.d.ts +996 -0
  13. package/browser/cyclops_sdk_schema.js +2194 -0
  14. package/browser/cyclops_sdk_schema.ts +2934 -0
  15. package/browser/fleet_sdk-ffi.d.ts +28 -0
  16. package/browser/fleet_sdk-ffi.js +3 -0
  17. package/browser/fleet_sdk-ffi.ts +35 -0
  18. package/browser/fleet_sdk.d.ts +3056 -0
  19. package/browser/fleet_sdk.js +5088 -0
  20. package/browser/fleet_sdk.ts +6830 -0
  21. package/browser/index.d.ts +2 -0
  22. package/browser/index.js +18 -0
  23. package/browser/index.web.ts +34 -0
  24. package/browser/tsconfig.json +20 -0
  25. package/browser/wasm-bindgen/index.d.ts +2346 -0
  26. package/browser/wasm-bindgen/index.js +6642 -0
  27. package/browser/wasm-bindgen/index_bg.wasm +0 -0
  28. package/browser/wasm-bindgen/index_bg.wasm.d.ts +1154 -0
  29. package/dist/index.d.ts +118 -0
  30. package/dist/index.js +207 -0
  31. package/dist/mcp.d.ts +33 -0
  32. package/dist/mcp.js +41 -0
  33. package/dist/native/cua_sdk-ffi.d.ts +1038 -0
  34. package/dist/native/cua_sdk-ffi.js +5095 -0
  35. package/dist/native/cua_sdk.d.ts +15906 -0
  36. package/dist/native/cua_sdk.js +27061 -0
  37. package/dist/native/index.d.ts +7 -0
  38. package/dist/native/index.js +12 -0
  39. package/dist/native/node-runtime.d.ts +72 -0
  40. package/dist/native/node-runtime.js +35 -0
  41. package/dist/spaces/cursorArt.d.ts +27 -0
  42. package/dist/spaces/cursorArt.js +59 -0
  43. package/dist/spaces/errors.d.ts +81 -0
  44. package/dist/spaces/errors.js +102 -0
  45. package/dist/spaces/events.d.ts +154 -0
  46. package/dist/spaces/events.js +182 -0
  47. package/dist/spaces/groups.d.ts +130 -0
  48. package/dist/spaces/groups.js +275 -0
  49. package/dist/spaces/host.d.ts +71 -0
  50. package/dist/spaces/host.js +154 -0
  51. package/dist/spaces/index.d.ts +48 -0
  52. package/dist/spaces/index.js +44 -0
  53. package/dist/spaces/pip.d.ts +128 -0
  54. package/dist/spaces/pip.js +250 -0
  55. package/dist/spaces/presence.d.ts +187 -0
  56. package/dist/spaces/presence.js +449 -0
  57. package/dist/spaces/presenceTypes.check.d.ts +12 -0
  58. package/dist/spaces/presenceTypes.check.js +1 -0
  59. package/dist/spaces/presenceTypes.d.ts +47 -0
  60. package/dist/spaces/presenceTypes.js +7 -0
  61. package/dist/spaces/routines.d.ts +158 -0
  62. package/dist/spaces/routines.js +339 -0
  63. package/dist/spaces/thread.d.ts +147 -0
  64. package/dist/spaces/thread.js +285 -0
  65. package/dist/spaces/transport/http.d.ts +51 -0
  66. package/dist/spaces/transport/http.js +113 -0
  67. package/dist/spaces/transport/index.d.ts +19 -0
  68. package/dist/spaces/transport/index.js +19 -0
  69. package/dist/spaces/transport/session.d.ts +120 -0
  70. package/dist/spaces/transport/session.js +188 -0
  71. package/dist/spaces/transport/tauri.d.ts +50 -0
  72. package/dist/spaces/transport/tauri.js +90 -0
  73. package/dist/spaces/transport/types.d.ts +123 -0
  74. package/dist/spaces/transport/types.js +59 -0
  75. package/dist/teleport/controller.d.ts +34 -0
  76. package/dist/teleport/controller.js +107 -0
  77. package/dist/teleport/drop.d.ts +62 -0
  78. package/dist/teleport/drop.js +138 -0
  79. package/dist/teleport/dropZone.d.ts +59 -0
  80. package/dist/teleport/dropZone.js +166 -0
  81. package/dist/teleport/element.d.ts +28 -0
  82. package/dist/teleport/element.js +340 -0
  83. package/dist/teleport/index.d.ts +32 -0
  84. package/dist/teleport/index.js +32 -0
  85. package/dist/teleport/install.d.ts +31 -0
  86. package/dist/teleport/install.js +65 -0
  87. package/dist/teleport/model.d.ts +245 -0
  88. package/dist/teleport/model.js +334 -0
  89. package/dist/teleport/windowDrag.d.ts +86 -0
  90. package/dist/teleport/windowDrag.js +71 -0
  91. 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,3 @@
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
+ export {};
@@ -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
+ };