@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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Generated by uniffi-bindgen-react-native — do not edit.
|
|
2
|
+
export * from './cua_sdk.js';
|
|
3
|
+
import * as cua_sdk from './cua_sdk.js';
|
|
4
|
+
let initialized = false;
|
|
5
|
+
if (!initialized) {
|
|
6
|
+
cua_sdk.default.initialize();
|
|
7
|
+
initialized = true;
|
|
8
|
+
}
|
|
9
|
+
export async function uniffiInitAsync() { }
|
|
10
|
+
export default {
|
|
11
|
+
cua_sdk,
|
|
12
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolveLibPath } from "@ubjs/node/typescript/dist/resolve-lib.js";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
FfiType: {
|
|
4
|
+
UInt8: {
|
|
5
|
+
tag: string;
|
|
6
|
+
};
|
|
7
|
+
Int8: {
|
|
8
|
+
tag: string;
|
|
9
|
+
};
|
|
10
|
+
UInt16: {
|
|
11
|
+
tag: string;
|
|
12
|
+
};
|
|
13
|
+
Int16: {
|
|
14
|
+
tag: string;
|
|
15
|
+
};
|
|
16
|
+
UInt32: {
|
|
17
|
+
tag: string;
|
|
18
|
+
};
|
|
19
|
+
Int32: {
|
|
20
|
+
tag: string;
|
|
21
|
+
};
|
|
22
|
+
UInt64: {
|
|
23
|
+
tag: string;
|
|
24
|
+
};
|
|
25
|
+
Int64: {
|
|
26
|
+
tag: string;
|
|
27
|
+
};
|
|
28
|
+
Float32: {
|
|
29
|
+
tag: string;
|
|
30
|
+
};
|
|
31
|
+
Float64: {
|
|
32
|
+
tag: string;
|
|
33
|
+
};
|
|
34
|
+
Handle: {
|
|
35
|
+
tag: string;
|
|
36
|
+
};
|
|
37
|
+
RustBuffer: {
|
|
38
|
+
tag: string;
|
|
39
|
+
};
|
|
40
|
+
ForeignBytes: {
|
|
41
|
+
tag: string;
|
|
42
|
+
};
|
|
43
|
+
RustCallStatus: {
|
|
44
|
+
tag: string;
|
|
45
|
+
};
|
|
46
|
+
VoidPointer: {
|
|
47
|
+
tag: string;
|
|
48
|
+
};
|
|
49
|
+
Void: {
|
|
50
|
+
tag: string;
|
|
51
|
+
};
|
|
52
|
+
Callback: (name: string) => {
|
|
53
|
+
tag: string;
|
|
54
|
+
name: string;
|
|
55
|
+
};
|
|
56
|
+
Struct: (name: string) => {
|
|
57
|
+
tag: string;
|
|
58
|
+
name: string;
|
|
59
|
+
};
|
|
60
|
+
Reference: (inner: unknown) => {
|
|
61
|
+
tag: string;
|
|
62
|
+
inner: unknown;
|
|
63
|
+
};
|
|
64
|
+
MutReference: (inner: unknown) => {
|
|
65
|
+
tag: string;
|
|
66
|
+
inner: unknown;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
resolveLibPath: typeof resolveLibPath;
|
|
70
|
+
UniffiNativeModule: unknown;
|
|
71
|
+
};
|
|
72
|
+
export default _default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { resolveLibPath } from "@ubjs/node/typescript/dist/resolve-lib.js";
|
|
4
|
+
const FfiType = {
|
|
5
|
+
UInt8: { tag: "UInt8" },
|
|
6
|
+
Int8: { tag: "Int8" },
|
|
7
|
+
UInt16: { tag: "UInt16" },
|
|
8
|
+
Int16: { tag: "Int16" },
|
|
9
|
+
UInt32: { tag: "UInt32" },
|
|
10
|
+
Int32: { tag: "Int32" },
|
|
11
|
+
UInt64: { tag: "UInt64" },
|
|
12
|
+
Int64: { tag: "Int64" },
|
|
13
|
+
Float32: { tag: "Float32" },
|
|
14
|
+
Float64: { tag: "Float64" },
|
|
15
|
+
Handle: { tag: "Handle" },
|
|
16
|
+
RustBuffer: { tag: "RustBuffer" },
|
|
17
|
+
ForeignBytes: { tag: "ForeignBytes" },
|
|
18
|
+
RustCallStatus: { tag: "RustCallStatus" },
|
|
19
|
+
VoidPointer: { tag: "VoidPointer" },
|
|
20
|
+
Void: { tag: "Void" },
|
|
21
|
+
Callback: (name) => ({ tag: "Callback", name }),
|
|
22
|
+
Struct: (name) => ({ tag: "Struct", name }),
|
|
23
|
+
Reference: (inner) => ({ tag: "Reference", inner }),
|
|
24
|
+
MutReference: (inner) => ({ tag: "MutReference", inner }),
|
|
25
|
+
};
|
|
26
|
+
const sdkLibrary = resolveLibPath({
|
|
27
|
+
crateName: "cua_sdk",
|
|
28
|
+
callerUrl: import.meta.url,
|
|
29
|
+
npmPackageBase: "@trycua/cua-",
|
|
30
|
+
tripleStyle: "node",
|
|
31
|
+
});
|
|
32
|
+
const runtimePath = join(dirname(sdkLibrary), "cua_node_runtime.node");
|
|
33
|
+
const require = createRequire(import.meta.url);
|
|
34
|
+
const { UniffiNativeModule } = require(runtimePath);
|
|
35
|
+
export default { FfiType, resolveLibPath, UniffiNativeModule };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** A presence cursor shape (the names of `cua.env.v1.CursorShape`). */
|
|
2
|
+
export type CursorShapeName = "arrow" | "text" | "pointer" | "resize_ew" | "resize_ns" | "resize_nwse" | "resize_nesw" | "move" | "crosshair" | "wait" | "progress" | "not_allowed" | "grab" | "grabbing";
|
|
3
|
+
/** Every shape, in wire order. */
|
|
4
|
+
export declare const CURSOR_SHAPES: readonly CursorShapeName[];
|
|
5
|
+
/** One shape's art: an SVG path (absolute M, L, C, Z; nonzero fill) and its hot spot. */
|
|
6
|
+
export interface CursorArtShape {
|
|
7
|
+
hotspot: readonly [number, number];
|
|
8
|
+
d: string;
|
|
9
|
+
}
|
|
10
|
+
/** The shared presence cursor art: fill with the participant's color over the outline. */
|
|
11
|
+
export declare const CURSOR_ART: {
|
|
12
|
+
canvas: number;
|
|
13
|
+
outline: {
|
|
14
|
+
color: string;
|
|
15
|
+
width: number;
|
|
16
|
+
};
|
|
17
|
+
shapes: Readonly<Record<CursorShapeName, CursorArtShape>>;
|
|
18
|
+
};
|
|
19
|
+
/** Whether `name` is a known shape. */
|
|
20
|
+
export declare function isCursorShape(name: unknown): name is CursorShapeName;
|
|
21
|
+
/** The art for `shape`; unknown names get the arrow. */
|
|
22
|
+
export declare function cursorArt(shape: string): CursorArtShape;
|
|
23
|
+
/**
|
|
24
|
+
* A standalone SVG of `shape` filled with `color`, `size` pixels square.
|
|
25
|
+
* The hot spot is at `cursorArt(shape).hotspot * size / CURSOR_ART.canvas`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function cursorArtSvg(shape: string, color: string, size?: number): string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Generated by libs/cua/scripts/generate-presence-art.mjs from
|
|
2
|
+
// libs/cua/crates/cua-spaces/assets/presence-cursors.json. Do not edit.
|
|
3
|
+
/** Every shape, in wire order. */
|
|
4
|
+
export const CURSOR_SHAPES = Object.freeze([
|
|
5
|
+
"arrow",
|
|
6
|
+
"text",
|
|
7
|
+
"pointer",
|
|
8
|
+
"resize_ew",
|
|
9
|
+
"resize_ns",
|
|
10
|
+
"resize_nwse",
|
|
11
|
+
"resize_nesw",
|
|
12
|
+
"move",
|
|
13
|
+
"crosshair",
|
|
14
|
+
"wait",
|
|
15
|
+
"progress",
|
|
16
|
+
"not_allowed",
|
|
17
|
+
"grab",
|
|
18
|
+
"grabbing",
|
|
19
|
+
]);
|
|
20
|
+
/** The shared presence cursor art: fill with the participant's color over the outline. */
|
|
21
|
+
export const CURSOR_ART = Object.freeze({
|
|
22
|
+
canvas: 32,
|
|
23
|
+
outline: Object.freeze({ color: "#ffffff", width: 2.5 }),
|
|
24
|
+
shapes: Object.freeze({
|
|
25
|
+
arrow: { hotspot: [2, 2], d: "M2 2 L2 24.95 L8.21 19.01 L12.26 28.19 L16.04 26.57 L12.12 17.66 L20.09 17.66 Z" },
|
|
26
|
+
text: { hotspot: [16, 16], d: "M11 4 L21 4 L21 6.5 L17.25 6.5 L17.25 25.5 L21 25.5 L21 28 L11 28 L11 25.5 L14.75 25.5 L14.75 6.5 L11 6.5 Z" },
|
|
27
|
+
pointer: { hotspot: [13, 3], d: "M11 5 C11 2.3 15 2.3 15 5 L15 12.5 C15 11 18.5 11 18.5 12.8 C18.5 11.3 22 11.3 22 13.2 C22 11.8 25 11.8 25 13.8 L25 21 C25 25.5 22.5 28 18.5 28 L14.5 28 C11.5 28 10 26.5 8.5 24 L5.2 18.2 C4.3 16.6 6.4 15.2 7.7 16.4 L11 19.5 Z" },
|
|
28
|
+
resize_ew: { hotspot: [16, 16], d: "M4 16 L10 10 L10 14 L22 14 L22 10 L28 16 L22 22 L22 18 L10 18 L10 22 Z" },
|
|
29
|
+
resize_ns: { hotspot: [16, 16], d: "M16 4 L22 10 L18 10 L18 22 L22 22 L16 28 L10 22 L14 22 L14 10 L10 10 Z" },
|
|
30
|
+
resize_nwse: { hotspot: [16, 16], d: "M7.51 7.51 L16 7.51 L13.17 10.34 L21.66 18.83 L24.49 16 L24.49 24.49 L16 24.49 L18.83 21.66 L10.34 13.17 L7.51 16 Z" },
|
|
31
|
+
resize_nesw: { hotspot: [16, 16], d: "M7.51 24.49 L7.51 16 L10.34 18.83 L18.83 10.34 L16 7.51 L24.49 7.51 L24.49 16 L21.66 13.17 L13.17 21.66 L16 24.49 Z" },
|
|
32
|
+
move: { hotspot: [16, 16], d: "M16 3 L21 8 L17.5 8 L17.5 14.5 L24 14.5 L24 11 L29 16 L24 21 L24 17.5 L17.5 17.5 L17.5 24 L21 24 L16 29 L11 24 L14.5 24 L14.5 17.5 L8 17.5 L8 21 L3 16 L8 11 L8 14.5 L14.5 14.5 L14.5 8 L11 8 Z" },
|
|
33
|
+
crosshair: { hotspot: [16, 16], d: "M15 4 L17 4 L17 13 L15 13 Z M15 19 L17 19 L17 28 L15 28 Z M4 15 L13 15 L13 17 L4 17 Z M19 15 L28 15 L28 17 L19 17 Z" },
|
|
34
|
+
wait: { hotspot: [16, 16], d: "M16 5 C22.08 5 27 9.92 27 16 C27 22.08 22.08 27 16 27 C9.92 27 5 22.08 5 16 C5 9.92 9.92 5 16 5 Z M16 9.5 C12.41 9.5 9.5 12.41 9.5 16 C9.5 19.59 12.41 22.5 16 22.5 C19.59 22.5 22.5 19.59 22.5 16 C22.5 12.41 19.59 9.5 16 9.5 Z M16 16 L16 5 L27 16 Z" },
|
|
35
|
+
progress: { hotspot: [2, 2], d: "M2 2 L2 24.95 L8.21 19.01 L12.26 28.19 L16.04 26.57 L12.12 17.66 L20.09 17.66 Z M24 18 C27.31 18 30 20.69 30 24 C30 27.31 27.31 30 24 30 C20.69 30 18 27.31 18 24 C18 20.69 20.69 18 24 18 Z M24 20.5 C22.07 20.5 20.5 22.07 20.5 24 C20.5 25.93 22.07 27.5 24 27.5 C25.93 27.5 27.5 25.93 27.5 24 C27.5 22.07 25.93 20.5 24 20.5 Z" },
|
|
36
|
+
not_allowed: { hotspot: [16, 16], d: "M16 5 C22.08 5 27 9.92 27 16 C27 22.08 22.08 27 16 27 C9.92 27 5 22.08 5 16 C5 9.92 9.92 5 16 5 Z M16 8.5 C11.86 8.5 8.5 11.86 8.5 16 C8.5 20.14 11.86 23.5 16 23.5 C20.14 23.5 23.5 20.14 23.5 16 C23.5 11.86 20.14 8.5 16 8.5 Z M11.93 10.17 L21.83 20.07 L20.07 21.83 L10.17 11.93 Z" },
|
|
37
|
+
grab: { hotspot: [16, 16], d: "M8 12 C8 9.5 11.5 9.5 11.5 12 L11.5 9 C11.5 6.5 15 6.5 15 9 L15 8 C15 5.5 18.5 5.5 18.5 8 L18.5 9 C18.5 6.5 22 6.5 22 9 L22 13 C22 11 25 11 25 13 L25 20 C25 25 22 28 18 28 L14 28 C10.5 28 8 25.5 8 22 Z" },
|
|
38
|
+
grabbing: { hotspot: [16, 16], d: "M8 16 C8 13.5 11.5 13.5 11.5 15 C11.5 12.5 15 12.5 15 14.5 C15 12 18.5 12 18.5 14.5 C18.5 12.5 22 12.5 22 15 C22 13.5 25 13.5 25 16 L25 21 C25 25.5 22 28 18 28 L14 28 C10.5 28 8 25.5 8 22 Z" },
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
/** Whether `name` is a known shape. */
|
|
42
|
+
export function isCursorShape(name) {
|
|
43
|
+
return typeof name === "string" && Object.prototype.hasOwnProperty.call(CURSOR_ART.shapes, name);
|
|
44
|
+
}
|
|
45
|
+
/** The art for `shape`; unknown names get the arrow. */
|
|
46
|
+
export function cursorArt(shape) {
|
|
47
|
+
return isCursorShape(shape) ? CURSOR_ART.shapes[shape] : CURSOR_ART.shapes.arrow;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A standalone SVG of `shape` filled with `color`, `size` pixels square.
|
|
51
|
+
* The hot spot is at `cursorArt(shape).hotspot * size / CURSOR_ART.canvas`.
|
|
52
|
+
*/
|
|
53
|
+
export function cursorArtSvg(shape, color, size = CURSOR_ART.canvas) {
|
|
54
|
+
const a = cursorArt(shape);
|
|
55
|
+
const c = CURSOR_ART.canvas;
|
|
56
|
+
const fill = /^#[0-9a-fA-F]{3,8}$/.test(color) ? color : "#3b82f6";
|
|
57
|
+
return (`<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${c} ${c}">` +
|
|
58
|
+
`<path d="${a.d}" fill="${fill}" stroke="${CURSOR_ART.outline.color}" stroke-width="${CURSOR_ART.outline.width}" stroke-linejoin="round" paint-order="stroke"/></svg>`);
|
|
59
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every failure in this SDK is an exception with a stable `code`.
|
|
3
|
+
*
|
|
4
|
+
* There is exactly one rule here and it is not negotiable: **no call in this
|
|
5
|
+
* SDK resolves successfully unless the remote side proved the effect
|
|
6
|
+
* happened.** Cua has shipped clicks that acked in 3ms and injected nothing,
|
|
7
|
+
* uploads that reported success for files that never landed, and a decoder
|
|
8
|
+
* that drained every chunk and emitted nothing. An SDK is where that class of
|
|
9
|
+
* bug becomes a third party's outage, so the primitives here verify and then
|
|
10
|
+
* throw rather than return an optimistic value.
|
|
11
|
+
*/
|
|
12
|
+
/** Stable, matchable error codes. Adding a code is a minor release; removing or
|
|
13
|
+
* repurposing one is a breaking release. */
|
|
14
|
+
export type SpacesErrorCode =
|
|
15
|
+
/** Credentials missing or rejected by the token endpoint. */
|
|
16
|
+
'auth'
|
|
17
|
+
/** Transport-level failure: DNS, connect, TLS, socket reset, timeout. */
|
|
18
|
+
| 'transport'
|
|
19
|
+
/** The control plane answered, but with a non-success status. */
|
|
20
|
+
| 'http'
|
|
21
|
+
/** The control plane answered with a body this SDK cannot interpret. */
|
|
22
|
+
| 'protocol'
|
|
23
|
+
/** The caller passed something this SDK rejects before any I/O. */
|
|
24
|
+
| 'usage'
|
|
25
|
+
/** A Space, thread or run id does not exist (or is no longer bound). */
|
|
26
|
+
| 'not_found'
|
|
27
|
+
/** A bare name matches Spaces in more than one location; the message lists
|
|
28
|
+
* the ids to use (`local:<name>`, `cloud:<name>`). */
|
|
29
|
+
| 'ambiguous_sandbox'
|
|
30
|
+
/** An operation timed out waiting for a remote state change. */
|
|
31
|
+
| 'timeout'
|
|
32
|
+
/** A file transfer completed but could not be proved intact. */
|
|
33
|
+
| 'verification'
|
|
34
|
+
/** A shared-Space operation was refused because isolation was not acknowledged. */
|
|
35
|
+
| 'isolation'
|
|
36
|
+
/** A command ran inside the Space and exited non-zero. */
|
|
37
|
+
| 'space_command'
|
|
38
|
+
/** The host presentation channel (Cua Spaces desktop app) is not reachable. */
|
|
39
|
+
| 'host_unavailable'
|
|
40
|
+
/** The requested capability exists in the product but not on this path yet. */
|
|
41
|
+
| 'unsupported'
|
|
42
|
+
/** The Space's spacesd reports a feature this call needs as unsupported. */
|
|
43
|
+
| 'capability_missing'
|
|
44
|
+
/** A host-side prerequisite (app sessions, a local runtime) is missing. */
|
|
45
|
+
| 'host_capability_missing'
|
|
46
|
+
/** The Space has no cua-spacesd. */
|
|
47
|
+
| 'spacesd_not_available'
|
|
48
|
+
/** The teleport consent gate refused (or the approver declined). */
|
|
49
|
+
| 'teleport_refused';
|
|
50
|
+
export interface SpacesErrorOptions {
|
|
51
|
+
cause?: unknown;
|
|
52
|
+
/** Free-form, already-redacted detail shown in the message. */
|
|
53
|
+
detail?: string;
|
|
54
|
+
/** HTTP status, when code is 'http'. */
|
|
55
|
+
status?: number;
|
|
56
|
+
/** Request target, for triage. Never carries credentials. */
|
|
57
|
+
target?: string;
|
|
58
|
+
}
|
|
59
|
+
/** Trim an untrusted body for an error message without hiding it entirely. */
|
|
60
|
+
export declare function excerpt(body: string, max?: number): string;
|
|
61
|
+
export declare class SpacesError extends Error {
|
|
62
|
+
readonly code: SpacesErrorCode;
|
|
63
|
+
readonly status: number | undefined;
|
|
64
|
+
readonly target: string | undefined;
|
|
65
|
+
readonly detail: string | undefined;
|
|
66
|
+
constructor(code: SpacesErrorCode, message: string, options?: SpacesErrorOptions);
|
|
67
|
+
static auth(message: string, options?: SpacesErrorOptions): SpacesError;
|
|
68
|
+
static usage(message: string, options?: SpacesErrorOptions): SpacesError;
|
|
69
|
+
static protocol(message: string, options?: SpacesErrorOptions): SpacesError;
|
|
70
|
+
static timeout(message: string, options?: SpacesErrorOptions): SpacesError;
|
|
71
|
+
}
|
|
72
|
+
/** Narrowing helper for consumers: `if (isSpacesError(e, 'verification')) …` */
|
|
73
|
+
export declare function isSpacesError(value: unknown, code?: SpacesErrorCode): value is SpacesError;
|
|
74
|
+
/**
|
|
75
|
+
* Wraps anything the native SDK threw as a {@link SpacesError} with a stable
|
|
76
|
+
* code (the `CuaError` variant stays reachable as `cause`). Already-wrapped
|
|
77
|
+
* errors pass through.
|
|
78
|
+
*/
|
|
79
|
+
export declare function toSpacesError(error: unknown): SpacesError;
|
|
80
|
+
/** Runs `body`, rethrowing native errors as {@link SpacesError}. */
|
|
81
|
+
export declare function wrapErrors<T>(body: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every failure in this SDK is an exception with a stable `code`.
|
|
3
|
+
*
|
|
4
|
+
* There is exactly one rule here and it is not negotiable: **no call in this
|
|
5
|
+
* SDK resolves successfully unless the remote side proved the effect
|
|
6
|
+
* happened.** Cua has shipped clicks that acked in 3ms and injected nothing,
|
|
7
|
+
* uploads that reported success for files that never landed, and a decoder
|
|
8
|
+
* that drained every chunk and emitted nothing. An SDK is where that class of
|
|
9
|
+
* bug becomes a third party's outage, so the primitives here verify and then
|
|
10
|
+
* throw rather than return an optimistic value.
|
|
11
|
+
*/
|
|
12
|
+
/** Trim an untrusted body for an error message without hiding it entirely. */
|
|
13
|
+
export function excerpt(body, max = 400) {
|
|
14
|
+
const flat = body.replace(/\s+/g, ' ').trim();
|
|
15
|
+
return flat.length <= max ? flat : `${flat.slice(0, max)}… (${flat.length} bytes)`;
|
|
16
|
+
}
|
|
17
|
+
export class SpacesError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
status;
|
|
20
|
+
target;
|
|
21
|
+
detail;
|
|
22
|
+
constructor(code, message, options = {}) {
|
|
23
|
+
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
24
|
+
this.name = 'SpacesError';
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.status = options.status;
|
|
27
|
+
this.target = options.target;
|
|
28
|
+
this.detail = options.detail;
|
|
29
|
+
}
|
|
30
|
+
static auth(message, options) {
|
|
31
|
+
return new SpacesError('auth', message, options);
|
|
32
|
+
}
|
|
33
|
+
static usage(message, options) {
|
|
34
|
+
return new SpacesError('usage', message, options);
|
|
35
|
+
}
|
|
36
|
+
static protocol(message, options) {
|
|
37
|
+
return new SpacesError('protocol', message, options);
|
|
38
|
+
}
|
|
39
|
+
static timeout(message, options) {
|
|
40
|
+
return new SpacesError('timeout', message, options);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Narrowing helper for consumers: `if (isSpacesError(e, 'verification')) …` */
|
|
44
|
+
export function isSpacesError(value, code) {
|
|
45
|
+
return value instanceof SpacesError && (code === undefined || value.code === code);
|
|
46
|
+
}
|
|
47
|
+
/** Maps a `CuaError` variant tag (from the native binding) to a code. */
|
|
48
|
+
const CUA_TAGS = {
|
|
49
|
+
InvalidArgument: 'usage',
|
|
50
|
+
NotFound: 'not_found',
|
|
51
|
+
AmbiguousSandbox: 'ambiguous_sandbox',
|
|
52
|
+
ProviderNotConfigured: 'auth',
|
|
53
|
+
Unsupported: 'unsupported',
|
|
54
|
+
SpacesdNotAvailable: 'spacesd_not_available',
|
|
55
|
+
Timeout: 'timeout',
|
|
56
|
+
Fleet: 'http',
|
|
57
|
+
// Fleet's admission refused a size over the account's limits (Fleet's
|
|
58
|
+
// message names the limit): pick a smaller size.
|
|
59
|
+
FleetAdmissionDenied: 'usage',
|
|
60
|
+
// Out of Cua Cloud credit (the message names the billing page): add
|
|
61
|
+
// credit there, or run locally.
|
|
62
|
+
CloudCreditExhausted: 'usage',
|
|
63
|
+
Runtime: 'space_command',
|
|
64
|
+
Env: 'space_command',
|
|
65
|
+
Http: 'http',
|
|
66
|
+
Unauthenticated: 'auth',
|
|
67
|
+
PermissionDenied: 'auth',
|
|
68
|
+
Transport: 'transport',
|
|
69
|
+
// No `cua daemon` answers (start Cua, or run `cua daemon start`).
|
|
70
|
+
DaemonNotRunning: 'transport',
|
|
71
|
+
Closed: 'transport',
|
|
72
|
+
CapabilityMissing: 'capability_missing',
|
|
73
|
+
HostCapabilityMissing: 'host_capability_missing',
|
|
74
|
+
TeleportRefused: 'teleport_refused',
|
|
75
|
+
Internal: 'protocol',
|
|
76
|
+
// A pull, build or VM create would fill the disk (`cua cache prune`).
|
|
77
|
+
InsufficientDisk: 'space_command',
|
|
78
|
+
// A catalog image CI has not published yet (pass the ref explicitly).
|
|
79
|
+
ImageNotPublished: 'not_found',
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Wraps anything the native SDK threw as a {@link SpacesError} with a stable
|
|
83
|
+
* code (the `CuaError` variant stays reachable as `cause`). Already-wrapped
|
|
84
|
+
* errors pass through.
|
|
85
|
+
*/
|
|
86
|
+
export function toSpacesError(error) {
|
|
87
|
+
if (error instanceof SpacesError)
|
|
88
|
+
return error;
|
|
89
|
+
const tag = error?.tag;
|
|
90
|
+
const code = typeof tag === 'string' ? CUA_TAGS[tag] : undefined;
|
|
91
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
92
|
+
return new SpacesError(code ?? 'protocol', message, { cause: error });
|
|
93
|
+
}
|
|
94
|
+
/** Runs `body`, rethrowing native errors as {@link SpacesError}. */
|
|
95
|
+
export async function wrapErrors(body) {
|
|
96
|
+
try {
|
|
97
|
+
return await body();
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw toSpacesError(error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an agent sends back.
|
|
3
|
+
*
|
|
4
|
+
* The honest situation, as of this release: the agent runtime inside a Space is
|
|
5
|
+
* a terminal. `agent_status` returns the tail of the run's output (the agent
|
|
6
|
+
* runs as a detached, tagged cua-spacesd process). There is no structured
|
|
7
|
+
* result channel yet — no file manifest, no image parts, no approval
|
|
8
|
+
* protocol. The supported agents are launched auto-approved and the sandbox is
|
|
9
|
+
* the safety boundary.
|
|
10
|
+
*
|
|
11
|
+
* So this module does two things and is careful about the difference:
|
|
12
|
+
*
|
|
13
|
+
* 1. It defines the *result model* a chat app with agent coworkers needs — text, files,
|
|
14
|
+
* images, links, approval requests — as a stable discriminated union, so an
|
|
15
|
+
* app can be written against it today and keep working when the runtime
|
|
16
|
+
* starts emitting the real thing.
|
|
17
|
+
* 2. It derives what it can from the terminal transcript, and marks every
|
|
18
|
+
* derived event `derived: true`. A consumer can therefore tell a fact
|
|
19
|
+
* ("the agent emitted this file") from an inference ("a path-shaped string
|
|
20
|
+
* appeared in the scrollback"). Nothing here pretends to be ground truth.
|
|
21
|
+
*
|
|
22
|
+
* When the agent runtime gains a structured channel (see `docs/`), the adapter
|
|
23
|
+
* gains a branch that emits the same events with `derived: false`. The union is
|
|
24
|
+
* the stable contract; the adapter is not.
|
|
25
|
+
*/
|
|
26
|
+
export type ThreadEventKind = 'text' | 'file' | 'image' | 'link' | 'approval_request' | 'state' | 'error';
|
|
27
|
+
interface ThreadEventBase {
|
|
28
|
+
kind: ThreadEventKind;
|
|
29
|
+
/** Monotonic within a thread, assigned by the SDK. */
|
|
30
|
+
seq: number;
|
|
31
|
+
/** Wall clock at the moment the SDK observed it, not when the agent produced it. */
|
|
32
|
+
observedAt: string;
|
|
33
|
+
/**
|
|
34
|
+
* `true` when this event was inferred from unstructured terminal output
|
|
35
|
+
* rather than reported by the agent runtime. Always check it before treating
|
|
36
|
+
* an event as authoritative.
|
|
37
|
+
*/
|
|
38
|
+
derived: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface TextEvent extends ThreadEventBase {
|
|
41
|
+
kind: 'text';
|
|
42
|
+
text: string;
|
|
43
|
+
}
|
|
44
|
+
/** A file the agent appears to have produced, by absolute path inside the Space.
|
|
45
|
+
* Fetch it with `space.download(path, destDir)` — the SDK does not pre-fetch. */
|
|
46
|
+
export interface FileEvent extends ThreadEventBase {
|
|
47
|
+
kind: 'file';
|
|
48
|
+
path: string;
|
|
49
|
+
}
|
|
50
|
+
/** An image the agent produced. `data` is base64; `path` is set instead when the
|
|
51
|
+
* image is only known by its in-Space location. */
|
|
52
|
+
export interface ImageEvent extends ThreadEventBase {
|
|
53
|
+
kind: 'image';
|
|
54
|
+
mimeType: string;
|
|
55
|
+
data?: string;
|
|
56
|
+
path?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LinkEvent extends ThreadEventBase {
|
|
59
|
+
kind: 'link';
|
|
60
|
+
url: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The agent is blocked on a human decision.
|
|
64
|
+
*
|
|
65
|
+
* No agent runtime in a Space emits this today (they run auto-approved). It is
|
|
66
|
+
* defined because an app that puts an agent in front of a user needs the shape,
|
|
67
|
+
* and because a derived detector can spot a REPL prompt that is waiting. Answer
|
|
68
|
+
* it with `thread.send(...)` — there is no separate approval RPC yet, and this
|
|
69
|
+
* SDK will not invent one that silently does nothing.
|
|
70
|
+
*/
|
|
71
|
+
export interface ApprovalRequestEvent extends ThreadEventBase {
|
|
72
|
+
kind: 'approval_request';
|
|
73
|
+
prompt: string;
|
|
74
|
+
/** Choices parsed from the prompt, when they were parseable. */
|
|
75
|
+
options: string[];
|
|
76
|
+
}
|
|
77
|
+
export interface StateEvent extends ThreadEventBase {
|
|
78
|
+
kind: 'state';
|
|
79
|
+
state: AgentStatus;
|
|
80
|
+
/** The ladder's reason for this status. */
|
|
81
|
+
reason: string;
|
|
82
|
+
}
|
|
83
|
+
export interface ErrorEvent extends ThreadEventBase {
|
|
84
|
+
kind: 'error';
|
|
85
|
+
message: string;
|
|
86
|
+
}
|
|
87
|
+
export type ThreadEvent = TextEvent | FileEvent | ImageEvent | LinkEvent | ApprovalRequestEvent | StateEvent | ErrorEvent;
|
|
88
|
+
/**
|
|
89
|
+
* The agent status ladder — one closed vocabulary for every harness and every
|
|
90
|
+
* provider. A UI can rely on this being closed.
|
|
91
|
+
*
|
|
92
|
+
* `idle` and `finished` are deliberately different: both mean "no turn is
|
|
93
|
+
* running", but `idle` means the session can still be continued and `finished`
|
|
94
|
+
* means it cannot.
|
|
95
|
+
*
|
|
96
|
+
* `unknown` is a real, reachable state and is **not** a synonym for "done". A
|
|
97
|
+
* probe that could not run, an unreachable Space, and an interactive REPL whose
|
|
98
|
+
* working-vs-waiting we cannot tell apart all land here. Reporting any of them
|
|
99
|
+
* as `idle` is how a caller concludes an agent finished when the Space actually
|
|
100
|
+
* fell over — and `crashed` exists so a dead process that never recorded an
|
|
101
|
+
* exit status is never read as a clean finish.
|
|
102
|
+
*/
|
|
103
|
+
export type AgentStatus = 'running' | 'awaiting_input' | 'idle' | 'finished' | 'failed' | 'crashed' | 'unknown';
|
|
104
|
+
/** Everything the SDK knows about a run's current moment. */
|
|
105
|
+
export interface ThreadStatus {
|
|
106
|
+
runId: string;
|
|
107
|
+
status: AgentStatus;
|
|
108
|
+
/** Why the ladder landed there, in words. Always populated. */
|
|
109
|
+
reason: string;
|
|
110
|
+
/** A follow-up sent now starts the next turn: the server's published
|
|
111
|
+
* rule (idle, or a crashed or failed run it restarts; not mid-turn). */
|
|
112
|
+
acceptsMessage: boolean;
|
|
113
|
+
/** The raw transcript tail exactly as the Space reported it. Always present,
|
|
114
|
+
* because every derived event above is an interpretation of this. */
|
|
115
|
+
transcript: string;
|
|
116
|
+
/** The agent's terminal window on the Space desktop, when it was found.
|
|
117
|
+
* `null` means "not found", which is not the same as "does not exist". */
|
|
118
|
+
desktopWindow: string | null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Turns a growing transcript into events, without re-emitting what it already
|
|
122
|
+
* emitted.
|
|
123
|
+
*
|
|
124
|
+
* The runtime gives us a *tail*, not a stream, so the adapter tracks what it has
|
|
125
|
+
* consumed by content, not by offset: a tail that scrolled past our last known
|
|
126
|
+
* position is detected, and only the portion it can prove is new is emitted.
|
|
127
|
+
* When it cannot prove overlap at all — the tail
|
|
128
|
+
* scrolled entirely past — it emits the whole tail and an `error` event saying
|
|
129
|
+
* output was lost, rather than silently dropping it.
|
|
130
|
+
*/
|
|
131
|
+
export declare class TranscriptAdapter {
|
|
132
|
+
private consumed;
|
|
133
|
+
private seq;
|
|
134
|
+
/** Feed the newest transcript tail; get back only the newly observed events. */
|
|
135
|
+
ingest(tail: string, now?: () => Date): ThreadEvent[];
|
|
136
|
+
/** Reset for a new turn that restarts the session (codex `resume` does this). */
|
|
137
|
+
reset(): void;
|
|
138
|
+
private diff;
|
|
139
|
+
private extract;
|
|
140
|
+
private make;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Spot a terminal prompt that is waiting on a human.
|
|
144
|
+
*
|
|
145
|
+
* Only fires on a prompt at the very end of the fresh output — a question in
|
|
146
|
+
* the middle of the scrollback has already been answered. Recognizes the two
|
|
147
|
+
* common shapes: a `[y/N]`-style suffix and a numbered choice list followed by
|
|
148
|
+
* a prompt line.
|
|
149
|
+
*/
|
|
150
|
+
export declare function detectApproval(fresh: string): {
|
|
151
|
+
prompt: string;
|
|
152
|
+
options: string[];
|
|
153
|
+
} | null;
|
|
154
|
+
export {};
|