@stelis/agent-q-core 0.0.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 +144 -0
- package/dist/adapter-internal.d.ts +5 -0
- package/dist/adapter-internal.js +6 -0
- package/dist/adapter-internal.js.map +1 -0
- package/dist/config.d.ts +74 -0
- package/dist/config.js +489 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +320 -0
- package/dist/core.js +840 -0
- package/dist/core.js.map +1 -0
- package/dist/device.d.ts +55 -0
- package/dist/device.js +23 -0
- package/dist/device.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/host-output-schema.d.ts +2437 -0
- package/dist/host-output-schema.js +655 -0
- package/dist/host-output-schema.js.map +1 -0
- package/dist/protocol-error.d.ts +4 -0
- package/dist/protocol-error.js +9 -0
- package/dist/protocol-error.js.map +1 -0
- package/dist/protocol-management-primitives.d.ts +27 -0
- package/dist/protocol-management-primitives.js +51 -0
- package/dist/protocol-management-primitives.js.map +1 -0
- package/dist/protocol-primitives.d.ts +53 -0
- package/dist/protocol-primitives.js +331 -0
- package/dist/protocol-primitives.js.map +1 -0
- package/dist/protocol.d.ts +207 -0
- package/dist/protocol.js +897 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider-protocol.d.ts +262 -0
- package/dist/provider-protocol.js +637 -0
- package/dist/provider-protocol.js.map +1 -0
- package/dist/public-error.d.ts +9 -0
- package/dist/public-error.js +79 -0
- package/dist/public-error.js.map +1 -0
- package/dist/safe-text.d.ts +31 -0
- package/dist/safe-text.js +143 -0
- package/dist/safe-text.js.map +1 -0
- package/dist/transport-invariants.d.ts +18 -0
- package/dist/transport-invariants.js +24 -0
- package/dist/transport-invariants.js.map +1 -0
- package/dist/usb.d.ts +76 -0
- package/dist/usb.js +454 -0
- package/dist/usb.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,655 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
import { DISCONNECT_ENDED_REASONS, DISCONNECT_REASONS, GET_ACCOUNTS_SESSION_ENDED_REASONS, GET_APPROVAL_HISTORY_SESSION_ENDED_REASONS, GET_CAPABILITIES_SESSION_ENDED_REASONS, POLICY_PROPOSE_SESSION_ENDED_REASONS, POLICY_GET_SESSION_ENDED_REASONS, SIGN_PERSONAL_MESSAGE_SESSION_ENDED_REASONS, SIGN_TRANSACTION_SESSION_ENDED_REASONS, } from "./core.js";
|
|
4
|
+
import { PUBLIC_ERROR_MESSAGES } from "./public-error.js";
|
|
5
|
+
import { ED25519_PUBLIC_KEY_BASE64_PATTERN, APPROVAL_HISTORY_HIGHEST_ACTIONS, APPROVAL_HISTORY_POLICY_UPDATE_RESULTS, APPROVAL_HISTORY_REASON_CODE_PATTERN, APPROVAL_HISTORY_RULE_REF_PATTERN, MAX_ACCOUNTS_PER_RESPONSE, MAX_APPROVAL_HISTORY_RECORDS, MAX_CAPABILITY_ACCOUNTS_PER_CHAIN, MAX_CAPABILITY_CHAINS, MAX_SIGN_RESULT_PAYLOAD_BASE64_CHARS, MAX_POLICY_RULE_COUNT, POLICY_ID_PATTERN, POLICY_PROPOSE_RESULT_STATUSES, SIGN_CHAIN_PATTERN, SIGN_METHOD_PATTERN, SIGNING_HISTORY_TERMINAL_RESULTS, SIGN_RESULT_ERROR_MESSAGES, SUI_ADDRESS_PATTERN, SUI_DERIVATION_PATH, SUI_ED25519_SIGNATURE_BASE64_PATTERN, SUI_SIGN_PERSONAL_MESSAGE_METHOD, SUI_SIGN_TRANSACTION_METHOD, UINT_DECIMAL_STRING_PATTERN, isUint64DecimalString, isSuiAddressForPublicKey, sanitizeCurrentPolicyDocument, } from "./protocol.js";
|
|
6
|
+
import { DEVICE_ID_PATTERN, DEVICE_STATES, IDENTIFICATION_CODE_PATTERN, ISO_TIMESTAMP_PATTERN, MAX_FIRMWARE_NAME_LENGTH, MAX_FIRMWARE_VERSION_LENGTH, MAX_HARDWARE_ID_LENGTH, MAX_LABEL_LENGTH, MAX_PORT_HINT_LENGTH, PRINTABLE_ASCII_ONLY, PURPOSE_PATTERN, PROVISIONING_STATES, REQUEST_ID_PATTERN, isValidLabel, isValidPurpose, } from "./safe-text.js";
|
|
7
|
+
// Mirrors public-error.ts exactly: the code must be an allowlisted public code
|
|
8
|
+
// and the message must be that code's canonical string. This keeps Agent-Q
|
|
9
|
+
// egress schemas in lockstep with the runtime.
|
|
10
|
+
export const publicErrorShape = z
|
|
11
|
+
.object({
|
|
12
|
+
code: z.string(),
|
|
13
|
+
message: z.string(),
|
|
14
|
+
retryable: z.boolean(),
|
|
15
|
+
})
|
|
16
|
+
.strict()
|
|
17
|
+
.refine((value) => PUBLIC_ERROR_MESSAGES[value.code] === value.message, {
|
|
18
|
+
message: "error must be a canonical public error (allowlisted code with its matching message)",
|
|
19
|
+
});
|
|
20
|
+
export const safeDeviceIdShape = z.string().regex(DEVICE_ID_PATTERN);
|
|
21
|
+
export const requestIdShape = z.string().regex(REQUEST_ID_PATTERN);
|
|
22
|
+
export const identificationCodeShape = z.string().regex(IDENTIFICATION_CODE_PATTERN);
|
|
23
|
+
export const displayTextShape = (maxLength) => z.string().regex(PRINTABLE_ASCII_ONLY).max(maxLength);
|
|
24
|
+
export const portHintShape = displayTextShape(MAX_PORT_HINT_LENGTH);
|
|
25
|
+
export const isoInstantShape = z
|
|
26
|
+
.string()
|
|
27
|
+
.regex(ISO_TIMESTAMP_PATTERN)
|
|
28
|
+
.refine((value) => Number.isFinite(Date.parse(value)));
|
|
29
|
+
export const safePurposeShape = z.string().regex(PURPOSE_PATTERN).refine((value) => isValidPurpose(value));
|
|
30
|
+
export const safeLabelShape = z.string().min(1).max(MAX_LABEL_LENGTH).refine((value) => isValidLabel(value));
|
|
31
|
+
export const deviceShape = z.object({
|
|
32
|
+
deviceId: safeDeviceIdShape,
|
|
33
|
+
state: z.enum(DEVICE_STATES),
|
|
34
|
+
firmwareName: displayTextShape(MAX_FIRMWARE_NAME_LENGTH),
|
|
35
|
+
hardware: displayTextShape(MAX_HARDWARE_ID_LENGTH),
|
|
36
|
+
firmwareVersion: displayTextShape(MAX_FIRMWARE_VERSION_LENGTH),
|
|
37
|
+
}).strict();
|
|
38
|
+
export const provisioningShape = z.object({
|
|
39
|
+
state: z.enum(PROVISIONING_STATES),
|
|
40
|
+
}).strict();
|
|
41
|
+
export const deviceStatusSnapshotShape = z.object({
|
|
42
|
+
device: deviceShape,
|
|
43
|
+
provisioning: provisioningShape,
|
|
44
|
+
}).strict();
|
|
45
|
+
export const statusResponseShape = z.object({
|
|
46
|
+
id: requestIdShape,
|
|
47
|
+
version: z.literal(1),
|
|
48
|
+
type: z.literal("status"),
|
|
49
|
+
device: deviceShape,
|
|
50
|
+
provisioning: provisioningShape,
|
|
51
|
+
}).strict();
|
|
52
|
+
export const identifyResponseShape = z.object({
|
|
53
|
+
id: requestIdShape,
|
|
54
|
+
version: z.literal(1),
|
|
55
|
+
type: z.literal("identify_device_result"),
|
|
56
|
+
status: z.literal("displayed"),
|
|
57
|
+
code: identificationCodeShape,
|
|
58
|
+
device: deviceShape,
|
|
59
|
+
}).strict();
|
|
60
|
+
export const liveStatusShape = z.object({
|
|
61
|
+
source: z.literal("live"),
|
|
62
|
+
connected: z.literal(true),
|
|
63
|
+
portPath: portHintShape,
|
|
64
|
+
protocolResponse: statusResponseShape,
|
|
65
|
+
}).strict();
|
|
66
|
+
export const identifiedDeviceShape = z.object({
|
|
67
|
+
source: z.literal("live"),
|
|
68
|
+
connected: z.literal(true),
|
|
69
|
+
portPath: portHintShape,
|
|
70
|
+
status: z.literal("displayed"),
|
|
71
|
+
code: identificationCodeShape,
|
|
72
|
+
protocolResponse: identifyResponseShape,
|
|
73
|
+
}).strict();
|
|
74
|
+
export const failedIdentificationShape = z.object({
|
|
75
|
+
source: z.literal("error"),
|
|
76
|
+
connected: z.literal(false),
|
|
77
|
+
portPath: portHintShape,
|
|
78
|
+
deviceId: safeDeviceIdShape,
|
|
79
|
+
status: z.literal("error"),
|
|
80
|
+
error: publicErrorShape,
|
|
81
|
+
}).strict();
|
|
82
|
+
export const errorToolResultShape = z.object({
|
|
83
|
+
source: z.literal("error"),
|
|
84
|
+
connected: z.literal(false),
|
|
85
|
+
error: publicErrorShape,
|
|
86
|
+
}).strict();
|
|
87
|
+
export const runtimeSessionShape = z.object({
|
|
88
|
+
sessionTtlMs: z.number().int().positive(),
|
|
89
|
+
connectedAt: isoInstantShape,
|
|
90
|
+
}).strict();
|
|
91
|
+
export const deviceListEntryShape = z.object({
|
|
92
|
+
deviceId: safeDeviceIdShape,
|
|
93
|
+
transport: z.literal("usb"),
|
|
94
|
+
lastPortHint: portHintShape,
|
|
95
|
+
lastSeenAt: isoInstantShape,
|
|
96
|
+
label: safeLabelShape.nullable(),
|
|
97
|
+
lastStatus: deviceStatusSnapshotShape,
|
|
98
|
+
assignedPurposes: z.array(safePurposeShape),
|
|
99
|
+
isDefaultActive: z.boolean(),
|
|
100
|
+
runtimeSession: runtimeSessionShape.nullable(),
|
|
101
|
+
}).strict();
|
|
102
|
+
const unavailableReasonShape = z.enum([
|
|
103
|
+
"timeout",
|
|
104
|
+
"port_not_found",
|
|
105
|
+
"port_in_use",
|
|
106
|
+
"port_permission_denied",
|
|
107
|
+
"handshake_failed",
|
|
108
|
+
"incompatible_version",
|
|
109
|
+
"transport_closed",
|
|
110
|
+
]);
|
|
111
|
+
const scanDeviceFailureShape = z.object({
|
|
112
|
+
source: z.literal("error"),
|
|
113
|
+
connected: z.literal(false),
|
|
114
|
+
portPath: portHintShape,
|
|
115
|
+
unavailableReason: unavailableReasonShape,
|
|
116
|
+
firmwareErrorCode: z
|
|
117
|
+
.string()
|
|
118
|
+
.refine((code) => Object.prototype.hasOwnProperty.call(PUBLIC_ERROR_MESSAGES, code))
|
|
119
|
+
.optional(),
|
|
120
|
+
}).strict();
|
|
121
|
+
export const scanDevicesSuccessOutputShape = z.object({
|
|
122
|
+
source: z.literal("live"),
|
|
123
|
+
devices: z.array(liveStatusShape),
|
|
124
|
+
failures: z.array(scanDeviceFailureShape),
|
|
125
|
+
activeDeviceId: safeDeviceIdShape.nullable(),
|
|
126
|
+
}).strict();
|
|
127
|
+
export const scanDevicesToolOutputShape = z.discriminatedUnion("source", [
|
|
128
|
+
scanDevicesSuccessOutputShape,
|
|
129
|
+
errorToolResultShape,
|
|
130
|
+
]);
|
|
131
|
+
export const identifyDevicesSuccessOutputShape = z.object({
|
|
132
|
+
source: z.literal("live"),
|
|
133
|
+
devices: z.array(z.discriminatedUnion("source", [identifiedDeviceShape, failedIdentificationShape])),
|
|
134
|
+
activeDeviceId: safeDeviceIdShape.nullable(),
|
|
135
|
+
}).strict();
|
|
136
|
+
export const identifyDevicesToolOutputShape = z.discriminatedUnion("source", [
|
|
137
|
+
identifyDevicesSuccessOutputShape,
|
|
138
|
+
errorToolResultShape,
|
|
139
|
+
]);
|
|
140
|
+
export const selectDeviceSuccessOutputShape = z.object({
|
|
141
|
+
source: z.literal("selected"),
|
|
142
|
+
activeDeviceId: safeDeviceIdShape,
|
|
143
|
+
purpose: safePurposeShape.nullable(),
|
|
144
|
+
device: deviceShape,
|
|
145
|
+
}).strict();
|
|
146
|
+
export const selectDeviceToolOutputShape = z.discriminatedUnion("source", [
|
|
147
|
+
selectDeviceSuccessOutputShape,
|
|
148
|
+
errorToolResultShape,
|
|
149
|
+
]);
|
|
150
|
+
export const listDevicesSuccessOutputShape = z.object({
|
|
151
|
+
source: z.literal("list"),
|
|
152
|
+
devices: z.array(deviceListEntryShape),
|
|
153
|
+
activeDeviceId: safeDeviceIdShape.nullable(),
|
|
154
|
+
activeDeviceIdsByPurpose: z.record(safePurposeShape, safeDeviceIdShape),
|
|
155
|
+
}).strict();
|
|
156
|
+
export const listDevicesToolOutputShape = z.discriminatedUnion("source", [
|
|
157
|
+
listDevicesSuccessOutputShape,
|
|
158
|
+
errorToolResultShape,
|
|
159
|
+
]);
|
|
160
|
+
export const setDeviceMetadataSuccessOutputShape = z.object({
|
|
161
|
+
source: z.literal("metadata"),
|
|
162
|
+
deviceId: safeDeviceIdShape,
|
|
163
|
+
label: safeLabelShape.nullable(),
|
|
164
|
+
}).strict();
|
|
165
|
+
export const setDeviceMetadataToolOutputShape = z.discriminatedUnion("source", [
|
|
166
|
+
setDeviceMetadataSuccessOutputShape,
|
|
167
|
+
errorToolResultShape,
|
|
168
|
+
]);
|
|
169
|
+
export const connectDeviceSuccessOutputShape = z.object({
|
|
170
|
+
source: z.literal("connected"),
|
|
171
|
+
deviceId: safeDeviceIdShape,
|
|
172
|
+
sessionTtlMs: z.number().int().positive(),
|
|
173
|
+
connectedAt: isoInstantShape,
|
|
174
|
+
device: deviceShape,
|
|
175
|
+
}).strict();
|
|
176
|
+
export const connectDeviceToolOutputShape = z.discriminatedUnion("source", [
|
|
177
|
+
connectDeviceSuccessOutputShape,
|
|
178
|
+
errorToolResultShape,
|
|
179
|
+
]);
|
|
180
|
+
export const disconnectDeviceSuccessOutputShape = z
|
|
181
|
+
.object({
|
|
182
|
+
source: z.enum(["disconnected", "not_connected"]),
|
|
183
|
+
deviceId: safeDeviceIdShape,
|
|
184
|
+
reason: z.enum(DISCONNECT_REASONS),
|
|
185
|
+
})
|
|
186
|
+
.strict()
|
|
187
|
+
.refine((result) => (result.source === "not_connected" && result.reason === "not_connected") ||
|
|
188
|
+
(result.source === "disconnected" &&
|
|
189
|
+
DISCONNECT_ENDED_REASONS.includes(result.reason)), { message: "disconnect source and reason disagree" });
|
|
190
|
+
export const disconnectDeviceToolOutputShape = z.discriminatedUnion("source", [
|
|
191
|
+
disconnectDeviceSuccessOutputShape,
|
|
192
|
+
errorToolResultShape,
|
|
193
|
+
]);
|
|
194
|
+
const capabilityAccountShape = z.object({
|
|
195
|
+
keyScheme: z.literal("ed25519"),
|
|
196
|
+
derivationPath: z.literal(SUI_DERIVATION_PATH),
|
|
197
|
+
}).strict();
|
|
198
|
+
const capabilityChainShape = z.object({
|
|
199
|
+
id: z.literal("sui"),
|
|
200
|
+
accounts: z.array(capabilityAccountShape).length(MAX_CAPABILITY_ACCOUNTS_PER_CHAIN),
|
|
201
|
+
methods: z.array(z.never()).length(0),
|
|
202
|
+
}).strict();
|
|
203
|
+
const signingCapabilityEntryShape = z.object({
|
|
204
|
+
chain: z.literal("sui"),
|
|
205
|
+
method: z.enum([SUI_SIGN_TRANSACTION_METHOD, SUI_SIGN_PERSONAL_MESSAGE_METHOD]),
|
|
206
|
+
}).strict();
|
|
207
|
+
const signingCapabilitiesShape = z
|
|
208
|
+
.object({
|
|
209
|
+
authorization: z.enum(["user", "policy"]),
|
|
210
|
+
methods: z.array(signingCapabilityEntryShape).min(1).max(2),
|
|
211
|
+
})
|
|
212
|
+
.strict()
|
|
213
|
+
.refine((value) => {
|
|
214
|
+
const methods = new Set(value.methods.map((entry) => entry.method));
|
|
215
|
+
if (methods.size !== value.methods.length) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
if (value.authorization === "policy") {
|
|
219
|
+
return methods.size === 1 && methods.has(SUI_SIGN_TRANSACTION_METHOD);
|
|
220
|
+
}
|
|
221
|
+
return (methods.size === 2 &&
|
|
222
|
+
methods.has(SUI_SIGN_TRANSACTION_METHOD) &&
|
|
223
|
+
methods.has(SUI_SIGN_PERSONAL_MESSAGE_METHOD));
|
|
224
|
+
}, { message: "signing methods must match authorization mode" });
|
|
225
|
+
const liveCapabilitiesOutputShape = z.object({
|
|
226
|
+
source: z.literal("live"),
|
|
227
|
+
deviceId: safeDeviceIdShape,
|
|
228
|
+
capabilities: z.array(capabilityChainShape).length(MAX_CAPABILITY_CHAINS),
|
|
229
|
+
signing: signingCapabilitiesShape.optional(),
|
|
230
|
+
}).strict();
|
|
231
|
+
const liveProviderCapabilitiesOutputShape = z.object({
|
|
232
|
+
source: z.literal("live"),
|
|
233
|
+
deviceId: safeDeviceIdShape,
|
|
234
|
+
capabilities: z.array(capabilityChainShape).length(MAX_CAPABILITY_CHAINS),
|
|
235
|
+
signing: signingCapabilitiesShape.optional(),
|
|
236
|
+
}).strict();
|
|
237
|
+
const liveMcpCapabilitiesOutputShape = z.object({
|
|
238
|
+
source: z.literal("live"),
|
|
239
|
+
deviceId: safeDeviceIdShape,
|
|
240
|
+
capabilities: z.array(capabilityChainShape).length(MAX_CAPABILITY_CHAINS),
|
|
241
|
+
signing: signingCapabilitiesShape.optional(),
|
|
242
|
+
}).strict();
|
|
243
|
+
const notConnectedCapabilitiesOutputShape = z.object({
|
|
244
|
+
source: z.literal("not_connected"),
|
|
245
|
+
deviceId: safeDeviceIdShape,
|
|
246
|
+
reason: z.literal("not_connected"),
|
|
247
|
+
}).strict();
|
|
248
|
+
const sessionEndedCapabilitiesOutputShape = z.object({
|
|
249
|
+
source: z.literal("session_ended"),
|
|
250
|
+
deviceId: safeDeviceIdShape,
|
|
251
|
+
reason: z.enum(GET_CAPABILITIES_SESSION_ENDED_REASONS),
|
|
252
|
+
}).strict();
|
|
253
|
+
export const getCapabilitiesSuccessOutputShape = z.discriminatedUnion("source", [
|
|
254
|
+
liveCapabilitiesOutputShape,
|
|
255
|
+
notConnectedCapabilitiesOutputShape,
|
|
256
|
+
sessionEndedCapabilitiesOutputShape,
|
|
257
|
+
]);
|
|
258
|
+
export const getCapabilitiesToolOutputShape = z.discriminatedUnion("source", [
|
|
259
|
+
liveCapabilitiesOutputShape,
|
|
260
|
+
notConnectedCapabilitiesOutputShape,
|
|
261
|
+
sessionEndedCapabilitiesOutputShape,
|
|
262
|
+
errorToolResultShape,
|
|
263
|
+
]);
|
|
264
|
+
export const providerGetCapabilitiesSuccessOutputShape = z.discriminatedUnion("source", [
|
|
265
|
+
liveProviderCapabilitiesOutputShape,
|
|
266
|
+
notConnectedCapabilitiesOutputShape,
|
|
267
|
+
sessionEndedCapabilitiesOutputShape,
|
|
268
|
+
]);
|
|
269
|
+
export const providerGetCapabilitiesToolOutputShape = z.discriminatedUnion("source", [
|
|
270
|
+
liveProviderCapabilitiesOutputShape,
|
|
271
|
+
notConnectedCapabilitiesOutputShape,
|
|
272
|
+
sessionEndedCapabilitiesOutputShape,
|
|
273
|
+
errorToolResultShape,
|
|
274
|
+
]);
|
|
275
|
+
export const mcpGetCapabilitiesSuccessOutputShape = z.discriminatedUnion("source", [
|
|
276
|
+
liveMcpCapabilitiesOutputShape,
|
|
277
|
+
notConnectedCapabilitiesOutputShape,
|
|
278
|
+
sessionEndedCapabilitiesOutputShape,
|
|
279
|
+
]);
|
|
280
|
+
export const mcpGetCapabilitiesToolOutputShape = z.discriminatedUnion("source", [
|
|
281
|
+
liveMcpCapabilitiesOutputShape,
|
|
282
|
+
notConnectedCapabilitiesOutputShape,
|
|
283
|
+
sessionEndedCapabilitiesOutputShape,
|
|
284
|
+
errorToolResultShape,
|
|
285
|
+
]);
|
|
286
|
+
const accountShape = z.object({
|
|
287
|
+
chain: z.literal("sui"),
|
|
288
|
+
address: z.string().regex(SUI_ADDRESS_PATTERN),
|
|
289
|
+
publicKey: z.string().regex(ED25519_PUBLIC_KEY_BASE64_PATTERN),
|
|
290
|
+
keyScheme: z.literal("ed25519"),
|
|
291
|
+
derivationPath: z.literal(SUI_DERIVATION_PATH),
|
|
292
|
+
}).strict().refine((account) => isSuiAddressForPublicKey(account.address, account.publicKey), {
|
|
293
|
+
message: "Sui address must match publicKey",
|
|
294
|
+
});
|
|
295
|
+
const liveAccountsOutputShape = z.object({
|
|
296
|
+
source: z.literal("live"),
|
|
297
|
+
deviceId: safeDeviceIdShape,
|
|
298
|
+
accounts: z.array(accountShape).length(MAX_ACCOUNTS_PER_RESPONSE),
|
|
299
|
+
}).strict();
|
|
300
|
+
const notConnectedAccountsOutputShape = z.object({
|
|
301
|
+
source: z.literal("not_connected"),
|
|
302
|
+
deviceId: safeDeviceIdShape,
|
|
303
|
+
reason: z.literal("not_connected"),
|
|
304
|
+
}).strict();
|
|
305
|
+
const sessionEndedAccountsOutputShape = z.object({
|
|
306
|
+
source: z.literal("session_ended"),
|
|
307
|
+
deviceId: safeDeviceIdShape,
|
|
308
|
+
reason: z.enum(GET_ACCOUNTS_SESSION_ENDED_REASONS),
|
|
309
|
+
}).strict();
|
|
310
|
+
export const getAccountsSuccessOutputShape = z.discriminatedUnion("source", [
|
|
311
|
+
liveAccountsOutputShape,
|
|
312
|
+
notConnectedAccountsOutputShape,
|
|
313
|
+
sessionEndedAccountsOutputShape,
|
|
314
|
+
]);
|
|
315
|
+
export const getAccountsToolOutputShape = z.discriminatedUnion("source", [
|
|
316
|
+
liveAccountsOutputShape,
|
|
317
|
+
notConnectedAccountsOutputShape,
|
|
318
|
+
sessionEndedAccountsOutputShape,
|
|
319
|
+
errorToolResultShape,
|
|
320
|
+
]);
|
|
321
|
+
const policyDocumentShape = z.custom((value) => {
|
|
322
|
+
try {
|
|
323
|
+
return sanitizeCurrentPolicyDocument(value) !== null;
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
}, {
|
|
329
|
+
message: "policy must match the current active policy document schema",
|
|
330
|
+
});
|
|
331
|
+
const livePolicyOutputShape = z.object({
|
|
332
|
+
source: z.literal("live"),
|
|
333
|
+
deviceId: safeDeviceIdShape,
|
|
334
|
+
policy: policyDocumentShape,
|
|
335
|
+
}).strict();
|
|
336
|
+
const notConnectedPolicyOutputShape = z.object({
|
|
337
|
+
source: z.literal("not_connected"),
|
|
338
|
+
deviceId: safeDeviceIdShape,
|
|
339
|
+
reason: z.literal("not_connected"),
|
|
340
|
+
}).strict();
|
|
341
|
+
const sessionEndedPolicyOutputShape = z.object({
|
|
342
|
+
source: z.literal("session_ended"),
|
|
343
|
+
deviceId: safeDeviceIdShape,
|
|
344
|
+
reason: z.enum(POLICY_GET_SESSION_ENDED_REASONS),
|
|
345
|
+
}).strict();
|
|
346
|
+
export const policyGetSuccessOutputShape = z.discriminatedUnion("source", [
|
|
347
|
+
livePolicyOutputShape,
|
|
348
|
+
notConnectedPolicyOutputShape,
|
|
349
|
+
sessionEndedPolicyOutputShape,
|
|
350
|
+
]);
|
|
351
|
+
export const policyGetToolOutputShape = z.discriminatedUnion("source", [
|
|
352
|
+
livePolicyOutputShape,
|
|
353
|
+
notConnectedPolicyOutputShape,
|
|
354
|
+
sessionEndedPolicyOutputShape,
|
|
355
|
+
errorToolResultShape,
|
|
356
|
+
]);
|
|
357
|
+
const approvalHistoryRecordShape = z.object({
|
|
358
|
+
seq: z.string().regex(UINT_DECIMAL_STRING_PATTERN).refine((value) => isUint64DecimalString(value)),
|
|
359
|
+
uptimeMs: z.string().regex(UINT_DECIMAL_STRING_PATTERN).refine((value) => isUint64DecimalString(value)),
|
|
360
|
+
timeSource: z.literal("uptime"),
|
|
361
|
+
reasonCode: z.string().regex(APPROVAL_HISTORY_REASON_CODE_PATTERN),
|
|
362
|
+
}).strict();
|
|
363
|
+
const policyUpdateApprovalHistoryRecordShape = approvalHistoryRecordShape.extend({
|
|
364
|
+
eventKind: z.literal("policy_update"),
|
|
365
|
+
result: z.enum(APPROVAL_HISTORY_POLICY_UPDATE_RESULTS),
|
|
366
|
+
policyHash: z.string().regex(POLICY_ID_PATTERN),
|
|
367
|
+
ruleCount: z.number().int().min(0).max(MAX_POLICY_RULE_COUNT),
|
|
368
|
+
highestAction: z.enum(APPROVAL_HISTORY_HIGHEST_ACTIONS),
|
|
369
|
+
}).strict();
|
|
370
|
+
const signingUserConfirmationApprovalHistoryRecordShape = approvalHistoryRecordShape.extend({
|
|
371
|
+
eventKind: z.literal("signing"),
|
|
372
|
+
recordKind: z.literal("confirmation"),
|
|
373
|
+
authorization: z.literal("user"),
|
|
374
|
+
confirmationKind: z.enum(["local_pin", "physical_confirm"]),
|
|
375
|
+
chain: z.string().regex(SIGN_CHAIN_PATTERN),
|
|
376
|
+
method: z.string().regex(SIGN_METHOD_PATTERN),
|
|
377
|
+
payloadDigest: z.string().regex(POLICY_ID_PATTERN),
|
|
378
|
+
}).strict();
|
|
379
|
+
const signingPolicyConfirmationApprovalHistoryRecordShape = approvalHistoryRecordShape.extend({
|
|
380
|
+
eventKind: z.literal("signing"),
|
|
381
|
+
recordKind: z.literal("confirmation"),
|
|
382
|
+
authorization: z.literal("policy"),
|
|
383
|
+
confirmationKind: z.literal("policy"),
|
|
384
|
+
chain: z.string().regex(SIGN_CHAIN_PATTERN),
|
|
385
|
+
method: z.string().regex(SIGN_METHOD_PATTERN),
|
|
386
|
+
payloadDigest: z.string().regex(POLICY_ID_PATTERN),
|
|
387
|
+
policyHash: z.string().regex(POLICY_ID_PATTERN),
|
|
388
|
+
ruleRef: z.string().regex(APPROVAL_HISTORY_RULE_REF_PATTERN),
|
|
389
|
+
}).strict();
|
|
390
|
+
const signingTerminalApprovalHistoryRecordShape = approvalHistoryRecordShape.extend({
|
|
391
|
+
eventKind: z.literal("signing"),
|
|
392
|
+
recordKind: z.literal("terminal"),
|
|
393
|
+
authorization: z.enum(["user", "policy"]),
|
|
394
|
+
terminalResult: z.enum(SIGNING_HISTORY_TERMINAL_RESULTS),
|
|
395
|
+
chain: z.string().regex(SIGN_CHAIN_PATTERN),
|
|
396
|
+
method: z.string().regex(SIGN_METHOD_PATTERN),
|
|
397
|
+
payloadDigest: z.string().regex(POLICY_ID_PATTERN),
|
|
398
|
+
policyHash: z.string().regex(POLICY_ID_PATTERN).optional(),
|
|
399
|
+
ruleRef: z.string().regex(APPROVAL_HISTORY_RULE_REF_PATTERN).optional(),
|
|
400
|
+
}).strict().refine((value) => {
|
|
401
|
+
const hasPolicyMetadata = value.policyHash !== undefined && value.ruleRef !== undefined;
|
|
402
|
+
if (value.authorization === "policy") {
|
|
403
|
+
return (hasPolicyMetadata &&
|
|
404
|
+
["signed", "policy_rejected", "signing_failed"].includes(value.terminalResult));
|
|
405
|
+
}
|
|
406
|
+
return (value.policyHash === undefined &&
|
|
407
|
+
value.ruleRef === undefined &&
|
|
408
|
+
["signed", "user_rejected", "user_timed_out", "signing_failed"].includes(value.terminalResult));
|
|
409
|
+
}, { message: "signing policy metadata must match authorization" });
|
|
410
|
+
const approvalHistoryRecordOutputShape = z.union([
|
|
411
|
+
policyUpdateApprovalHistoryRecordShape,
|
|
412
|
+
signingUserConfirmationApprovalHistoryRecordShape,
|
|
413
|
+
signingPolicyConfirmationApprovalHistoryRecordShape,
|
|
414
|
+
signingTerminalApprovalHistoryRecordShape,
|
|
415
|
+
]);
|
|
416
|
+
const liveApprovalHistoryOutputShape = z.object({
|
|
417
|
+
source: z.literal("live"),
|
|
418
|
+
deviceId: safeDeviceIdShape,
|
|
419
|
+
records: z.array(approvalHistoryRecordOutputShape).max(MAX_APPROVAL_HISTORY_RECORDS),
|
|
420
|
+
hasMore: z.boolean(),
|
|
421
|
+
}).strict();
|
|
422
|
+
const notConnectedApprovalHistoryOutputShape = z.object({
|
|
423
|
+
source: z.literal("not_connected"),
|
|
424
|
+
deviceId: safeDeviceIdShape,
|
|
425
|
+
reason: z.literal("not_connected"),
|
|
426
|
+
}).strict();
|
|
427
|
+
const sessionEndedApprovalHistoryOutputShape = z.object({
|
|
428
|
+
source: z.literal("session_ended"),
|
|
429
|
+
deviceId: safeDeviceIdShape,
|
|
430
|
+
reason: z.enum(GET_APPROVAL_HISTORY_SESSION_ENDED_REASONS),
|
|
431
|
+
}).strict();
|
|
432
|
+
export const getApprovalHistorySuccessOutputShape = z.discriminatedUnion("source", [
|
|
433
|
+
liveApprovalHistoryOutputShape,
|
|
434
|
+
notConnectedApprovalHistoryOutputShape,
|
|
435
|
+
sessionEndedApprovalHistoryOutputShape,
|
|
436
|
+
]);
|
|
437
|
+
export const getApprovalHistoryToolOutputShape = z.discriminatedUnion("source", [
|
|
438
|
+
liveApprovalHistoryOutputShape,
|
|
439
|
+
notConnectedApprovalHistoryOutputShape,
|
|
440
|
+
sessionEndedApprovalHistoryOutputShape,
|
|
441
|
+
errorToolResultShape,
|
|
442
|
+
]);
|
|
443
|
+
const signResultErrorShape = z.object({
|
|
444
|
+
code: z.enum(Object.keys(SIGN_RESULT_ERROR_MESSAGES)),
|
|
445
|
+
message: z.enum(Object.values(SIGN_RESULT_ERROR_MESSAGES)),
|
|
446
|
+
}).strict().refine((error) => error.message === SIGN_RESULT_ERROR_MESSAGES[error.code], {
|
|
447
|
+
message: "Sign result error message must match its code.",
|
|
448
|
+
});
|
|
449
|
+
const canonicalBase64Shape = z
|
|
450
|
+
.string()
|
|
451
|
+
.regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/);
|
|
452
|
+
const personalMessageBytesShape = canonicalBase64Shape
|
|
453
|
+
.min(1)
|
|
454
|
+
.max(MAX_SIGN_RESULT_PAYLOAD_BASE64_CHARS)
|
|
455
|
+
.refine((value) => {
|
|
456
|
+
const decoded = Buffer.from(value, "base64");
|
|
457
|
+
return (decoded.length > 0 &&
|
|
458
|
+
decoded.toString("base64") === value);
|
|
459
|
+
}, {
|
|
460
|
+
message: "messageBytes must be canonical base64",
|
|
461
|
+
});
|
|
462
|
+
const liveUserSignSignedOutputShape = z.object({
|
|
463
|
+
source: z.literal("live"),
|
|
464
|
+
deviceId: safeDeviceIdShape,
|
|
465
|
+
status: z.literal("signed"),
|
|
466
|
+
authorization: z.literal("user"),
|
|
467
|
+
chain: z.literal("sui"),
|
|
468
|
+
method: z.literal(SUI_SIGN_TRANSACTION_METHOD),
|
|
469
|
+
signature: z.string().regex(SUI_ED25519_SIGNATURE_BASE64_PATTERN),
|
|
470
|
+
}).strict();
|
|
471
|
+
const livePolicySignSignedOutputShape = liveUserSignSignedOutputShape.extend({
|
|
472
|
+
authorization: z.literal("policy"),
|
|
473
|
+
}).strict();
|
|
474
|
+
const liveUserSignPersonalMessageSignedOutputShape = z.object({
|
|
475
|
+
source: z.literal("live"),
|
|
476
|
+
deviceId: safeDeviceIdShape,
|
|
477
|
+
status: z.literal("signed"),
|
|
478
|
+
authorization: z.literal("user"),
|
|
479
|
+
chain: z.literal("sui"),
|
|
480
|
+
method: z.literal(SUI_SIGN_PERSONAL_MESSAGE_METHOD),
|
|
481
|
+
signature: z.string().regex(SUI_ED25519_SIGNATURE_BASE64_PATTERN),
|
|
482
|
+
messageBytes: personalMessageBytesShape,
|
|
483
|
+
}).strict();
|
|
484
|
+
const liveUserSignTerminalOutputShape = z.discriminatedUnion("status", [
|
|
485
|
+
z.object({
|
|
486
|
+
source: z.literal("live"),
|
|
487
|
+
deviceId: safeDeviceIdShape,
|
|
488
|
+
status: z.literal("user_rejected"),
|
|
489
|
+
authorization: z.literal("user"),
|
|
490
|
+
error: signResultErrorShape.refine((error) => error.code === "user_rejected", {
|
|
491
|
+
message: "User-rejected sign result error code must be user_rejected.",
|
|
492
|
+
}),
|
|
493
|
+
}).strict(),
|
|
494
|
+
z.object({
|
|
495
|
+
source: z.literal("live"),
|
|
496
|
+
deviceId: safeDeviceIdShape,
|
|
497
|
+
status: z.literal("user_timed_out"),
|
|
498
|
+
authorization: z.literal("user"),
|
|
499
|
+
error: signResultErrorShape.refine((error) => error.code === "user_timed_out", {
|
|
500
|
+
message: "Timed-out sign result error code must be user_timed_out.",
|
|
501
|
+
}),
|
|
502
|
+
}).strict(),
|
|
503
|
+
z.object({
|
|
504
|
+
source: z.literal("live"),
|
|
505
|
+
deviceId: safeDeviceIdShape,
|
|
506
|
+
status: z.literal("signing_failed"),
|
|
507
|
+
authorization: z.literal("user"),
|
|
508
|
+
error: signResultErrorShape.refine((error) => error.code === "signing_failed", {
|
|
509
|
+
message: "Failed sign result error code must be signing_failed.",
|
|
510
|
+
}),
|
|
511
|
+
}).strict(),
|
|
512
|
+
]);
|
|
513
|
+
const livePolicySignTerminalOutputShape = z.discriminatedUnion("status", [
|
|
514
|
+
z.object({
|
|
515
|
+
source: z.literal("live"),
|
|
516
|
+
deviceId: safeDeviceIdShape,
|
|
517
|
+
status: z.literal("policy_rejected"),
|
|
518
|
+
authorization: z.literal("policy"),
|
|
519
|
+
policyHash: z.string().regex(POLICY_ID_PATTERN),
|
|
520
|
+
ruleRef: z.string().regex(APPROVAL_HISTORY_RULE_REF_PATTERN),
|
|
521
|
+
error: signResultErrorShape.refine((error) => error.code === "policy_rejected", {
|
|
522
|
+
message: "Policy-rejected sign result error code must be policy_rejected.",
|
|
523
|
+
}),
|
|
524
|
+
}).strict(),
|
|
525
|
+
z.object({
|
|
526
|
+
source: z.literal("live"),
|
|
527
|
+
deviceId: safeDeviceIdShape,
|
|
528
|
+
status: z.literal("signing_failed"),
|
|
529
|
+
authorization: z.literal("policy"),
|
|
530
|
+
error: signResultErrorShape.refine((error) => error.code === "signing_failed", {
|
|
531
|
+
message: "Failed sign result error code must be signing_failed.",
|
|
532
|
+
}),
|
|
533
|
+
}).strict(),
|
|
534
|
+
]);
|
|
535
|
+
const notConnectedSignOutputShape = z.object({
|
|
536
|
+
source: z.literal("not_connected"),
|
|
537
|
+
deviceId: safeDeviceIdShape,
|
|
538
|
+
reason: z.literal("not_connected"),
|
|
539
|
+
}).strict();
|
|
540
|
+
const sessionEndedSignTransactionOutputShape = z.object({
|
|
541
|
+
source: z.literal("session_ended"),
|
|
542
|
+
deviceId: safeDeviceIdShape,
|
|
543
|
+
reason: z.enum(SIGN_TRANSACTION_SESSION_ENDED_REASONS),
|
|
544
|
+
}).strict();
|
|
545
|
+
const sessionEndedSignPersonalMessageOutputShape = z.object({
|
|
546
|
+
source: z.literal("session_ended"),
|
|
547
|
+
deviceId: safeDeviceIdShape,
|
|
548
|
+
reason: z.enum(SIGN_PERSONAL_MESSAGE_SESSION_ENDED_REASONS),
|
|
549
|
+
}).strict();
|
|
550
|
+
export const signTransactionSuccessOutputShape = z.union([
|
|
551
|
+
liveUserSignSignedOutputShape,
|
|
552
|
+
livePolicySignSignedOutputShape,
|
|
553
|
+
liveUserSignTerminalOutputShape,
|
|
554
|
+
livePolicySignTerminalOutputShape,
|
|
555
|
+
notConnectedSignOutputShape,
|
|
556
|
+
sessionEndedSignTransactionOutputShape,
|
|
557
|
+
]);
|
|
558
|
+
export const signTransactionToolOutputShape = z.union([
|
|
559
|
+
liveUserSignSignedOutputShape,
|
|
560
|
+
livePolicySignSignedOutputShape,
|
|
561
|
+
liveUserSignTerminalOutputShape,
|
|
562
|
+
livePolicySignTerminalOutputShape,
|
|
563
|
+
notConnectedSignOutputShape,
|
|
564
|
+
sessionEndedSignTransactionOutputShape,
|
|
565
|
+
errorToolResultShape,
|
|
566
|
+
]);
|
|
567
|
+
export const signPersonalMessageSuccessOutputShape = z.union([
|
|
568
|
+
liveUserSignPersonalMessageSignedOutputShape,
|
|
569
|
+
liveUserSignTerminalOutputShape,
|
|
570
|
+
notConnectedSignOutputShape,
|
|
571
|
+
sessionEndedSignPersonalMessageOutputShape,
|
|
572
|
+
]);
|
|
573
|
+
export const signPersonalMessageToolOutputShape = z.union([
|
|
574
|
+
liveUserSignPersonalMessageSignedOutputShape,
|
|
575
|
+
liveUserSignTerminalOutputShape,
|
|
576
|
+
notConnectedSignOutputShape,
|
|
577
|
+
sessionEndedSignPersonalMessageOutputShape,
|
|
578
|
+
errorToolResultShape,
|
|
579
|
+
]);
|
|
580
|
+
const policyProposeResultPolicyShape = z.object({
|
|
581
|
+
policyHash: z.string().regex(POLICY_ID_PATTERN),
|
|
582
|
+
ruleCount: z.number().int().min(0).max(MAX_POLICY_RULE_COUNT),
|
|
583
|
+
highestAction: z.enum(APPROVAL_HISTORY_HIGHEST_ACTIONS),
|
|
584
|
+
}).strict();
|
|
585
|
+
const livePolicyProposeOutputShape = z
|
|
586
|
+
.object({
|
|
587
|
+
source: z.literal("live"),
|
|
588
|
+
deviceId: safeDeviceIdShape,
|
|
589
|
+
status: z.enum(POLICY_PROPOSE_RESULT_STATUSES),
|
|
590
|
+
reasonCode: z.string().regex(APPROVAL_HISTORY_REASON_CODE_PATTERN),
|
|
591
|
+
policy: policyProposeResultPolicyShape.optional(),
|
|
592
|
+
})
|
|
593
|
+
.strict()
|
|
594
|
+
.refine((value) => (value.status === "invalid_policy") === (value.policy === undefined), {
|
|
595
|
+
message: "invalid_policy omits policy metadata; other policy_propose_result statuses include it",
|
|
596
|
+
});
|
|
597
|
+
const notConnectedPolicyProposeOutputShape = z.object({
|
|
598
|
+
source: z.literal("not_connected"),
|
|
599
|
+
deviceId: safeDeviceIdShape,
|
|
600
|
+
reason: z.literal("not_connected"),
|
|
601
|
+
}).strict();
|
|
602
|
+
const sessionEndedPolicyProposeOutputShape = z.object({
|
|
603
|
+
source: z.literal("session_ended"),
|
|
604
|
+
deviceId: safeDeviceIdShape,
|
|
605
|
+
reason: z.enum(POLICY_PROPOSE_SESSION_ENDED_REASONS),
|
|
606
|
+
}).strict();
|
|
607
|
+
export const policyProposeSuccessOutputShape = z.discriminatedUnion("source", [
|
|
608
|
+
livePolicyProposeOutputShape,
|
|
609
|
+
notConnectedPolicyProposeOutputShape,
|
|
610
|
+
sessionEndedPolicyProposeOutputShape,
|
|
611
|
+
]);
|
|
612
|
+
export const policyProposeToolOutputShape = z.discriminatedUnion("source", [
|
|
613
|
+
livePolicyProposeOutputShape,
|
|
614
|
+
notConnectedPolicyProposeOutputShape,
|
|
615
|
+
sessionEndedPolicyProposeOutputShape,
|
|
616
|
+
errorToolResultShape,
|
|
617
|
+
]);
|
|
618
|
+
const cachedDeviceStatusOutputShape = z.object({
|
|
619
|
+
source: z.literal("cached"),
|
|
620
|
+
connected: z.literal(false),
|
|
621
|
+
statusObservedAt: isoInstantShape,
|
|
622
|
+
unavailableReason: unavailableReasonShape,
|
|
623
|
+
firmwareErrorCode: z
|
|
624
|
+
.string()
|
|
625
|
+
.refine((code) => Object.prototype.hasOwnProperty.call(PUBLIC_ERROR_MESSAGES, code))
|
|
626
|
+
.optional(),
|
|
627
|
+
cachedStatus: deviceStatusSnapshotShape,
|
|
628
|
+
}).strict();
|
|
629
|
+
export const getDeviceStatusSuccessOutputShape = z.discriminatedUnion("source", [
|
|
630
|
+
liveStatusShape,
|
|
631
|
+
cachedDeviceStatusOutputShape,
|
|
632
|
+
]);
|
|
633
|
+
export const getDeviceStatusToolOutputShape = z.discriminatedUnion("source", [
|
|
634
|
+
liveStatusShape,
|
|
635
|
+
cachedDeviceStatusOutputShape,
|
|
636
|
+
errorToolResultShape,
|
|
637
|
+
]);
|
|
638
|
+
export const hostSuccessOutputSchemas = {
|
|
639
|
+
scanDevices: scanDevicesSuccessOutputShape,
|
|
640
|
+
identifyDevices: identifyDevicesSuccessOutputShape,
|
|
641
|
+
selectDevice: selectDeviceSuccessOutputShape,
|
|
642
|
+
getDeviceStatus: getDeviceStatusSuccessOutputShape,
|
|
643
|
+
listDevices: listDevicesSuccessOutputShape,
|
|
644
|
+
setDeviceMetadata: setDeviceMetadataSuccessOutputShape,
|
|
645
|
+
connectDevice: connectDeviceSuccessOutputShape,
|
|
646
|
+
disconnectDevice: disconnectDeviceSuccessOutputShape,
|
|
647
|
+
getCapabilities: getCapabilitiesSuccessOutputShape,
|
|
648
|
+
getAccounts: getAccountsSuccessOutputShape,
|
|
649
|
+
policyGet: policyGetSuccessOutputShape,
|
|
650
|
+
getApprovalHistory: getApprovalHistorySuccessOutputShape,
|
|
651
|
+
signTransaction: signTransactionSuccessOutputShape,
|
|
652
|
+
signPersonalMessage: signPersonalMessageSuccessOutputShape,
|
|
653
|
+
policyPropose: policyProposeSuccessOutputShape,
|
|
654
|
+
};
|
|
655
|
+
//# sourceMappingURL=host-output-schema.js.map
|