@trycua/cua-driver 0.36.0 → 0.38.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 +2 -5
- package/dist/native/cua_driver_contract.d.ts +41 -2
- package/dist/native/cua_driver_contract.js +45 -2
- package/package.json +7 -13
- package/dist/fleet.d.ts +0 -48
- package/dist/fleet.js +0 -98
package/README.md
CHANGED
|
@@ -14,11 +14,8 @@ import { CuaDriver } from "@trycua/cua-driver"
|
|
|
14
14
|
organizational `/embedded` entrypoint; they are the same generated Rust object.
|
|
15
15
|
The `/electron` entrypoint is a thin compatibility naming layer over the same
|
|
16
16
|
generated macOS permission functions. The package does not contain a TypeScript
|
|
17
|
-
MCP protocol implementation.
|
|
18
|
-
|
|
19
|
-
See [the candidate Fleet connection guide](../docs/shared-fleet-mcp-client.md)
|
|
20
|
-
for prerequisites, ownership, and release limits. Agents already have
|
|
21
|
-
runtime-neutral MCP clients and should configure the executable directly:
|
|
17
|
+
MCP protocol implementation. Agents already have runtime-neutral MCP clients
|
|
18
|
+
and should configure the executable directly:
|
|
22
19
|
|
|
23
20
|
```text
|
|
24
21
|
cua-driver mcp
|
|
@@ -77,6 +77,25 @@ export declare const ActionEvidence: Readonly<{
|
|
|
77
77
|
new: (partial: Partial<ActionEvidence> & Required<Omit<ActionEvidence, "detail">>) => ActionEvidence;
|
|
78
78
|
defaults: () => Partial<ActionEvidence>;
|
|
79
79
|
}>;
|
|
80
|
+
/**
|
|
81
|
+
* A call an agent can make next: `{tool, arguments}`.
|
|
82
|
+
*/
|
|
83
|
+
export type ActionNextCall = {
|
|
84
|
+
tool: string;
|
|
85
|
+
/**
|
|
86
|
+
* The call's arguments. A JSON object on the wire; the SDK records carry
|
|
87
|
+
* the same object as JSON text.
|
|
88
|
+
*/
|
|
89
|
+
arguments: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Generated factory for {@link ActionNextCall} record objects.
|
|
93
|
+
*/
|
|
94
|
+
export declare const ActionNextCall: Readonly<{
|
|
95
|
+
create: (partial: Partial<ActionNextCall> & Required<Omit<ActionNextCall, never>>) => ActionNextCall;
|
|
96
|
+
new: (partial: Partial<ActionNextCall> & Required<Omit<ActionNextCall, never>>) => ActionNextCall;
|
|
97
|
+
defaults: () => Partial<ActionNextCall>;
|
|
98
|
+
}>;
|
|
80
99
|
export declare enum ActionEffect {
|
|
81
100
|
Confirmed = 0,
|
|
82
101
|
Partial = 1,
|
|
@@ -109,13 +128,26 @@ export type ActionResult = {
|
|
|
109
128
|
* Present only with `effect: refused`.
|
|
110
129
|
*/
|
|
111
130
|
error?: ActionError;
|
|
131
|
+
/**
|
|
132
|
+
* What to do next, in one short sentence. Present when the effect is
|
|
133
|
+
* `unverifiable` or `suspected_noop`, so an unconfirmed action points at
|
|
134
|
+
* the next step instead of leaving the agent to guess. Also carries a
|
|
135
|
+
* suggestion to chain steps with `run_steps` after several direct actions
|
|
136
|
+
* in a row.
|
|
137
|
+
*/
|
|
138
|
+
hint?: string;
|
|
139
|
+
/**
|
|
140
|
+
* The call that moves the task forward, always safe to run as is (a read,
|
|
141
|
+
* or a call that keeps the user's window where it is).
|
|
142
|
+
*/
|
|
143
|
+
nextCall?: ActionNextCall;
|
|
112
144
|
};
|
|
113
145
|
/**
|
|
114
146
|
* Generated factory for {@link ActionResult} record objects.
|
|
115
147
|
*/
|
|
116
148
|
export declare const ActionResult: Readonly<{
|
|
117
|
-
create: (partial: Partial<ActionResult> & Required<Omit<ActionResult, "delivery" | "evidence" | "escalation" | "summary" | "error">>) => ActionResult;
|
|
118
|
-
new: (partial: Partial<ActionResult> & Required<Omit<ActionResult, "delivery" | "evidence" | "escalation" | "summary" | "error">>) => ActionResult;
|
|
149
|
+
create: (partial: Partial<ActionResult> & Required<Omit<ActionResult, "hint" | "delivery" | "evidence" | "escalation" | "summary" | "error" | "nextCall">>) => ActionResult;
|
|
150
|
+
new: (partial: Partial<ActionResult> & Required<Omit<ActionResult, "hint" | "delivery" | "evidence" | "escalation" | "summary" | "error" | "nextCall">>) => ActionResult;
|
|
119
151
|
defaults: () => Partial<ActionResult>;
|
|
120
152
|
}>;
|
|
121
153
|
export type AppInfo = {
|
|
@@ -2437,6 +2469,13 @@ declare const _default: Readonly<{
|
|
|
2437
2469
|
lift(value: UniffiByteArray): ActionEvidenceKind;
|
|
2438
2470
|
lower(value: ActionEvidenceKind, alloc: import("@ubjs/core").RustBufferAllocator): UniffiByteArray;
|
|
2439
2471
|
};
|
|
2472
|
+
FfiConverterTypeActionNextCall: {
|
|
2473
|
+
read(from: RustBuffer): ActionNextCall;
|
|
2474
|
+
write(value: ActionNextCall, into: RustBuffer): void;
|
|
2475
|
+
allocationSize(value: ActionNextCall): number;
|
|
2476
|
+
lift(value: UniffiByteArray): ActionNextCall;
|
|
2477
|
+
lower(value: ActionNextCall, alloc: import("@ubjs/core").RustBufferAllocator): UniffiByteArray;
|
|
2478
|
+
};
|
|
2440
2479
|
FfiConverterTypeActionResult: {
|
|
2441
2480
|
read(from: RustBuffer): ActionResult;
|
|
2442
2481
|
write(value: ActionResult, into: RustBuffer): void;
|
|
@@ -293,6 +293,40 @@ const FfiConverterTypeActionEvidence = (() => {
|
|
|
293
293
|
;
|
|
294
294
|
return new FFIConverter();
|
|
295
295
|
})();
|
|
296
|
+
/**
|
|
297
|
+
* Generated factory for {@link ActionNextCall} record objects.
|
|
298
|
+
*/
|
|
299
|
+
export const ActionNextCall = (() => {
|
|
300
|
+
const defaults = () => ({});
|
|
301
|
+
const create = (() => {
|
|
302
|
+
return uniffiCreateRecord(defaults);
|
|
303
|
+
})();
|
|
304
|
+
return Object.freeze({
|
|
305
|
+
create,
|
|
306
|
+
new: create,
|
|
307
|
+
defaults: () => Object.freeze(defaults()),
|
|
308
|
+
});
|
|
309
|
+
})();
|
|
310
|
+
const FfiConverterTypeActionNextCall = (() => {
|
|
311
|
+
class FFIConverter extends AbstractFfiConverterByteArray {
|
|
312
|
+
read(from) {
|
|
313
|
+
return {
|
|
314
|
+
tool: FfiConverterString.read(from),
|
|
315
|
+
arguments: FfiConverterString.read(from)
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
write(value, into) {
|
|
319
|
+
FfiConverterString.write(value.tool, into);
|
|
320
|
+
FfiConverterString.write(value.arguments, into);
|
|
321
|
+
}
|
|
322
|
+
allocationSize(value) {
|
|
323
|
+
return FfiConverterString.allocationSize(value.tool) +
|
|
324
|
+
FfiConverterString.allocationSize(value.arguments);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
;
|
|
328
|
+
return new FFIConverter();
|
|
329
|
+
})();
|
|
296
330
|
export var ActionEffect;
|
|
297
331
|
(function (ActionEffect) {
|
|
298
332
|
ActionEffect[ActionEffect["Confirmed"] = 0] = "Confirmed";
|
|
@@ -392,7 +426,9 @@ const FfiConverterTypeActionResult = (() => {
|
|
|
392
426
|
evidence: FfiConverterOptionalSequenceTypeActionEvidence.read(from),
|
|
393
427
|
escalation: FfiConverterOptionalTypeActionEscalation.read(from),
|
|
394
428
|
summary: FfiConverterOptionalString.read(from),
|
|
395
|
-
error: FfiConverterOptionalTypeActionError.read(from)
|
|
429
|
+
error: FfiConverterOptionalTypeActionError.read(from),
|
|
430
|
+
hint: FfiConverterOptionalString.read(from),
|
|
431
|
+
nextCall: FfiConverterOptionalTypeActionNextCall.read(from)
|
|
396
432
|
};
|
|
397
433
|
}
|
|
398
434
|
write(value, into) {
|
|
@@ -403,6 +439,8 @@ const FfiConverterTypeActionResult = (() => {
|
|
|
403
439
|
FfiConverterOptionalTypeActionEscalation.write(value.escalation, into);
|
|
404
440
|
FfiConverterOptionalString.write(value.summary, into);
|
|
405
441
|
FfiConverterOptionalTypeActionError.write(value.error, into);
|
|
442
|
+
FfiConverterOptionalString.write(value.hint, into);
|
|
443
|
+
FfiConverterOptionalTypeActionNextCall.write(value.nextCall, into);
|
|
406
444
|
}
|
|
407
445
|
allocationSize(value) {
|
|
408
446
|
return FfiConverterTypeActionEffect.allocationSize(value.effect) +
|
|
@@ -411,7 +449,9 @@ const FfiConverterTypeActionResult = (() => {
|
|
|
411
449
|
FfiConverterOptionalSequenceTypeActionEvidence.allocationSize(value.evidence) +
|
|
412
450
|
FfiConverterOptionalTypeActionEscalation.allocationSize(value.escalation) +
|
|
413
451
|
FfiConverterOptionalString.allocationSize(value.summary) +
|
|
414
|
-
FfiConverterOptionalTypeActionError.allocationSize(value.error)
|
|
452
|
+
FfiConverterOptionalTypeActionError.allocationSize(value.error) +
|
|
453
|
+
FfiConverterOptionalString.allocationSize(value.hint) +
|
|
454
|
+
FfiConverterOptionalTypeActionNextCall.allocationSize(value.nextCall);
|
|
415
455
|
}
|
|
416
456
|
}
|
|
417
457
|
;
|
|
@@ -4861,6 +4901,8 @@ const FfiConverterOptionalSequenceTypeActionEvidence = new FfiConverterOptional(
|
|
|
4861
4901
|
const FfiConverterOptionalTypeActionEscalation = new FfiConverterOptional(FfiConverterTypeActionEscalation);
|
|
4862
4902
|
// FfiConverter for ActionError | undefined
|
|
4863
4903
|
const FfiConverterOptionalTypeActionError = new FfiConverterOptional(FfiConverterTypeActionError);
|
|
4904
|
+
// FfiConverter for ActionNextCall | undefined
|
|
4905
|
+
const FfiConverterOptionalTypeActionNextCall = new FfiConverterOptional(FfiConverterTypeActionNextCall);
|
|
4864
4906
|
// FfiConverter for number | undefined
|
|
4865
4907
|
const FfiConverterOptionalFloat64 = new FfiConverterOptional(FfiConverterFloat64);
|
|
4866
4908
|
// FfiConverter for ClickButton | undefined
|
|
@@ -4974,6 +5016,7 @@ export default Object.freeze({
|
|
|
4974
5016
|
FfiConverterTypeActionEscalationTarget,
|
|
4975
5017
|
FfiConverterTypeActionEvidence,
|
|
4976
5018
|
FfiConverterTypeActionEvidenceKind,
|
|
5019
|
+
FfiConverterTypeActionNextCall,
|
|
4977
5020
|
FfiConverterTypeActionResult,
|
|
4978
5021
|
FfiConverterTypeActionRoute,
|
|
4979
5022
|
FfiConverterTypeActionTarget,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trycua/cua-driver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "Rust-backed Cua Driver SDK and embedded Node host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,10 +22,6 @@
|
|
|
22
22
|
"./electron": {
|
|
23
23
|
"types": "./dist/electron.d.ts",
|
|
24
24
|
"import": "./dist/electron.js"
|
|
25
|
-
},
|
|
26
|
-
"./fleet": {
|
|
27
|
-
"types": "./dist/fleet.d.ts",
|
|
28
|
-
"import": "./dist/fleet.js"
|
|
29
25
|
}
|
|
30
26
|
},
|
|
31
27
|
"files": [
|
|
@@ -35,8 +31,6 @@
|
|
|
35
31
|
"dist/embedded.d.ts",
|
|
36
32
|
"dist/electron.js",
|
|
37
33
|
"dist/electron.d.ts",
|
|
38
|
-
"dist/fleet.js",
|
|
39
|
-
"dist/fleet.d.ts",
|
|
40
34
|
"dist/native",
|
|
41
35
|
"README.md",
|
|
42
36
|
"dist/daemon.js",
|
|
@@ -50,11 +44,11 @@
|
|
|
50
44
|
"@ubjs/node": "0.31.0-3"
|
|
51
45
|
},
|
|
52
46
|
"optionalDependencies": {
|
|
53
|
-
"@trycua/cua-driver-darwin-arm64": "0.
|
|
54
|
-
"@trycua/cua-driver-darwin-x64": "0.
|
|
55
|
-
"@trycua/cua-driver-linux-arm64-gnu": "0.
|
|
56
|
-
"@trycua/cua-driver-linux-x64-gnu": "0.
|
|
57
|
-
"@trycua/cua-driver-win32-arm64-msvc": "0.
|
|
58
|
-
"@trycua/cua-driver-win32-x64-msvc": "0.
|
|
47
|
+
"@trycua/cua-driver-darwin-arm64": "0.38.0",
|
|
48
|
+
"@trycua/cua-driver-darwin-x64": "0.38.0",
|
|
49
|
+
"@trycua/cua-driver-linux-arm64-gnu": "0.38.0",
|
|
50
|
+
"@trycua/cua-driver-linux-x64-gnu": "0.38.0",
|
|
51
|
+
"@trycua/cua-driver-win32-arm64-msvc": "0.38.0",
|
|
52
|
+
"@trycua/cua-driver-win32-x64-msvc": "0.38.0"
|
|
59
53
|
}
|
|
60
54
|
}
|
package/dist/fleet.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { type CuaDriverLike } from './index.js';
|
|
2
|
-
/** Structural subset of Fleet's generated Sandbox record. */
|
|
3
|
-
export interface FleetDriverSandbox {
|
|
4
|
-
namespace: string;
|
|
5
|
-
claim: string;
|
|
6
|
-
name: string;
|
|
7
|
-
services: string[];
|
|
8
|
-
}
|
|
9
|
-
/** Compatible with the generated Fleet client; no shared native pointers. */
|
|
10
|
-
export interface FleetDriverClient {
|
|
11
|
-
serviceRequest(sandbox: FleetDriverSandbox, service: string, path: string, request: {
|
|
12
|
-
method: string;
|
|
13
|
-
url: string;
|
|
14
|
-
headers: {
|
|
15
|
-
name: string;
|
|
16
|
-
value: string;
|
|
17
|
-
}[];
|
|
18
|
-
body?: ArrayBuffer;
|
|
19
|
-
timeoutSecs?: bigint;
|
|
20
|
-
maxResponseBytes?: bigint;
|
|
21
|
-
}, options?: {
|
|
22
|
-
signal: AbortSignal;
|
|
23
|
-
}): Promise<{
|
|
24
|
-
status: number;
|
|
25
|
-
headers: {
|
|
26
|
-
name: string;
|
|
27
|
-
value: string;
|
|
28
|
-
}[];
|
|
29
|
-
body: ArrayBuffer;
|
|
30
|
-
}>;
|
|
31
|
-
}
|
|
32
|
-
export interface FleetDriverConnection {
|
|
33
|
-
readonly driver: CuaDriverLike;
|
|
34
|
-
readonly sessionName: string;
|
|
35
|
-
/** Close before releasing the Fleet claim. This never releases the claim. */
|
|
36
|
-
close(): Promise<void>;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Connect to an advertised service on the caller's live Fleet claim.
|
|
40
|
-
* The caller owns the client and claim, and must await close before releasing
|
|
41
|
-
* either. Abort closes this connection; it does not undo desktop actions.
|
|
42
|
-
*/
|
|
43
|
-
export declare function connectFleetDriver({ client, sandbox, service, signal, }: {
|
|
44
|
-
client: FleetDriverClient;
|
|
45
|
-
sandbox: FleetDriverSandbox;
|
|
46
|
-
service?: string;
|
|
47
|
-
signal?: AbortSignal;
|
|
48
|
-
}): Promise<FleetDriverConnection>;
|
package/dist/fleet.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/** Node-only composition of an existing Fleet client and the shared Rust Driver. */
|
|
2
|
-
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { openMcpDriverChannel, DriverServiceTransportError, } from './index.js';
|
|
4
|
-
const FLEET_DRIVER_MAX_RESPONSE_BYTES = 16n * 1024n * 1024n;
|
|
5
|
-
/**
|
|
6
|
-
* Connect to an advertised service on the caller's live Fleet claim.
|
|
7
|
-
* The caller owns the client and claim, and must await close before releasing
|
|
8
|
-
* either. Abort closes this connection; it does not undo desktop actions.
|
|
9
|
-
*/
|
|
10
|
-
export async function connectFleetDriver({ client, sandbox, service = 'mcp', signal, }) {
|
|
11
|
-
const target = {
|
|
12
|
-
namespace: sandbox.namespace,
|
|
13
|
-
claim: sandbox.claim,
|
|
14
|
-
name: sandbox.name,
|
|
15
|
-
services: [...sandbox.services],
|
|
16
|
-
};
|
|
17
|
-
if (!target.services.includes(service)) {
|
|
18
|
-
throw new Error('Fleet sandbox does not advertise the requested Driver service');
|
|
19
|
-
}
|
|
20
|
-
if (signal?.aborted)
|
|
21
|
-
throw new Error('Fleet Driver connection aborted');
|
|
22
|
-
const serviceRequest = client.serviceRequest.bind(client);
|
|
23
|
-
let closing;
|
|
24
|
-
async function send(request) {
|
|
25
|
-
// Keep routing authority in Fleet even if the native boundary changes.
|
|
26
|
-
if (!request.path.startsWith('/') ||
|
|
27
|
-
request.path.length > 2048 ||
|
|
28
|
-
request.path.startsWith('//') ||
|
|
29
|
-
/[\\?#\s%]/u.test(request.path) ||
|
|
30
|
-
request.path.split('/').some((part) => part === '.' || part === '..') ||
|
|
31
|
-
request.timeoutMs <= 0n ||
|
|
32
|
-
request.timeoutMs > 2147483647n) {
|
|
33
|
-
throw new DriverServiceTransportError.Failed({
|
|
34
|
-
reason: 'Invalid bounded Driver service request',
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
const controller = new AbortController();
|
|
38
|
-
const timeout = setTimeout(() => controller.abort(), Number(request.timeoutMs));
|
|
39
|
-
let onAbort = () => { };
|
|
40
|
-
const aborted = new Promise((_, reject) => {
|
|
41
|
-
onAbort = () => reject(new Error('Fleet Driver service request canceled'));
|
|
42
|
-
controller.signal.addEventListener('abort', onAbort, { once: true });
|
|
43
|
-
});
|
|
44
|
-
try {
|
|
45
|
-
const response = await Promise.race([
|
|
46
|
-
serviceRequest({ ...target, services: [...target.services] }, service, request.path, {
|
|
47
|
-
method: request.method,
|
|
48
|
-
url: `https://service.invalid${request.path}`,
|
|
49
|
-
headers: request.headers.map((header) => ({ ...header })),
|
|
50
|
-
body: request.body,
|
|
51
|
-
timeoutSecs: (request.timeoutMs + 999n) / 1000n,
|
|
52
|
-
maxResponseBytes: FLEET_DRIVER_MAX_RESPONSE_BYTES,
|
|
53
|
-
}, { signal: controller.signal }),
|
|
54
|
-
aborted,
|
|
55
|
-
]);
|
|
56
|
-
if (BigInt(response.body.byteLength) > FLEET_DRIVER_MAX_RESPONSE_BYTES) {
|
|
57
|
-
throw new Error('Fleet Driver response exceeds the configured size limit');
|
|
58
|
-
}
|
|
59
|
-
return response;
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
// Native callback errors must not expose Fleet credentials or response bodies.
|
|
63
|
-
throw new DriverServiceTransportError.Failed({
|
|
64
|
-
reason: 'Fleet Driver service request failed',
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
finally {
|
|
68
|
-
clearTimeout(timeout);
|
|
69
|
-
controller.signal.removeEventListener('abort', onAbort);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const channel = openMcpDriverChannel({ send }, `fleet:${randomUUID()}`);
|
|
73
|
-
const close = () => {
|
|
74
|
-
if (!closing) {
|
|
75
|
-
signal?.removeEventListener('abort', onAbort);
|
|
76
|
-
// Retain the promise so cancellation cannot orphan cleanup or hide errors
|
|
77
|
-
// from a later explicit close. Rust bounds its own session teardown.
|
|
78
|
-
closing = channel.close();
|
|
79
|
-
}
|
|
80
|
-
return closing;
|
|
81
|
-
};
|
|
82
|
-
const onAbort = () => {
|
|
83
|
-
void close().catch(() => { });
|
|
84
|
-
};
|
|
85
|
-
signal?.addEventListener('abort', onAbort, { once: true });
|
|
86
|
-
try {
|
|
87
|
-
if (signal?.aborted)
|
|
88
|
-
throw new Error('Fleet Driver connection aborted');
|
|
89
|
-
await channel.open();
|
|
90
|
-
if (signal?.aborted || closing)
|
|
91
|
-
throw new Error('Fleet Driver connection aborted');
|
|
92
|
-
return Object.freeze({ driver: channel.driver(), sessionName: channel.publicSession(), close });
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
await close();
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
}
|