@agentrix/shared 1.0.1
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/dist/index.cjs +1957 -0
- package/dist/index.d.cts +6321 -0
- package/package.json +39 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1957 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
var node_fs = require('node:fs');
|
|
5
|
+
var node_path = require('node:path');
|
|
6
|
+
var tweetnacl = require('tweetnacl');
|
|
7
|
+
var base64js = require('base64-js');
|
|
8
|
+
|
|
9
|
+
function _interopNamespaceDefault(e) {
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n.default = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var base64js__namespace = /*#__PURE__*/_interopNamespaceDefault(base64js);
|
|
27
|
+
|
|
28
|
+
const ApiErrorSchema = zod.z.object({
|
|
29
|
+
error: zod.z.string(),
|
|
30
|
+
message: zod.z.string(),
|
|
31
|
+
details: zod.z.any().optional()
|
|
32
|
+
});
|
|
33
|
+
const PaginatedResponseSchema = (itemSchema) => zod.z.object({
|
|
34
|
+
total: zod.z.number(),
|
|
35
|
+
page: zod.z.number(),
|
|
36
|
+
limit: zod.z.number(),
|
|
37
|
+
items: zod.z.array(itemSchema)
|
|
38
|
+
});
|
|
39
|
+
const SimpleSuccessSchema = zod.z.object({
|
|
40
|
+
success: zod.z.literal(true),
|
|
41
|
+
message: zod.z.string()
|
|
42
|
+
});
|
|
43
|
+
const DateSchema = zod.z.string().datetime();
|
|
44
|
+
const IdSchema = zod.z.string().min(1);
|
|
45
|
+
const FileStatsSchema = zod.z.object({
|
|
46
|
+
path: zod.z.string(),
|
|
47
|
+
insertions: zod.z.number(),
|
|
48
|
+
deletions: zod.z.number()
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const UserBasicInfoSchema = zod.z.object({
|
|
52
|
+
id: IdSchema,
|
|
53
|
+
username: zod.z.string(),
|
|
54
|
+
email: zod.z.string().email().nullable(),
|
|
55
|
+
avatar: zod.z.string().url().nullable()
|
|
56
|
+
});
|
|
57
|
+
const OAuthAccountInfoSchema = zod.z.object({
|
|
58
|
+
provider: zod.z.string(),
|
|
59
|
+
username: zod.z.string(),
|
|
60
|
+
email: zod.z.string().email().nullable(),
|
|
61
|
+
avatarUrl: zod.z.string().url()
|
|
62
|
+
});
|
|
63
|
+
const UserWithOAuthAccountsSchema = UserBasicInfoSchema.extend({
|
|
64
|
+
oauthAccounts: zod.z.array(OAuthAccountInfoSchema).optional()
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const SignatureAuthRequestSchema = zod.z.object({
|
|
68
|
+
publicKey: zod.z.string(),
|
|
69
|
+
// Base64-encoded Ed25519 public key
|
|
70
|
+
challenge: zod.z.string(),
|
|
71
|
+
// Base64-encoded random challenge
|
|
72
|
+
signature: zod.z.string(),
|
|
73
|
+
// Base64-encoded Ed25519 signature
|
|
74
|
+
salt: zod.z.string(),
|
|
75
|
+
// Salt for PIN code encryption (base64)
|
|
76
|
+
encryptedSecret: zod.z.string()
|
|
77
|
+
// Encrypted secret (base64)
|
|
78
|
+
});
|
|
79
|
+
const SignatureAuthResponseSchema = zod.z.object({
|
|
80
|
+
token: zod.z.string(),
|
|
81
|
+
user: UserBasicInfoSchema
|
|
82
|
+
});
|
|
83
|
+
const UserProfileResponseSchema = zod.z.object({
|
|
84
|
+
user: UserBasicInfoSchema.extend({
|
|
85
|
+
encryptedSecret: zod.z.string(),
|
|
86
|
+
secretSalt: zod.z.string(),
|
|
87
|
+
createdAt: DateSchema,
|
|
88
|
+
oauthAccounts: zod.z.array(OAuthAccountInfoSchema).optional()
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
const LogoutResponseSchema = zod.z.object({
|
|
92
|
+
success: zod.z.literal(true)
|
|
93
|
+
});
|
|
94
|
+
const ResetSecretRequestSchema = zod.z.object({
|
|
95
|
+
salt: zod.z.string(),
|
|
96
|
+
// New salt for PIN code encryption
|
|
97
|
+
encryptedSecret: zod.z.string()
|
|
98
|
+
// New encrypted secret
|
|
99
|
+
});
|
|
100
|
+
const ResetSecretResponseSchema = zod.z.object({
|
|
101
|
+
deleted: zod.z.object({
|
|
102
|
+
machines: zod.z.number(),
|
|
103
|
+
ownedMachineUsers: zod.z.number(),
|
|
104
|
+
memberAccess: zod.z.number()
|
|
105
|
+
})
|
|
106
|
+
});
|
|
107
|
+
const OAuthLoginQuerySchema = zod.z.object({
|
|
108
|
+
redirect: zod.z.string().optional(),
|
|
109
|
+
// Optional redirect URL
|
|
110
|
+
signature: zod.z.string(),
|
|
111
|
+
// Base64-encoded Ed25519 public key
|
|
112
|
+
challenge: zod.z.string(),
|
|
113
|
+
// Base64-encoded random challenge
|
|
114
|
+
signatureProof: zod.z.string(),
|
|
115
|
+
// Base64-encoded Ed25519 signature
|
|
116
|
+
salt: zod.z.string(),
|
|
117
|
+
// Salt for PIN code encryption (base64)
|
|
118
|
+
encryptedSecret: zod.z.string()
|
|
119
|
+
// Encrypted secret (base64)
|
|
120
|
+
});
|
|
121
|
+
const OAuthCallbackQuerySchema = zod.z.object({
|
|
122
|
+
code: zod.z.string(),
|
|
123
|
+
state: zod.z.string().optional()
|
|
124
|
+
});
|
|
125
|
+
const OAuthCallbackResponseSchema = zod.z.object({
|
|
126
|
+
token: zod.z.string(),
|
|
127
|
+
user: UserWithOAuthAccountsSchema
|
|
128
|
+
});
|
|
129
|
+
const OAuthBindQuerySchema = zod.z.object({
|
|
130
|
+
redirect: zod.z.string().optional()
|
|
131
|
+
// Optional redirect URL
|
|
132
|
+
});
|
|
133
|
+
const OAuthBindResponseSchema = zod.z.object({
|
|
134
|
+
authUrl: zod.z.string().url()
|
|
135
|
+
});
|
|
136
|
+
const OAuthBindCallbackResponseSchema = OAuthAccountInfoSchema;
|
|
137
|
+
const OAuthUnbindResponseSchema = zod.z.object({
|
|
138
|
+
success: zod.z.literal(true)
|
|
139
|
+
});
|
|
140
|
+
const MachineAuthRequestSchema = zod.z.object({
|
|
141
|
+
machineId: zod.z.string()
|
|
142
|
+
// Unique machine identifier
|
|
143
|
+
});
|
|
144
|
+
const MachineAuthResultQuerySchema = zod.z.object({
|
|
145
|
+
machineId: zod.z.string()
|
|
146
|
+
});
|
|
147
|
+
const MachineAuthAuthorizedResponseSchema = zod.z.object({
|
|
148
|
+
id: zod.z.string(),
|
|
149
|
+
state: zod.z.literal("authorized"),
|
|
150
|
+
token: zod.z.string(),
|
|
151
|
+
content: zod.z.string()
|
|
152
|
+
// Encrypted approval data
|
|
153
|
+
});
|
|
154
|
+
const MachineApprovalStatusQuerySchema = zod.z.object({
|
|
155
|
+
machineId: zod.z.string()
|
|
156
|
+
});
|
|
157
|
+
const ApprovalStatusResponseSchema = zod.z.object({
|
|
158
|
+
status: zod.z.enum(["pending", "approved"])
|
|
159
|
+
});
|
|
160
|
+
const MachineApprovalRequestSchema = zod.z.object({
|
|
161
|
+
machineId: zod.z.string(),
|
|
162
|
+
content: zod.z.string()
|
|
163
|
+
// Base64-encoded encrypted approval data
|
|
164
|
+
});
|
|
165
|
+
const CloudJoinRequestSchema = zod.z.object({
|
|
166
|
+
cloudId: zod.z.string()
|
|
167
|
+
});
|
|
168
|
+
const CloudJoinResultQuerySchema = zod.z.object({
|
|
169
|
+
cloudId: zod.z.string()
|
|
170
|
+
});
|
|
171
|
+
const CloudJoinStatusQuerySchema = zod.z.object({
|
|
172
|
+
userId: zod.z.string(),
|
|
173
|
+
cloudId: zod.z.string()
|
|
174
|
+
});
|
|
175
|
+
const CloudJoinApprovalRequestSchema = zod.z.object({
|
|
176
|
+
userId: zod.z.string(),
|
|
177
|
+
cloudId: zod.z.string()
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const StartTaskRequestSchema = zod.z.object({
|
|
181
|
+
chatId: zod.z.string(),
|
|
182
|
+
message: zod.z.custom(
|
|
183
|
+
(data) => {
|
|
184
|
+
return typeof data === "object" && data !== null && "type" in data;
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
message: "Invalid SDKMessage format"
|
|
188
|
+
}
|
|
189
|
+
).optional(),
|
|
190
|
+
encryptedMessage: zod.z.string().optional(),
|
|
191
|
+
// base64 sealed-box payload for local machines
|
|
192
|
+
cwd: zod.z.string().optional(),
|
|
193
|
+
// For local mode: current working directory
|
|
194
|
+
machineId: zod.z.string().optional(),
|
|
195
|
+
// For local mode: specific machine
|
|
196
|
+
cloudId: zod.z.string().optional(),
|
|
197
|
+
// For cloud mode: cloud ID
|
|
198
|
+
repositoryId: zod.z.string().optional(),
|
|
199
|
+
baseBranch: zod.z.string().optional(),
|
|
200
|
+
// Base branch for the repository
|
|
201
|
+
dataEncryptionKey: zod.z.string().optional()
|
|
202
|
+
// base64 sealed-box: app public key encrypted by machine public key
|
|
203
|
+
}).refine((data) => data.machineId || data.cloudId, {
|
|
204
|
+
message: "Must provide either machineId or cloudId"
|
|
205
|
+
}).refine(
|
|
206
|
+
(data) => {
|
|
207
|
+
if (data.machineId) {
|
|
208
|
+
return !!data.encryptedMessage && !!data.dataEncryptionKey && !data.message;
|
|
209
|
+
}
|
|
210
|
+
if (data.cloudId) {
|
|
211
|
+
return !!data.message && !data.encryptedMessage;
|
|
212
|
+
}
|
|
213
|
+
return true;
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
message: "For local machine tasks, encryptedMessage is required; for cloud tasks, message is required"
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
const startTaskSchema = StartTaskRequestSchema;
|
|
220
|
+
const StartTaskResponseSchema = zod.z.object({
|
|
221
|
+
taskId: IdSchema,
|
|
222
|
+
chatId: IdSchema,
|
|
223
|
+
agentId: zod.z.string(),
|
|
224
|
+
userId: zod.z.string(),
|
|
225
|
+
state: zod.z.string(),
|
|
226
|
+
machineId: zod.z.string().nullable(),
|
|
227
|
+
cloudId: zod.z.string().nullable(),
|
|
228
|
+
repositoryId: zod.z.string().nullable(),
|
|
229
|
+
baseBranch: zod.z.string().nullable(),
|
|
230
|
+
title: zod.z.string().nullable(),
|
|
231
|
+
createdAt: DateSchema,
|
|
232
|
+
updatedAt: DateSchema
|
|
233
|
+
});
|
|
234
|
+
const TaskItemSchema = zod.z.object({
|
|
235
|
+
id: IdSchema,
|
|
236
|
+
chatId: IdSchema,
|
|
237
|
+
userId: zod.z.string(),
|
|
238
|
+
state: zod.z.string(),
|
|
239
|
+
agentId: zod.z.string(),
|
|
240
|
+
machineId: zod.z.string().nullable(),
|
|
241
|
+
cloudId: zod.z.string().nullable(),
|
|
242
|
+
repositoryId: zod.z.string().nullable(),
|
|
243
|
+
baseBranch: zod.z.string().nullable(),
|
|
244
|
+
title: zod.z.string().nullable(),
|
|
245
|
+
// Task title (can be set by worker)
|
|
246
|
+
agentSessionId: zod.z.string().nullable(),
|
|
247
|
+
dataEncryptionKey: zod.z.string().nullable(),
|
|
248
|
+
pullRequestNumber: zod.z.number().nullable(),
|
|
249
|
+
pullRequestUrl: zod.z.string().nullable(),
|
|
250
|
+
pullRequestState: zod.z.enum(["open", "closed", "merged"]).nullable(),
|
|
251
|
+
// PR state
|
|
252
|
+
pullRequestStateChangedAt: zod.z.string().nullable(),
|
|
253
|
+
// ISO 8601 string
|
|
254
|
+
gitStats: zod.z.object({
|
|
255
|
+
totalInsertions: zod.z.number(),
|
|
256
|
+
totalDeletions: zod.z.number(),
|
|
257
|
+
files: zod.z.array(FileStatsSchema)
|
|
258
|
+
}).nullable(),
|
|
259
|
+
createdAt: zod.z.string(),
|
|
260
|
+
// ISO 8601 string
|
|
261
|
+
updatedAt: zod.z.string()
|
|
262
|
+
// ISO 8601 string
|
|
263
|
+
});
|
|
264
|
+
const ListTasksResponseSchema = zod.z.object({
|
|
265
|
+
tasks: zod.z.array(TaskItemSchema)
|
|
266
|
+
});
|
|
267
|
+
const ResumeTaskRequestSchema = zod.z.object({
|
|
268
|
+
taskId: zod.z.string(),
|
|
269
|
+
message: zod.z.custom(
|
|
270
|
+
(data) => {
|
|
271
|
+
return typeof data === "object" && data !== null && "type" in data;
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
message: "Invalid SDKMessage format"
|
|
275
|
+
}
|
|
276
|
+
).optional(),
|
|
277
|
+
encryptedMessage: zod.z.string().optional(),
|
|
278
|
+
// base64 sealed-box payload for local tasks
|
|
279
|
+
dataEncryptionKey: zod.z.string().optional()
|
|
280
|
+
// base64 sealed-box: app public key encrypted by machine public key
|
|
281
|
+
}).refine(
|
|
282
|
+
(data) => {
|
|
283
|
+
return !!data.message !== !!data.encryptedMessage;
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
message: "Exactly one of message or encryptedMessage must be provided"
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
const resumeTaskRequestSchema = ResumeTaskRequestSchema;
|
|
290
|
+
const ResumeTaskResponseSchema = zod.z.object({
|
|
291
|
+
message: zod.z.string(),
|
|
292
|
+
taskId: IdSchema
|
|
293
|
+
});
|
|
294
|
+
const CancelTaskRequestSchema = zod.z.object({
|
|
295
|
+
taskId: zod.z.string(),
|
|
296
|
+
reason: zod.z.string().optional()
|
|
297
|
+
});
|
|
298
|
+
const cancelTaskRequestSchema = CancelTaskRequestSchema;
|
|
299
|
+
const CancelTaskResponseSchema = zod.z.object({
|
|
300
|
+
message: zod.z.string(),
|
|
301
|
+
taskId: IdSchema
|
|
302
|
+
});
|
|
303
|
+
const StopTaskRequestSchema = zod.z.object({
|
|
304
|
+
reason: zod.z.string().optional()
|
|
305
|
+
});
|
|
306
|
+
const stopTaskRequestSchema = StopTaskRequestSchema;
|
|
307
|
+
const StopTaskResponseSchema = zod.z.object({
|
|
308
|
+
message: zod.z.string(),
|
|
309
|
+
taskId: IdSchema
|
|
310
|
+
});
|
|
311
|
+
const PermissionResponseRequestSchema = zod.z.object({
|
|
312
|
+
// Permission response data - structure depends on what the worker requested
|
|
313
|
+
// For now, we keep it flexible
|
|
314
|
+
approved: zod.z.boolean().optional(),
|
|
315
|
+
data: zod.z.any().optional()
|
|
316
|
+
});
|
|
317
|
+
const permissionResponseRequestSchema = PermissionResponseRequestSchema;
|
|
318
|
+
const PermissionResponseResponseSchema = zod.z.object({
|
|
319
|
+
message: zod.z.string(),
|
|
320
|
+
taskId: IdSchema
|
|
321
|
+
});
|
|
322
|
+
const ProjectEntrySchema = zod.z.object({
|
|
323
|
+
name: zod.z.string(),
|
|
324
|
+
type: zod.z.enum(["file", "directory"]),
|
|
325
|
+
size: zod.z.number(),
|
|
326
|
+
// Size in bytes
|
|
327
|
+
modifiedAt: zod.z.string()
|
|
328
|
+
// ISO 8601 string
|
|
329
|
+
});
|
|
330
|
+
const ProjectDirectoryResponseSchema = zod.z.object({
|
|
331
|
+
type: zod.z.literal("directory"),
|
|
332
|
+
path: zod.z.string(),
|
|
333
|
+
// Relative path from project root
|
|
334
|
+
entries: zod.z.array(ProjectEntrySchema),
|
|
335
|
+
modifiedAt: zod.z.string()
|
|
336
|
+
// ISO 8601 string
|
|
337
|
+
});
|
|
338
|
+
const QueryEventsRequestSchema = zod.z.object({
|
|
339
|
+
limit: zod.z.coerce.number().min(1).max(100).optional(),
|
|
340
|
+
offset: zod.z.coerce.number().min(0).optional(),
|
|
341
|
+
before: zod.z.string().datetime().optional(),
|
|
342
|
+
after: zod.z.string().datetime().optional(),
|
|
343
|
+
eventType: zod.z.enum(["task-message", "task-artifacts-updated"]).optional()
|
|
344
|
+
});
|
|
345
|
+
const CreateMergeRequestSchema = zod.z.object({
|
|
346
|
+
taskId: zod.z.string(),
|
|
347
|
+
// taskId
|
|
348
|
+
title: zod.z.string().optional(),
|
|
349
|
+
// PR title
|
|
350
|
+
description: zod.z.string().optional(),
|
|
351
|
+
// PR description
|
|
352
|
+
draft: zod.z.boolean().optional(),
|
|
353
|
+
// Create as draft PR (default: false)
|
|
354
|
+
autoMerge: zod.z.boolean().optional()
|
|
355
|
+
// Enable auto-merge (default: false)
|
|
356
|
+
});
|
|
357
|
+
const createMergeRequestSchema = CreateMergeRequestSchema;
|
|
358
|
+
const CreateMergeRequestResponseSchema = zod.z.object({
|
|
359
|
+
taskId: zod.z.string(),
|
|
360
|
+
pullRequestNumber: zod.z.number().optional(),
|
|
361
|
+
// PR number (e.g., #123)
|
|
362
|
+
pullRequestUrl: zod.z.string().optional(),
|
|
363
|
+
// Full URL to the PR
|
|
364
|
+
status: zod.z.enum(["success", "failed"]),
|
|
365
|
+
// Current status
|
|
366
|
+
reason: zod.z.string().optional()
|
|
367
|
+
// failed-reason
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const ChatMemberSchema = zod.z.object({
|
|
371
|
+
id: IdSchema,
|
|
372
|
+
chatId: IdSchema,
|
|
373
|
+
memberCode: zod.z.string(),
|
|
374
|
+
type: zod.z.enum(["human", "agent"]),
|
|
375
|
+
role: zod.z.string(),
|
|
376
|
+
createdAt: zod.z.string(),
|
|
377
|
+
// ISO 8601 string
|
|
378
|
+
updatedAt: zod.z.string()
|
|
379
|
+
// ISO 8601 string
|
|
380
|
+
});
|
|
381
|
+
const ChatTypeSchema = zod.z.enum(["direct", "group"]);
|
|
382
|
+
const ChatSchema = zod.z.object({
|
|
383
|
+
id: IdSchema,
|
|
384
|
+
owner: IdSchema,
|
|
385
|
+
// Group: userId of owner; Direct: "memberCode1:memberCode2" (sorted)
|
|
386
|
+
type: ChatTypeSchema,
|
|
387
|
+
createdAt: zod.z.string(),
|
|
388
|
+
// ISO 8601 string
|
|
389
|
+
updatedAt: zod.z.string()
|
|
390
|
+
// ISO 8601 string
|
|
391
|
+
});
|
|
392
|
+
const ChatWithMembersSchema = ChatSchema.extend({
|
|
393
|
+
members: zod.z.array(ChatMemberSchema)
|
|
394
|
+
});
|
|
395
|
+
const ChatMemberInputSchema = zod.z.object({
|
|
396
|
+
memberCode: zod.z.string().min(1),
|
|
397
|
+
type: zod.z.enum(["human", "agent"])
|
|
398
|
+
});
|
|
399
|
+
const CreateChatRequestSchema = zod.z.object({
|
|
400
|
+
type: ChatTypeSchema.default("direct"),
|
|
401
|
+
// Optional, defaults to 'direct'
|
|
402
|
+
members: zod.z.array(ChatMemberInputSchema)
|
|
403
|
+
});
|
|
404
|
+
const CreateChatResponseSchema = ChatWithMembersSchema;
|
|
405
|
+
const ListChatsResponseSchema = zod.z.object({
|
|
406
|
+
chats: zod.z.array(ChatWithMembersSchema)
|
|
407
|
+
});
|
|
408
|
+
const GetChatResponseSchema = ChatWithMembersSchema;
|
|
409
|
+
const ListChatMembersResponseSchema = zod.z.object({
|
|
410
|
+
members: zod.z.array(ChatMemberSchema)
|
|
411
|
+
});
|
|
412
|
+
const AddChatMemberRequestSchema = zod.z.object({
|
|
413
|
+
members: zod.z.array(ChatMemberInputSchema).min(1)
|
|
414
|
+
});
|
|
415
|
+
const AddChatMemberResponseSchema = zod.z.object({
|
|
416
|
+
members: zod.z.array(ChatMemberSchema)
|
|
417
|
+
});
|
|
418
|
+
const RemoveChatMemberRequestSchema = zod.z.object({
|
|
419
|
+
members: zod.z.array(ChatMemberInputSchema).min(1)
|
|
420
|
+
});
|
|
421
|
+
const ListChatTasksResponseSchema = zod.z.object({
|
|
422
|
+
tasks: zod.z.array(TaskItemSchema)
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const AgentTypeSchema = zod.z.enum(["claude", "codex"]);
|
|
426
|
+
const AgentSchema = zod.z.object({
|
|
427
|
+
id: IdSchema,
|
|
428
|
+
name: zod.z.string(),
|
|
429
|
+
type: AgentTypeSchema,
|
|
430
|
+
avatar: zod.z.string().nullable(),
|
|
431
|
+
userId: zod.z.string(),
|
|
432
|
+
description: zod.z.string().nullable(),
|
|
433
|
+
signature: zod.z.string().nullable(),
|
|
434
|
+
guildMsg: zod.z.string(),
|
|
435
|
+
placeholderMsg: zod.z.string(),
|
|
436
|
+
developerName: zod.z.string(),
|
|
437
|
+
developerEmail: zod.z.string().nullable(),
|
|
438
|
+
gitRepoId: zod.z.string().nullable(),
|
|
439
|
+
supportLocal: zod.z.boolean(),
|
|
440
|
+
enable: zod.z.boolean()
|
|
441
|
+
});
|
|
442
|
+
const ListAgentsResponseSchema = zod.z.object({
|
|
443
|
+
agents: zod.z.array(AgentSchema)
|
|
444
|
+
});
|
|
445
|
+
const GetAgentResponseSchema = AgentSchema;
|
|
446
|
+
const CreateAgentRequestSchema = zod.z.object({
|
|
447
|
+
name: zod.z.string().min(1, "Name is required"),
|
|
448
|
+
type: AgentTypeSchema,
|
|
449
|
+
avatar: zod.z.string().optional(),
|
|
450
|
+
description: zod.z.string().optional(),
|
|
451
|
+
signature: zod.z.string().optional(),
|
|
452
|
+
guildMsg: zod.z.string().default("what can I do for you today?"),
|
|
453
|
+
placeholderMsg: zod.z.string().default("Ask me anything..."),
|
|
454
|
+
gitRepoId: zod.z.string().optional(),
|
|
455
|
+
supportLocal: zod.z.boolean().default(false)
|
|
456
|
+
});
|
|
457
|
+
const CreateAgentResponseSchema = AgentSchema;
|
|
458
|
+
const UpdateAgentRequestSchema = zod.z.object({
|
|
459
|
+
name: zod.z.string().min(1).optional(),
|
|
460
|
+
type: AgentTypeSchema.optional(),
|
|
461
|
+
avatar: zod.z.string().nullable().optional(),
|
|
462
|
+
description: zod.z.string().nullable().optional(),
|
|
463
|
+
signature: zod.z.string().nullable().optional(),
|
|
464
|
+
guildMsg: zod.z.string().optional(),
|
|
465
|
+
placeholderMsg: zod.z.string().optional(),
|
|
466
|
+
gitRepoId: zod.z.string().nullable().optional(),
|
|
467
|
+
supportLocal: zod.z.boolean().optional()
|
|
468
|
+
});
|
|
469
|
+
const UpdateAgentResponseSchema = AgentSchema;
|
|
470
|
+
const DeleteAgentResponseSchema = zod.z.object({
|
|
471
|
+
message: zod.z.string(),
|
|
472
|
+
agentId: IdSchema
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
const LocalMachineSchema = zod.z.object({
|
|
476
|
+
id: IdSchema,
|
|
477
|
+
owner: IdSchema,
|
|
478
|
+
status: zod.z.string(),
|
|
479
|
+
metadata: zod.z.string().nullable(),
|
|
480
|
+
approval: zod.z.string(),
|
|
481
|
+
dataEncryptionKey: zod.z.string(),
|
|
482
|
+
// per-user sealed-box key (base64)
|
|
483
|
+
createdAt: zod.z.string(),
|
|
484
|
+
// ISO 8601 string
|
|
485
|
+
updatedAt: zod.z.string()
|
|
486
|
+
// ISO 8601 string
|
|
487
|
+
});
|
|
488
|
+
const CloudMachineSchema = zod.z.object({
|
|
489
|
+
id: IdSchema,
|
|
490
|
+
cloudId: IdSchema,
|
|
491
|
+
deviceId: zod.z.string(),
|
|
492
|
+
status: zod.z.string(),
|
|
493
|
+
metadata: zod.z.string().nullable(),
|
|
494
|
+
createdAt: zod.z.string(),
|
|
495
|
+
// ISO 8601 string
|
|
496
|
+
updatedAt: zod.z.string()
|
|
497
|
+
// ISO 8601 string
|
|
498
|
+
});
|
|
499
|
+
const CloudSchema = zod.z.object({
|
|
500
|
+
id: IdSchema,
|
|
501
|
+
owner: IdSchema,
|
|
502
|
+
name: zod.z.string(),
|
|
503
|
+
type: zod.z.enum(["public", "private"]),
|
|
504
|
+
createdAt: zod.z.string(),
|
|
505
|
+
// ISO 8601 string
|
|
506
|
+
updatedAt: zod.z.string(),
|
|
507
|
+
// ISO 8601 string
|
|
508
|
+
machines: zod.z.array(CloudMachineSchema).optional()
|
|
509
|
+
});
|
|
510
|
+
const ListMachinesResponseSchema = zod.z.object({
|
|
511
|
+
clouds: zod.z.array(CloudSchema),
|
|
512
|
+
localMachines: zod.z.array(LocalMachineSchema)
|
|
513
|
+
});
|
|
514
|
+
const SyncMachineRequestSchema = zod.z.object({
|
|
515
|
+
id: zod.z.string(),
|
|
516
|
+
// Machine ID (local) or deviceId (cloud)
|
|
517
|
+
metadata: zod.z.string(),
|
|
518
|
+
// Encrypted metadata (or plaintext JSON for cloud/local-debug modes)
|
|
519
|
+
dataEncryptionKey: zod.z.string().optional()
|
|
520
|
+
// Encrypted machine encryption key (required for local machines)
|
|
521
|
+
});
|
|
522
|
+
const SyncLocalMachineResponseSchema = zod.z.object({
|
|
523
|
+
machine: zod.z.object({
|
|
524
|
+
id: IdSchema,
|
|
525
|
+
metadata: zod.z.string().nullable()
|
|
526
|
+
})
|
|
527
|
+
});
|
|
528
|
+
const SyncCloudMachineResponseSchema = zod.z.object({
|
|
529
|
+
machine: zod.z.object({
|
|
530
|
+
id: IdSchema,
|
|
531
|
+
deviceId: zod.z.string(),
|
|
532
|
+
metadata: zod.z.string().nullable()
|
|
533
|
+
})
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
const FileVisibilitySchema = zod.z.enum(["public", "private"]);
|
|
537
|
+
const GetUploadUrlsRequestSchema = zod.z.object({
|
|
538
|
+
count: zod.z.number().min(1).max(10)
|
|
539
|
+
// Number of upload URLs to generate (1-10)
|
|
540
|
+
});
|
|
541
|
+
const UploadUrlResultSchema = zod.z.object({
|
|
542
|
+
id: IdSchema,
|
|
543
|
+
url: zod.z.string().url(),
|
|
544
|
+
expiresAt: zod.z.string()
|
|
545
|
+
// ISO 8601 string
|
|
546
|
+
});
|
|
547
|
+
const GetUploadUrlsResponseSchema = zod.z.object({
|
|
548
|
+
files: zod.z.array(UploadUrlResultSchema)
|
|
549
|
+
});
|
|
550
|
+
const FileItemSchema = zod.z.object({
|
|
551
|
+
fileId: IdSchema,
|
|
552
|
+
name: zod.z.string(),
|
|
553
|
+
size: zod.z.number(),
|
|
554
|
+
contentType: zod.z.string(),
|
|
555
|
+
createdAt: zod.z.string()
|
|
556
|
+
// ISO 8601 string
|
|
557
|
+
});
|
|
558
|
+
const ConfirmUploadRequestSchema = zod.z.object({
|
|
559
|
+
fileId: IdSchema,
|
|
560
|
+
name: zod.z.string(),
|
|
561
|
+
size: zod.z.number(),
|
|
562
|
+
contentType: zod.z.string(),
|
|
563
|
+
visibility: FileVisibilitySchema.optional().default("private")
|
|
564
|
+
});
|
|
565
|
+
const ConfirmUploadResponseSchema = zod.z.object({
|
|
566
|
+
file: FileItemSchema
|
|
567
|
+
});
|
|
568
|
+
const ListFilesQuerySchema = zod.z.object({
|
|
569
|
+
page: zod.z.coerce.number().min(1).optional().default(1),
|
|
570
|
+
limit: zod.z.coerce.number().min(1).max(100).optional().default(20),
|
|
571
|
+
fileIds: zod.z.string().optional()
|
|
572
|
+
// Comma-separated file IDs (e.g., "file-123,file-456")
|
|
573
|
+
});
|
|
574
|
+
const ListFilesResponseSchema = zod.z.object({
|
|
575
|
+
total: zod.z.number(),
|
|
576
|
+
page: zod.z.number(),
|
|
577
|
+
limit: zod.z.number(),
|
|
578
|
+
files: zod.z.array(FileItemSchema)
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
const RepositorySchema = zod.z.object({
|
|
582
|
+
id: IdSchema,
|
|
583
|
+
owner: zod.z.string(),
|
|
584
|
+
name: zod.z.string(),
|
|
585
|
+
fullName: zod.z.string(),
|
|
586
|
+
defaultBranch: zod.z.string(),
|
|
587
|
+
isPrivate: zod.z.boolean(),
|
|
588
|
+
description: zod.z.string().nullable(),
|
|
589
|
+
url: zod.z.string().url(),
|
|
590
|
+
createdAt: DateSchema,
|
|
591
|
+
updatedAt: DateSchema
|
|
592
|
+
});
|
|
593
|
+
const ListRepositoriesResponseSchema = zod.z.object({
|
|
594
|
+
repositories: zod.z.array(RepositorySchema)
|
|
595
|
+
});
|
|
596
|
+
const GetRepositoryResponseSchema = zod.z.object({
|
|
597
|
+
repository: RepositorySchema
|
|
598
|
+
});
|
|
599
|
+
const GetGitUrlQuerySchema = zod.z.object({
|
|
600
|
+
branch: zod.z.string().optional()
|
|
601
|
+
});
|
|
602
|
+
const GetGitUrlResponseSchema = zod.z.object({
|
|
603
|
+
gitUrl: zod.z.string().url(),
|
|
604
|
+
branch: zod.z.string(),
|
|
605
|
+
repository: zod.z.object({
|
|
606
|
+
owner: zod.z.string(),
|
|
607
|
+
name: zod.z.string(),
|
|
608
|
+
fullName: zod.z.string()
|
|
609
|
+
})
|
|
610
|
+
});
|
|
611
|
+
const BranchSchema = zod.z.object({
|
|
612
|
+
name: zod.z.string(),
|
|
613
|
+
commit: zod.z.object({
|
|
614
|
+
sha: zod.z.string(),
|
|
615
|
+
url: zod.z.string().url()
|
|
616
|
+
}),
|
|
617
|
+
protected: zod.z.boolean()
|
|
618
|
+
});
|
|
619
|
+
const ListBranchesResponseSchema = zod.z.object({
|
|
620
|
+
branches: zod.z.array(BranchSchema)
|
|
621
|
+
});
|
|
622
|
+
const GetInstallUrlResponseSchema = zod.z.object({
|
|
623
|
+
installUrl: zod.z.string().url()
|
|
624
|
+
});
|
|
625
|
+
const GitHubIssueListItemSchema = zod.z.object({
|
|
626
|
+
number: zod.z.number(),
|
|
627
|
+
title: zod.z.string(),
|
|
628
|
+
html_url: zod.z.string().url()
|
|
629
|
+
});
|
|
630
|
+
const GitHubIssueSchema = zod.z.object({
|
|
631
|
+
number: zod.z.number(),
|
|
632
|
+
title: zod.z.string(),
|
|
633
|
+
body: zod.z.string().nullable(),
|
|
634
|
+
html_url: zod.z.string().url()
|
|
635
|
+
});
|
|
636
|
+
const ListIssuesQuerySchema = zod.z.object({
|
|
637
|
+
q: zod.z.string().optional()
|
|
638
|
+
// Search query
|
|
639
|
+
});
|
|
640
|
+
const ListIssuesResponseSchema = zod.z.object({
|
|
641
|
+
issues: zod.z.array(GitHubIssueListItemSchema),
|
|
642
|
+
total_count: zod.z.number()
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
const CreateCloudRequestSchema = zod.z.discriminatedUnion("type", [
|
|
646
|
+
zod.z.object({
|
|
647
|
+
type: zod.z.literal("public"),
|
|
648
|
+
name: zod.z.string().min(1, "name is required")
|
|
649
|
+
}),
|
|
650
|
+
zod.z.object({
|
|
651
|
+
type: zod.z.literal("private"),
|
|
652
|
+
name: zod.z.string().min(1, "name is required"),
|
|
653
|
+
ownerId: zod.z.string().min(1, "ownerId is required")
|
|
654
|
+
})
|
|
655
|
+
]);
|
|
656
|
+
const CreateCloudResponseSchema = zod.z.object({
|
|
657
|
+
id: IdSchema,
|
|
658
|
+
owner: zod.z.string(),
|
|
659
|
+
name: zod.z.string(),
|
|
660
|
+
secret: zod.z.string(),
|
|
661
|
+
// JWT token for cloud authentication
|
|
662
|
+
createdAt: DateSchema
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
const OAuthServerSchema = zod.z.object({
|
|
666
|
+
id: IdSchema,
|
|
667
|
+
provider: zod.z.string(),
|
|
668
|
+
displayName: zod.z.string(),
|
|
669
|
+
authorizeUrl: zod.z.string().url(),
|
|
670
|
+
tokenUrl: zod.z.string().url(),
|
|
671
|
+
userInfoUrl: zod.z.string().url(),
|
|
672
|
+
clientId: zod.z.string(),
|
|
673
|
+
clientSecret: zod.z.string(),
|
|
674
|
+
callbackUrl: zod.z.string().url(),
|
|
675
|
+
scopes: zod.z.array(zod.z.string()).default([]),
|
|
676
|
+
userInfoMapping: zod.z.record(zod.z.string(), zod.z.string()),
|
|
677
|
+
enabled: zod.z.boolean(),
|
|
678
|
+
createdAt: zod.z.union([DateSchema, zod.z.date().transform((d) => d.toISOString())]),
|
|
679
|
+
updatedAt: zod.z.union([DateSchema, zod.z.date().transform((d) => d.toISOString())])
|
|
680
|
+
});
|
|
681
|
+
const OAuthServerPublicSchema = OAuthServerSchema.omit({
|
|
682
|
+
clientSecret: true
|
|
683
|
+
});
|
|
684
|
+
const CreateOAuthServerRequestSchema = zod.z.object({
|
|
685
|
+
provider: zod.z.string().min(1).regex(/^[a-z0-9-]+$/),
|
|
686
|
+
displayName: zod.z.string().min(1),
|
|
687
|
+
authorizeUrl: zod.z.string().url(),
|
|
688
|
+
tokenUrl: zod.z.string().url(),
|
|
689
|
+
userInfoUrl: zod.z.string().url(),
|
|
690
|
+
clientId: zod.z.string().min(1),
|
|
691
|
+
clientSecret: zod.z.string().min(1),
|
|
692
|
+
scopes: zod.z.array(zod.z.string()).optional().default([]),
|
|
693
|
+
userInfoMapping: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
694
|
+
enabled: zod.z.boolean().default(true)
|
|
695
|
+
});
|
|
696
|
+
const CreateOAuthServerResponseSchema = OAuthServerSchema;
|
|
697
|
+
const ListOAuthServersQuerySchema = zod.z.object({
|
|
698
|
+
enabled: zod.z.string().optional().transform((val) => val === "true" ? true : val === "false" ? false : void 0)
|
|
699
|
+
});
|
|
700
|
+
const ListOAuthServersResponseSchema = zod.z.array(OAuthServerSchema);
|
|
701
|
+
const GetOAuthServerResponseSchema = OAuthServerSchema;
|
|
702
|
+
const UpdateOAuthServerRequestSchema = CreateOAuthServerRequestSchema.partial();
|
|
703
|
+
const UpdateOAuthServerResponseSchema = OAuthServerSchema;
|
|
704
|
+
const DeleteOAuthServerResponseSchema = zod.z.object({
|
|
705
|
+
success: zod.z.literal(true)
|
|
706
|
+
});
|
|
707
|
+
const ToggleOAuthServerRequestSchema = zod.z.object({
|
|
708
|
+
enabled: zod.z.boolean()
|
|
709
|
+
});
|
|
710
|
+
const ToggleOAuthServerResponseSchema = OAuthServerSchema;
|
|
711
|
+
|
|
712
|
+
const RechargeResponseSchema = zod.z.object({
|
|
713
|
+
success: zod.z.literal(true),
|
|
714
|
+
packageId: zod.z.string(),
|
|
715
|
+
newBalance: zod.z.number().nonnegative()
|
|
716
|
+
});
|
|
717
|
+
const UserBalanceResponseSchema = zod.z.object({
|
|
718
|
+
userId: zod.z.string(),
|
|
719
|
+
balance: zod.z.number().nonnegative(),
|
|
720
|
+
currentCreditsPackageId: zod.z.string().nullable(),
|
|
721
|
+
balanceRefreshAt: DateSchema.nullable(),
|
|
722
|
+
lastCalculatedAt: DateSchema
|
|
723
|
+
});
|
|
724
|
+
const CreditsPackageSchema = zod.z.object({
|
|
725
|
+
id: zod.z.string(),
|
|
726
|
+
userId: zod.z.string(),
|
|
727
|
+
name: zod.z.string(),
|
|
728
|
+
credit: zod.z.number().positive(),
|
|
729
|
+
usage: zod.z.number().nonnegative(),
|
|
730
|
+
remaining: zod.z.number().nonnegative(),
|
|
731
|
+
expiredAt: DateSchema,
|
|
732
|
+
createdAt: DateSchema,
|
|
733
|
+
updatedAt: DateSchema
|
|
734
|
+
});
|
|
735
|
+
const ListPackagesQuerySchema = zod.z.object({
|
|
736
|
+
limit: zod.z.string().optional().transform((v) => v ? parseInt(v) : 20),
|
|
737
|
+
offset: zod.z.string().optional().transform((v) => v ? parseInt(v) : 0),
|
|
738
|
+
activeOnly: zod.z.string().optional().transform((v) => v === "true")
|
|
739
|
+
});
|
|
740
|
+
const ListPackagesResponseSchema = zod.z.object({
|
|
741
|
+
packages: zod.z.array(CreditsPackageSchema),
|
|
742
|
+
total: zod.z.number().int().nonnegative()
|
|
743
|
+
});
|
|
744
|
+
const ChargeTransactionSchema = zod.z.object({
|
|
745
|
+
id: zod.z.string(),
|
|
746
|
+
userId: zod.z.string(),
|
|
747
|
+
creditsPackageId: zod.z.string(),
|
|
748
|
+
packageName: zod.z.string().optional(),
|
|
749
|
+
amount: zod.z.number().positive(),
|
|
750
|
+
balanceBefore: zod.z.number().nonnegative(),
|
|
751
|
+
balanceAfter: zod.z.number().nonnegative(),
|
|
752
|
+
type: zod.z.enum(["user_recharge", "system_bonus", "refund"]),
|
|
753
|
+
paymentMethod: zod.z.string().nullable(),
|
|
754
|
+
paymentId: zod.z.string().nullable(),
|
|
755
|
+
metadata: zod.z.any(),
|
|
756
|
+
createdAt: DateSchema,
|
|
757
|
+
transactionType: zod.z.literal("charge")
|
|
758
|
+
});
|
|
759
|
+
const ConsumeTransactionSchema = zod.z.object({
|
|
760
|
+
id: zod.z.string(),
|
|
761
|
+
userId: zod.z.string(),
|
|
762
|
+
taskId: zod.z.string(),
|
|
763
|
+
agentId: zod.z.string(),
|
|
764
|
+
creditsPackageId: zod.z.string(),
|
|
765
|
+
packageName: zod.z.string().optional(),
|
|
766
|
+
amount: zod.z.number().positive(),
|
|
767
|
+
balanceBefore: zod.z.number().nonnegative(),
|
|
768
|
+
balanceAfter: zod.z.number().nonnegative(),
|
|
769
|
+
metadata: zod.z.any(),
|
|
770
|
+
createdAt: DateSchema,
|
|
771
|
+
transactionType: zod.z.literal("consume")
|
|
772
|
+
});
|
|
773
|
+
const TransactionSchema = zod.z.union([
|
|
774
|
+
ChargeTransactionSchema,
|
|
775
|
+
ConsumeTransactionSchema
|
|
776
|
+
]);
|
|
777
|
+
const ListTransactionsQuerySchema = zod.z.object({
|
|
778
|
+
limit: zod.z.string().optional().transform((v) => v ? parseInt(v) : 50),
|
|
779
|
+
offset: zod.z.string().optional().transform((v) => v ? parseInt(v) : 0),
|
|
780
|
+
type: zod.z.enum(["charge", "consume"]).optional(),
|
|
781
|
+
startDate: zod.z.string().datetime().optional(),
|
|
782
|
+
endDate: zod.z.string().datetime().optional()
|
|
783
|
+
});
|
|
784
|
+
const ListTransactionsResponseSchema = zod.z.object({
|
|
785
|
+
transactions: zod.z.array(TransactionSchema),
|
|
786
|
+
total: zod.z.number().int().nonnegative()
|
|
787
|
+
});
|
|
788
|
+
const TaskTransactionsResponseSchema = zod.z.object({
|
|
789
|
+
transactions: zod.z.array(ConsumeTransactionSchema),
|
|
790
|
+
total: zod.z.number().int().nonnegative()
|
|
791
|
+
});
|
|
792
|
+
const StatsQuerySchema = zod.z.object({
|
|
793
|
+
startDate: zod.z.string().datetime().optional(),
|
|
794
|
+
endDate: zod.z.string().datetime().optional()
|
|
795
|
+
});
|
|
796
|
+
const BillingStatsResponseSchema = zod.z.object({
|
|
797
|
+
totalCharged: zod.z.number().nonnegative(),
|
|
798
|
+
totalConsumed: zod.z.number().nonnegative(),
|
|
799
|
+
chargeCount: zod.z.number().int().nonnegative(),
|
|
800
|
+
consumeCount: zod.z.number().int().nonnegative(),
|
|
801
|
+
transactionCount: zod.z.number().int().nonnegative()
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
const EventBaseSchema = zod.z.object({
|
|
805
|
+
eventId: zod.z.string()
|
|
806
|
+
});
|
|
807
|
+
const createEventId = () => {
|
|
808
|
+
return `event-${crypto.randomUUID()}`;
|
|
809
|
+
};
|
|
810
|
+
const EventAckSchema = EventBaseSchema.extend({
|
|
811
|
+
status: zod.z.enum(["success", "failed"]),
|
|
812
|
+
message: zod.z.string().optional(),
|
|
813
|
+
opCode: zod.z.string().optional(),
|
|
814
|
+
data: zod.z.any().optional()
|
|
815
|
+
});
|
|
816
|
+
const AppAliveEventSchema = EventBaseSchema.extend({
|
|
817
|
+
timestamp: zod.z.string()
|
|
818
|
+
});
|
|
819
|
+
const ApiServerAliveEventSchema = EventBaseSchema.extend({
|
|
820
|
+
timestamp: zod.z.string()
|
|
821
|
+
});
|
|
822
|
+
const MachineAliveEventSchema = EventBaseSchema.extend({
|
|
823
|
+
machineId: zod.z.string(),
|
|
824
|
+
timestamp: zod.z.string()
|
|
825
|
+
});
|
|
826
|
+
const ShutdownMachineSchema = EventBaseSchema.extend({
|
|
827
|
+
machineId: zod.z.string(),
|
|
828
|
+
reason: zod.z.string().optional()
|
|
829
|
+
});
|
|
830
|
+
const WorkerInitializingSchema = EventBaseSchema.extend({
|
|
831
|
+
taskId: zod.z.string(),
|
|
832
|
+
machineId: zod.z.string(),
|
|
833
|
+
timestamp: zod.z.string()
|
|
834
|
+
});
|
|
835
|
+
const WorkerReadySchema = EventBaseSchema.extend({
|
|
836
|
+
taskId: zod.z.string(),
|
|
837
|
+
machineId: zod.z.string(),
|
|
838
|
+
timestamp: zod.z.string()
|
|
839
|
+
});
|
|
840
|
+
const WorkerAliveEventSchema = EventBaseSchema.extend({
|
|
841
|
+
taskId: zod.z.string(),
|
|
842
|
+
machineId: zod.z.string(),
|
|
843
|
+
status: zod.z.string(),
|
|
844
|
+
// running, ready
|
|
845
|
+
timestamp: zod.z.string()
|
|
846
|
+
});
|
|
847
|
+
const WorkerExitSchema = EventBaseSchema.extend({
|
|
848
|
+
taskId: zod.z.string(),
|
|
849
|
+
machineId: zod.z.string(),
|
|
850
|
+
timestamp: zod.z.string(),
|
|
851
|
+
reason: zod.z.string().optional()
|
|
852
|
+
});
|
|
853
|
+
const WorkerRunningSchema = EventBaseSchema.extend({
|
|
854
|
+
taskId: zod.z.string(),
|
|
855
|
+
machineId: zod.z.string(),
|
|
856
|
+
timestamp: zod.z.string()
|
|
857
|
+
});
|
|
858
|
+
const baseTaskSchema = EventBaseSchema.extend({
|
|
859
|
+
taskId: zod.z.string(),
|
|
860
|
+
userId: zod.z.string(),
|
|
861
|
+
chatId: zod.z.string(),
|
|
862
|
+
agentId: zod.z.string(),
|
|
863
|
+
agentType: zod.z.string().optional().default("claude"),
|
|
864
|
+
gitUrl: zod.z.string().optional(),
|
|
865
|
+
baseBranch: zod.z.string().optional(),
|
|
866
|
+
cwd: zod.z.string().optional(),
|
|
867
|
+
// Current working directory for the task, only used under 'local' mode
|
|
868
|
+
dataEncryptionKey: zod.z.string().optional(),
|
|
869
|
+
// User's public key for encrypting sensitive data
|
|
870
|
+
model: zod.z.string().optional(),
|
|
871
|
+
// AI model to use
|
|
872
|
+
fallbackModel: zod.z.string().optional(),
|
|
873
|
+
// Fallback AI model
|
|
874
|
+
api_base_url: zod.z.string().optional(),
|
|
875
|
+
// Custom API base URL
|
|
876
|
+
api_key: zod.z.string().optional(),
|
|
877
|
+
// Custom API key
|
|
878
|
+
maxTurns: zod.z.number().optional()
|
|
879
|
+
// Maximum number of turns for the agent (default: 50)
|
|
880
|
+
});
|
|
881
|
+
const createTaskSchema = baseTaskSchema.extend({
|
|
882
|
+
message: zod.z.custom(
|
|
883
|
+
(data) => {
|
|
884
|
+
return typeof data === "object" && data !== null && "type" in data;
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
message: "Invalid SDKMessage format"
|
|
888
|
+
}
|
|
889
|
+
).optional(),
|
|
890
|
+
encryptedMessage: zod.z.string().optional()
|
|
891
|
+
// base64 sealed-box payload for local machines
|
|
892
|
+
}).refine(
|
|
893
|
+
(data) => {
|
|
894
|
+
return !!data.message !== !!data.encryptedMessage;
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
message: "Exactly one of message or encryptedMessage must be provided"
|
|
898
|
+
}
|
|
899
|
+
);
|
|
900
|
+
const resumeTaskSchema = baseTaskSchema.extend({
|
|
901
|
+
agentSessionId: zod.z.string(),
|
|
902
|
+
event: zod.z.string().optional(),
|
|
903
|
+
eventData: zod.z.any().optional(),
|
|
904
|
+
message: zod.z.custom(
|
|
905
|
+
(data) => {
|
|
906
|
+
return typeof data === "object" && data !== null && "type" in data;
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
message: "Invalid SDKMessage format"
|
|
910
|
+
}
|
|
911
|
+
).optional(),
|
|
912
|
+
encryptedMessage: zod.z.string().optional()
|
|
913
|
+
// base64 sealed-box for local tasks
|
|
914
|
+
});
|
|
915
|
+
const cancelTaskSchema = EventBaseSchema.extend({
|
|
916
|
+
taskId: zod.z.string(),
|
|
917
|
+
userId: zod.z.string(),
|
|
918
|
+
chatId: zod.z.string(),
|
|
919
|
+
agentId: zod.z.string(),
|
|
920
|
+
reason: zod.z.string().optional()
|
|
921
|
+
});
|
|
922
|
+
const StopTaskSchema = EventBaseSchema.extend({
|
|
923
|
+
taskId: zod.z.string(),
|
|
924
|
+
reason: zod.z.string().optional()
|
|
925
|
+
});
|
|
926
|
+
const TaskMessageSchema = EventBaseSchema.extend({
|
|
927
|
+
taskId: zod.z.string(),
|
|
928
|
+
from: zod.z.enum(["app", "api-server", "machine", "worker"]),
|
|
929
|
+
message: zod.z.custom(
|
|
930
|
+
(data) => {
|
|
931
|
+
return typeof data === "object" && data !== null && "type" in data;
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
message: "Invalid SDKMessage format"
|
|
935
|
+
}
|
|
936
|
+
).optional(),
|
|
937
|
+
encryptedMessage: zod.z.string().optional()
|
|
938
|
+
// base64 sealed-box payload (local mode)
|
|
939
|
+
}).refine(
|
|
940
|
+
(data) => {
|
|
941
|
+
return !!data.message !== !!data.encryptedMessage;
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
message: "Exactly one of message or encryptedMessage must be provided"
|
|
945
|
+
}
|
|
946
|
+
);
|
|
947
|
+
const RequirePermissionSchema = EventBaseSchema.extend({
|
|
948
|
+
taskId: zod.z.string(),
|
|
949
|
+
toolName: zod.z.string(),
|
|
950
|
+
toolInput: zod.z.record(zod.z.unknown())
|
|
951
|
+
});
|
|
952
|
+
const RequirePermissionResponseSchema = EventBaseSchema.extend({
|
|
953
|
+
taskId: zod.z.string(),
|
|
954
|
+
opCode: zod.z.string(),
|
|
955
|
+
// Echoed back, equals to eventId in RequirePermissionRequest
|
|
956
|
+
behavior: zod.z.enum(["allow", "deny"]),
|
|
957
|
+
message: zod.z.string().optional()
|
|
958
|
+
});
|
|
959
|
+
const TaskArtifactsUpdatedEventSchema = EventBaseSchema.extend({
|
|
960
|
+
taskId: zod.z.string(),
|
|
961
|
+
commitHash: zod.z.string(),
|
|
962
|
+
timestamp: zod.z.string(),
|
|
963
|
+
stats: zod.z.object({
|
|
964
|
+
totalInsertions: zod.z.number(),
|
|
965
|
+
totalDeletions: zod.z.number(),
|
|
966
|
+
files: zod.z.array(FileStatsSchema)
|
|
967
|
+
})
|
|
968
|
+
});
|
|
969
|
+
const ChangeTaskTitleEventSchema = EventBaseSchema.extend({
|
|
970
|
+
taskId: zod.z.string(),
|
|
971
|
+
title: zod.z.string()
|
|
972
|
+
});
|
|
973
|
+
const CreditExhaustedEventSchema = EventBaseSchema.extend({});
|
|
974
|
+
const WorkspaceFileRequestSchema = EventBaseSchema.extend({
|
|
975
|
+
taskId: zod.z.string(),
|
|
976
|
+
userId: zod.z.string(),
|
|
977
|
+
// User ID for workspace path resolution
|
|
978
|
+
relativePath: zod.z.string(),
|
|
979
|
+
// Relative path from workspace root (e.g., 'data/patch.diff', 'project/src/index.ts')
|
|
980
|
+
requestId: zod.z.string(),
|
|
981
|
+
// UUID for correlating request-response
|
|
982
|
+
maxFileSizeMB: zod.z.number().optional(),
|
|
983
|
+
// Maximum file size in MB (set by API, default: 10)
|
|
984
|
+
ifModifiedSince: zod.z.string().optional(),
|
|
985
|
+
// ISO timestamp for cache validation
|
|
986
|
+
dataEncryptionKey: zod.z.string().optional()
|
|
987
|
+
// Encrypted data encryption key (for local mode)
|
|
988
|
+
});
|
|
989
|
+
const WorkspaceFileResponseSchema = EventBaseSchema.extend({
|
|
990
|
+
requestId: zod.z.string(),
|
|
991
|
+
// Corresponds to request's requestId
|
|
992
|
+
taskId: zod.z.string(),
|
|
993
|
+
success: zod.z.boolean(),
|
|
994
|
+
notModified: zod.z.boolean().optional(),
|
|
995
|
+
// True if file hasn't changed since ifModifiedSince
|
|
996
|
+
// Success response
|
|
997
|
+
data: zod.z.object({
|
|
998
|
+
type: zod.z.enum(["file", "directory"]),
|
|
999
|
+
content: zod.z.string().optional(),
|
|
1000
|
+
// File content (base64 encoded) - plaintext
|
|
1001
|
+
encryptedContent: zod.z.string().optional(),
|
|
1002
|
+
// File content (encrypted) - for local mode with dataEncryptionKey
|
|
1003
|
+
entries: zod.z.array(zod.z.object({
|
|
1004
|
+
name: zod.z.string(),
|
|
1005
|
+
type: zod.z.enum(["file", "directory"]),
|
|
1006
|
+
size: zod.z.number(),
|
|
1007
|
+
modifiedAt: zod.z.string(),
|
|
1008
|
+
accessDenied: zod.z.boolean().optional()
|
|
1009
|
+
// Exceeds size limit
|
|
1010
|
+
})).optional(),
|
|
1011
|
+
// Directory listing
|
|
1012
|
+
metadata: zod.z.object({
|
|
1013
|
+
size: zod.z.number(),
|
|
1014
|
+
mimeType: zod.z.string().optional(),
|
|
1015
|
+
modifiedAt: zod.z.string(),
|
|
1016
|
+
accessDenied: zod.z.boolean().optional()
|
|
1017
|
+
// Exceeds size limit
|
|
1018
|
+
})
|
|
1019
|
+
}).optional(),
|
|
1020
|
+
// Error response
|
|
1021
|
+
error: zod.z.object({
|
|
1022
|
+
code: zod.z.string(),
|
|
1023
|
+
// 'file_not_found' | 'permission_denied' | 'file_too_large' | 'timeout' | 'machine_offline'
|
|
1024
|
+
message: zod.z.string()
|
|
1025
|
+
}).optional()
|
|
1026
|
+
});
|
|
1027
|
+
const UpdateTaskAgentSessionIdEventSchema = EventBaseSchema.extend({
|
|
1028
|
+
taskId: zod.z.string(),
|
|
1029
|
+
agentSessionId: zod.z.string()
|
|
1030
|
+
});
|
|
1031
|
+
const MergeRequestEventSchema = EventBaseSchema.extend({
|
|
1032
|
+
taskId: zod.z.string(),
|
|
1033
|
+
summary: zod.z.string(),
|
|
1034
|
+
description: zod.z.string().optional()
|
|
1035
|
+
});
|
|
1036
|
+
const IdOnlySchema = zod.z.object({
|
|
1037
|
+
id: zod.z.string()
|
|
1038
|
+
});
|
|
1039
|
+
const PrStateChangedSchema = zod.z.object({
|
|
1040
|
+
taskId: zod.z.string(),
|
|
1041
|
+
pullRequestNumber: zod.z.number(),
|
|
1042
|
+
pullRequestUrl: zod.z.string(),
|
|
1043
|
+
oldState: zod.z.enum(["open", "closed", "merged"]).nullable(),
|
|
1044
|
+
newState: zod.z.enum(["open", "closed", "merged"]),
|
|
1045
|
+
changedAt: zod.z.string()
|
|
1046
|
+
// ISO 8601 string
|
|
1047
|
+
});
|
|
1048
|
+
const SystemMessageSchema = EventBaseSchema.extend({
|
|
1049
|
+
type: zod.z.enum([
|
|
1050
|
+
"machine-online",
|
|
1051
|
+
"machine-offline",
|
|
1052
|
+
"chat-added",
|
|
1053
|
+
"chat-removed",
|
|
1054
|
+
"chat-member-added",
|
|
1055
|
+
"chat-member-removed",
|
|
1056
|
+
"repo-added",
|
|
1057
|
+
"repo-removed",
|
|
1058
|
+
"pr-state-changed"
|
|
1059
|
+
]),
|
|
1060
|
+
data: zod.z.union([
|
|
1061
|
+
IdOnlySchema,
|
|
1062
|
+
// machine-online, machine-offline, chat-removed, repo-removed
|
|
1063
|
+
ChatSchema,
|
|
1064
|
+
// chat-added
|
|
1065
|
+
zod.z.array(ChatMemberSchema),
|
|
1066
|
+
// chat-member-added (array)
|
|
1067
|
+
zod.z.array(IdOnlySchema),
|
|
1068
|
+
// chat-member-removed (array)
|
|
1069
|
+
RepositorySchema,
|
|
1070
|
+
// repo-added
|
|
1071
|
+
PrStateChangedSchema
|
|
1072
|
+
// pr-state-changed
|
|
1073
|
+
]),
|
|
1074
|
+
timestamp: zod.z.string()
|
|
1075
|
+
});
|
|
1076
|
+
const EventSchemaMap = {
|
|
1077
|
+
// App events
|
|
1078
|
+
"app-alive": AppAliveEventSchema,
|
|
1079
|
+
"api-server-alive": ApiServerAliveEventSchema,
|
|
1080
|
+
// Machine events
|
|
1081
|
+
"machine-alive": MachineAliveEventSchema,
|
|
1082
|
+
// Worker events
|
|
1083
|
+
"worker-initializing": WorkerInitializingSchema,
|
|
1084
|
+
"worker-ready": WorkerReadySchema,
|
|
1085
|
+
"worker-alive": WorkerAliveEventSchema,
|
|
1086
|
+
"worker-exit": WorkerExitSchema,
|
|
1087
|
+
"worker-running": WorkerRunningSchema,
|
|
1088
|
+
// Task events
|
|
1089
|
+
"create-task": createTaskSchema,
|
|
1090
|
+
"resume-task": resumeTaskSchema,
|
|
1091
|
+
"cancel-task": cancelTaskSchema,
|
|
1092
|
+
"stop-task": StopTaskSchema,
|
|
1093
|
+
"task-message": TaskMessageSchema,
|
|
1094
|
+
"change-task-title": ChangeTaskTitleEventSchema,
|
|
1095
|
+
"update-task-agent-session-id": UpdateTaskAgentSessionIdEventSchema,
|
|
1096
|
+
// Artifacts events
|
|
1097
|
+
"task-artifacts-updated": TaskArtifactsUpdatedEventSchema,
|
|
1098
|
+
// Permission events
|
|
1099
|
+
"require-permission": RequirePermissionSchema,
|
|
1100
|
+
"require-permission-response": RequirePermissionResponseSchema,
|
|
1101
|
+
// Git operation events
|
|
1102
|
+
// Merge request events
|
|
1103
|
+
"merge-request": MergeRequestEventSchema,
|
|
1104
|
+
// System message events
|
|
1105
|
+
"system-message": SystemMessageSchema,
|
|
1106
|
+
// Billing events
|
|
1107
|
+
"credit-exhausted": CreditExhaustedEventSchema,
|
|
1108
|
+
// Workspace file events
|
|
1109
|
+
"workspace-file-request": WorkspaceFileRequestSchema,
|
|
1110
|
+
"workspace-file-response": WorkspaceFileResponseSchema,
|
|
1111
|
+
// Ack events
|
|
1112
|
+
"event-ack": EventAckSchema
|
|
1113
|
+
};
|
|
1114
|
+
const workerTaskEvents = [
|
|
1115
|
+
"worker-initializing",
|
|
1116
|
+
"worker-ready",
|
|
1117
|
+
"worker-running",
|
|
1118
|
+
"worker-exit",
|
|
1119
|
+
"change-task-title",
|
|
1120
|
+
"update-task-agent-session-id",
|
|
1121
|
+
"task-artifacts-updated",
|
|
1122
|
+
"require-permission",
|
|
1123
|
+
"merge-request"
|
|
1124
|
+
];
|
|
1125
|
+
|
|
1126
|
+
function userAuth(token) {
|
|
1127
|
+
return {
|
|
1128
|
+
token,
|
|
1129
|
+
clientType: "user"
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function machineAuth(token, machineId) {
|
|
1133
|
+
return {
|
|
1134
|
+
token,
|
|
1135
|
+
clientType: "machine",
|
|
1136
|
+
machineId
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
function workerAuth(token, machineId, taskId) {
|
|
1140
|
+
return {
|
|
1141
|
+
token,
|
|
1142
|
+
clientType: "worker",
|
|
1143
|
+
machineId,
|
|
1144
|
+
taskId
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
let agentContext = null;
|
|
1149
|
+
function setAgentContext(context) {
|
|
1150
|
+
agentContext = context;
|
|
1151
|
+
}
|
|
1152
|
+
function getAgentContext() {
|
|
1153
|
+
if (!agentContext) {
|
|
1154
|
+
throw new Error("Agent context not initialized. Call setAgentContext() first.");
|
|
1155
|
+
}
|
|
1156
|
+
return agentContext;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
const FRAMEWORK_TYPES = ["claude", "codex"];
|
|
1160
|
+
|
|
1161
|
+
const AgentMetadataSchema = zod.z.object({
|
|
1162
|
+
name: zod.z.string(),
|
|
1163
|
+
version: zod.z.string(),
|
|
1164
|
+
description: zod.z.string().optional()
|
|
1165
|
+
});
|
|
1166
|
+
const MCPServerConfigSchema = zod.z.object({
|
|
1167
|
+
name: zod.z.string(),
|
|
1168
|
+
command: zod.z.string().optional(),
|
|
1169
|
+
args: zod.z.array(zod.z.string()).optional(),
|
|
1170
|
+
env: zod.z.record(zod.z.string()).optional(),
|
|
1171
|
+
url: zod.z.string().url().optional(),
|
|
1172
|
+
transport: zod.z.enum(["stdio", "http"]).optional()
|
|
1173
|
+
});
|
|
1174
|
+
const SkillConfigSchema = zod.z.object({
|
|
1175
|
+
name: zod.z.string(),
|
|
1176
|
+
description: zod.z.string().optional(),
|
|
1177
|
+
enabled: zod.z.boolean(),
|
|
1178
|
+
implementation: zod.z.string().optional()
|
|
1179
|
+
});
|
|
1180
|
+
const ClaudeConfigSchema = zod.z.object({
|
|
1181
|
+
// SDK native model configuration
|
|
1182
|
+
model: zod.z.string().optional(),
|
|
1183
|
+
fallbackModel: zod.z.string().optional(),
|
|
1184
|
+
maxTurns: zod.z.number().int().positive().optional(),
|
|
1185
|
+
// SDK native extra arguments
|
|
1186
|
+
extraArgs: zod.z.record(zod.z.string().nullable()).optional(),
|
|
1187
|
+
systemPrompt: zod.z.object({
|
|
1188
|
+
path: zod.z.string(),
|
|
1189
|
+
mode: zod.z.enum(["append", "replace"]).optional().default("append")
|
|
1190
|
+
}).optional(),
|
|
1191
|
+
settings: zod.z.object({
|
|
1192
|
+
permissionMode: zod.z.enum(["default", "acceptEdits", "bypassPermissions", "plan"]).optional(),
|
|
1193
|
+
allowedTools: zod.z.array(zod.z.string()).optional()
|
|
1194
|
+
}).optional(),
|
|
1195
|
+
mcpServers: zod.z.object({
|
|
1196
|
+
enabled: zod.z.array(zod.z.string()),
|
|
1197
|
+
directory: zod.z.string()
|
|
1198
|
+
}).optional(),
|
|
1199
|
+
skills: zod.z.object({
|
|
1200
|
+
enabled: zod.z.array(zod.z.string()),
|
|
1201
|
+
directory: zod.z.string()
|
|
1202
|
+
}).optional()
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
class AgentError extends Error {
|
|
1206
|
+
constructor(message) {
|
|
1207
|
+
super(message);
|
|
1208
|
+
this.name = "AgentError";
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
class AgentNotFoundError extends AgentError {
|
|
1212
|
+
constructor(agentId) {
|
|
1213
|
+
super(`Agent not found: ${agentId}`);
|
|
1214
|
+
this.name = "AgentNotFoundError";
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
class AgentConfigValidationError extends AgentError {
|
|
1218
|
+
constructor(message, errors) {
|
|
1219
|
+
super(message);
|
|
1220
|
+
this.errors = errors;
|
|
1221
|
+
this.name = "AgentConfigValidationError";
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
class FrameworkNotSupportedError extends AgentError {
|
|
1225
|
+
constructor(agentId, framework) {
|
|
1226
|
+
super(`Agent "${agentId}" does not support framework: ${framework}`);
|
|
1227
|
+
this.name = "FrameworkNotSupportedError";
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
class AgentLoadError extends AgentError {
|
|
1231
|
+
constructor(message, cause) {
|
|
1232
|
+
super(message);
|
|
1233
|
+
this.cause = cause;
|
|
1234
|
+
this.name = "AgentLoadError";
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
class MissingAgentFileError extends AgentError {
|
|
1238
|
+
constructor(filePath) {
|
|
1239
|
+
super(`Required agent file missing: ${filePath}`);
|
|
1240
|
+
this.name = "MissingAgentFileError";
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
function validateAgentDirectory(agentDir) {
|
|
1245
|
+
const errors = [];
|
|
1246
|
+
const warnings = [];
|
|
1247
|
+
if (!node_fs.existsSync(agentDir)) {
|
|
1248
|
+
errors.push(`Agent directory does not exist: ${agentDir}`);
|
|
1249
|
+
return { valid: false, errors, warnings };
|
|
1250
|
+
}
|
|
1251
|
+
if (!node_fs.statSync(agentDir).isDirectory()) {
|
|
1252
|
+
errors.push(`Path is not a directory: ${agentDir}`);
|
|
1253
|
+
return { valid: false, errors, warnings };
|
|
1254
|
+
}
|
|
1255
|
+
const agentJsonPath = node_path.join(agentDir, "agent.json");
|
|
1256
|
+
if (!node_fs.existsSync(agentJsonPath)) {
|
|
1257
|
+
errors.push("Missing required file: agent.json");
|
|
1258
|
+
}
|
|
1259
|
+
const readmePath = node_path.join(agentDir, "README.md");
|
|
1260
|
+
if (!node_fs.existsSync(readmePath)) {
|
|
1261
|
+
warnings.push("Missing README.md (recommended)");
|
|
1262
|
+
}
|
|
1263
|
+
return {
|
|
1264
|
+
valid: errors.length === 0,
|
|
1265
|
+
errors,
|
|
1266
|
+
warnings
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
function validateFrameworkDirectory(frameworkDir, framework) {
|
|
1270
|
+
const errors = [];
|
|
1271
|
+
const warnings = [];
|
|
1272
|
+
if (!node_fs.existsSync(frameworkDir)) {
|
|
1273
|
+
errors.push(`Framework directory does not exist: ${frameworkDir}`);
|
|
1274
|
+
return { valid: false, errors, warnings };
|
|
1275
|
+
}
|
|
1276
|
+
const configPath = node_path.join(frameworkDir, "config.json");
|
|
1277
|
+
if (!node_fs.existsSync(configPath)) {
|
|
1278
|
+
errors.push(`Missing required file: ${framework}/config.json`);
|
|
1279
|
+
}
|
|
1280
|
+
if (framework === "claude") {
|
|
1281
|
+
const mcpServersDir = node_path.join(frameworkDir, "mcp-servers");
|
|
1282
|
+
if (!node_fs.existsSync(mcpServersDir)) {
|
|
1283
|
+
warnings.push("Missing mcp-servers directory (optional)");
|
|
1284
|
+
}
|
|
1285
|
+
const skillsDir = node_path.join(frameworkDir, "skills");
|
|
1286
|
+
if (!node_fs.existsSync(skillsDir)) {
|
|
1287
|
+
warnings.push("Missing skills directory (optional)");
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
valid: errors.length === 0,
|
|
1292
|
+
errors,
|
|
1293
|
+
warnings
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
function assertFileExists(filePath, description) {
|
|
1297
|
+
if (!node_fs.existsSync(filePath)) {
|
|
1298
|
+
throw new MissingAgentFileError(description || filePath);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
function assertAgentExists(agentDir, agentId) {
|
|
1302
|
+
if (!node_fs.existsSync(agentDir)) {
|
|
1303
|
+
throw new AgentNotFoundError(agentId);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
async function loadMcpServers(mcpServersDir, enabledServers) {
|
|
1308
|
+
const loaded = {};
|
|
1309
|
+
if (!node_fs.existsSync(mcpServersDir)) {
|
|
1310
|
+
return loaded;
|
|
1311
|
+
}
|
|
1312
|
+
const serverDirs = node_fs.readdirSync(mcpServersDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1313
|
+
for (const serverName of enabledServers) {
|
|
1314
|
+
if (!serverDirs.includes(serverName)) {
|
|
1315
|
+
throw new AgentLoadError(
|
|
1316
|
+
`MCP server "${serverName}" is enabled but directory not found`
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
const serverDir = node_path.join(mcpServersDir, serverName);
|
|
1320
|
+
try {
|
|
1321
|
+
const config = await loadMcpServerConfig(serverDir, serverName);
|
|
1322
|
+
const instance = await createMcpServerInstance(config);
|
|
1323
|
+
loaded[serverName] = {
|
|
1324
|
+
name: serverName,
|
|
1325
|
+
config,
|
|
1326
|
+
instance
|
|
1327
|
+
};
|
|
1328
|
+
} catch (error) {
|
|
1329
|
+
throw new AgentLoadError(
|
|
1330
|
+
`Failed to load MCP server "${serverName}": ${error instanceof Error ? error.message : String(error)}`,
|
|
1331
|
+
error instanceof Error ? error : void 0
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
return loaded;
|
|
1336
|
+
}
|
|
1337
|
+
async function loadMcpServerConfig(serverDir, serverName) {
|
|
1338
|
+
const configPath = node_path.join(serverDir, "config.json");
|
|
1339
|
+
if (!node_fs.existsSync(configPath)) {
|
|
1340
|
+
throw new AgentLoadError(`MCP server "${serverName}" missing config.json`);
|
|
1341
|
+
}
|
|
1342
|
+
try {
|
|
1343
|
+
const content = node_fs.readFileSync(configPath, "utf-8");
|
|
1344
|
+
const rawConfig = JSON.parse(content);
|
|
1345
|
+
const validatedConfig = MCPServerConfigSchema.parse(rawConfig);
|
|
1346
|
+
return validatedConfig;
|
|
1347
|
+
} catch (error) {
|
|
1348
|
+
if (error instanceof SyntaxError) {
|
|
1349
|
+
throw new AgentConfigValidationError(
|
|
1350
|
+
`Invalid JSON in MCP server config: ${serverName}`
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
throw new AgentConfigValidationError(
|
|
1354
|
+
`Invalid MCP server configuration for "${serverName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
async function createMcpServerInstance(config) {
|
|
1359
|
+
if (config.transport === "stdio" && config.command) {
|
|
1360
|
+
throw new AgentLoadError(
|
|
1361
|
+
"stdio transport for MCP servers not yet implemented. Use inline MCP servers for now."
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
if (config.transport === "http" && config.url) {
|
|
1365
|
+
throw new AgentLoadError(
|
|
1366
|
+
"HTTP transport for MCP servers not yet implemented"
|
|
1367
|
+
);
|
|
1368
|
+
}
|
|
1369
|
+
throw new AgentLoadError(
|
|
1370
|
+
`Cannot create MCP server instance: unsupported configuration for "${config.name}"`
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
async function loadAgentConfig(options) {
|
|
1375
|
+
const { agentId, framework, validateOnly = false } = options;
|
|
1376
|
+
const agentContext = getAgentContext();
|
|
1377
|
+
const agentDir = agentContext.resolveAgentDir(agentId);
|
|
1378
|
+
assertAgentExists(agentDir, agentId);
|
|
1379
|
+
const validation = validateAgentDirectory(agentDir);
|
|
1380
|
+
if (!validation.valid) {
|
|
1381
|
+
throw new AgentConfigValidationError(
|
|
1382
|
+
`Agent directory validation failed for "${agentId}"`,
|
|
1383
|
+
validation.errors
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
if (validation.warnings.length > 0) {
|
|
1387
|
+
console.warn(`[AGENT] Warnings for agent "${agentId}":`, validation.warnings);
|
|
1388
|
+
}
|
|
1389
|
+
const metadata = await loadAgentMetadata(agentDir);
|
|
1390
|
+
const frameworkDir = node_path.join(agentDir, `.${framework}`);
|
|
1391
|
+
if (!node_fs.existsSync(frameworkDir)) {
|
|
1392
|
+
throw new FrameworkNotSupportedError(agentId, framework);
|
|
1393
|
+
}
|
|
1394
|
+
if (validateOnly) {
|
|
1395
|
+
return {
|
|
1396
|
+
metadata,
|
|
1397
|
+
framework
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
if (framework === "claude") {
|
|
1401
|
+
const claudeConfig = await loadClaudeConfiguration(agentDir);
|
|
1402
|
+
return {
|
|
1403
|
+
metadata,
|
|
1404
|
+
framework,
|
|
1405
|
+
claude: claudeConfig
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
throw new AgentLoadError(`Framework "${framework}" loader not implemented`);
|
|
1409
|
+
}
|
|
1410
|
+
async function loadAgentMetadata(agentDir) {
|
|
1411
|
+
const agentJsonPath = node_path.join(agentDir, "agent.json");
|
|
1412
|
+
assertFileExists(agentJsonPath, "agent.json");
|
|
1413
|
+
try {
|
|
1414
|
+
const content = node_fs.readFileSync(agentJsonPath, "utf-8");
|
|
1415
|
+
const rawData = JSON.parse(content);
|
|
1416
|
+
const metadata = AgentMetadataSchema.parse(rawData);
|
|
1417
|
+
return metadata;
|
|
1418
|
+
} catch (error) {
|
|
1419
|
+
if (error instanceof SyntaxError) {
|
|
1420
|
+
throw new AgentConfigValidationError("Invalid JSON in agent.json");
|
|
1421
|
+
}
|
|
1422
|
+
throw new AgentConfigValidationError(
|
|
1423
|
+
`Invalid agent metadata: ${error instanceof Error ? error.message : String(error)}`
|
|
1424
|
+
);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
async function loadClaudeConfiguration(agentDir, metadata) {
|
|
1428
|
+
const claudeDir = node_path.join(agentDir, ".claude");
|
|
1429
|
+
const validation = validateFrameworkDirectory(claudeDir, "claude");
|
|
1430
|
+
if (!validation.valid) {
|
|
1431
|
+
throw new AgentConfigValidationError(
|
|
1432
|
+
"Claude framework directory validation failed",
|
|
1433
|
+
validation.errors
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
const config = await loadClaudeConfig(claudeDir);
|
|
1437
|
+
let systemPrompt;
|
|
1438
|
+
if (config.systemPrompt) {
|
|
1439
|
+
systemPrompt = await loadSystemPrompt(claudeDir, config.systemPrompt.path);
|
|
1440
|
+
}
|
|
1441
|
+
const mcpServers = config.mcpServers ? await loadMcpServers(
|
|
1442
|
+
node_path.join(claudeDir, config.mcpServers.directory),
|
|
1443
|
+
config.mcpServers.enabled
|
|
1444
|
+
) : {};
|
|
1445
|
+
const skills = config.skills ? await loadSkills(
|
|
1446
|
+
node_path.join(claudeDir, config.skills.directory),
|
|
1447
|
+
config.skills.enabled
|
|
1448
|
+
) : [];
|
|
1449
|
+
return {
|
|
1450
|
+
config,
|
|
1451
|
+
systemPrompt,
|
|
1452
|
+
mcpServers,
|
|
1453
|
+
skills
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
async function loadClaudeConfig(claudeDir) {
|
|
1457
|
+
const configPath = node_path.join(claudeDir, "config.json");
|
|
1458
|
+
assertFileExists(configPath, ".claude/config.json");
|
|
1459
|
+
try {
|
|
1460
|
+
const content = node_fs.readFileSync(configPath, "utf-8");
|
|
1461
|
+
const rawConfig = JSON.parse(content);
|
|
1462
|
+
const config = ClaudeConfigSchema.parse(rawConfig);
|
|
1463
|
+
return config;
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
if (error instanceof SyntaxError) {
|
|
1466
|
+
throw new AgentConfigValidationError(
|
|
1467
|
+
"Invalid JSON in .claude/config.json"
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
throw new AgentConfigValidationError(
|
|
1471
|
+
`Invalid Claude configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
1472
|
+
);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
async function loadSystemPrompt(claudeDir, promptFile) {
|
|
1476
|
+
const promptPath = node_path.join(claudeDir, promptFile);
|
|
1477
|
+
if (!node_fs.existsSync(promptPath)) {
|
|
1478
|
+
throw new MissingAgentFileError(`.claude/${promptFile}`);
|
|
1479
|
+
}
|
|
1480
|
+
try {
|
|
1481
|
+
return node_fs.readFileSync(promptPath, "utf-8");
|
|
1482
|
+
} catch (error) {
|
|
1483
|
+
throw new AgentLoadError(
|
|
1484
|
+
`Failed to read system prompt: ${error instanceof Error ? error.message : String(error)}`
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
async function loadSkills(skillsDir, enabledSkills) {
|
|
1489
|
+
const skills = [];
|
|
1490
|
+
if (!node_fs.existsSync(skillsDir)) {
|
|
1491
|
+
return skills;
|
|
1492
|
+
}
|
|
1493
|
+
const skillDirs = node_fs.readdirSync(skillsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1494
|
+
for (const skillName of enabledSkills) {
|
|
1495
|
+
if (!skillDirs.includes(skillName)) {
|
|
1496
|
+
throw new AgentLoadError(
|
|
1497
|
+
`Skill "${skillName}" is enabled but directory not found`
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
const skillDir = node_path.join(skillsDir, skillName);
|
|
1501
|
+
const skillConfigPath = node_path.join(skillDir, "skill.json");
|
|
1502
|
+
if (!node_fs.existsSync(skillConfigPath)) {
|
|
1503
|
+
throw new MissingAgentFileError(
|
|
1504
|
+
`skills/${skillName}/skill.json`
|
|
1505
|
+
);
|
|
1506
|
+
}
|
|
1507
|
+
try {
|
|
1508
|
+
const content = node_fs.readFileSync(skillConfigPath, "utf-8");
|
|
1509
|
+
const rawSkill = JSON.parse(content);
|
|
1510
|
+
const skill = SkillConfigSchema.parse(rawSkill);
|
|
1511
|
+
skills.push(skill);
|
|
1512
|
+
} catch (error) {
|
|
1513
|
+
if (error instanceof SyntaxError) {
|
|
1514
|
+
throw new AgentConfigValidationError(
|
|
1515
|
+
`Invalid JSON in skills/${skillName}/skill.json`
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
throw new AgentConfigValidationError(
|
|
1519
|
+
`Invalid skill configuration for "${skillName}": ${error instanceof Error ? error.message : String(error)}`
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
return skills;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
const cryptoModule = typeof globalThis.crypto !== "undefined" ? globalThis.crypto : (async () => {
|
|
1527
|
+
try {
|
|
1528
|
+
const nodeCrypto = await import('node:crypto');
|
|
1529
|
+
return nodeCrypto.webcrypto;
|
|
1530
|
+
} catch {
|
|
1531
|
+
throw new Error("Web Crypto API not available");
|
|
1532
|
+
}
|
|
1533
|
+
})();
|
|
1534
|
+
async function getCrypto() {
|
|
1535
|
+
if (typeof cryptoModule === "object" && cryptoModule !== null && "subtle" in cryptoModule) {
|
|
1536
|
+
return cryptoModule;
|
|
1537
|
+
}
|
|
1538
|
+
return await cryptoModule;
|
|
1539
|
+
}
|
|
1540
|
+
async function hmac_sha512(key, data) {
|
|
1541
|
+
const crypto = await getCrypto();
|
|
1542
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
1543
|
+
"raw",
|
|
1544
|
+
key,
|
|
1545
|
+
{ name: "HMAC", hash: "SHA-512" },
|
|
1546
|
+
false,
|
|
1547
|
+
["sign"]
|
|
1548
|
+
);
|
|
1549
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, data);
|
|
1550
|
+
return new Uint8Array(signature);
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
async function deriveSecretKeyTreeRoot(seed, usage) {
|
|
1554
|
+
const I = await hmac_sha512(new TextEncoder().encode(usage + " Master Seed"), seed);
|
|
1555
|
+
return {
|
|
1556
|
+
key: I.slice(0, 32),
|
|
1557
|
+
chainCode: I.slice(32)
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
async function deriveSecretKeyTreeChild(chainCode, index) {
|
|
1561
|
+
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
1562
|
+
const I = await hmac_sha512(chainCode, data);
|
|
1563
|
+
return {
|
|
1564
|
+
key: I.subarray(0, 32),
|
|
1565
|
+
chainCode: I.subarray(32)
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
async function deriveKey(master, usage, path) {
|
|
1569
|
+
let state = await deriveSecretKeyTreeRoot(master, usage);
|
|
1570
|
+
let remaining = [...path];
|
|
1571
|
+
while (remaining.length > 0) {
|
|
1572
|
+
let index = remaining[0];
|
|
1573
|
+
remaining = remaining.slice(1);
|
|
1574
|
+
state = await deriveSecretKeyTreeChild(state.chainCode, index);
|
|
1575
|
+
}
|
|
1576
|
+
return state.key;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
function encodeBase64(buffer, variant = "base64") {
|
|
1580
|
+
if (variant === "base64url") {
|
|
1581
|
+
return encodeBase64Url(buffer);
|
|
1582
|
+
}
|
|
1583
|
+
return base64js__namespace.fromByteArray(buffer);
|
|
1584
|
+
}
|
|
1585
|
+
function encodeBase64Url(buffer) {
|
|
1586
|
+
return base64js__namespace.fromByteArray(buffer).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
1587
|
+
}
|
|
1588
|
+
function decodeBase64(base64, variant = "base64") {
|
|
1589
|
+
if (!base64) {
|
|
1590
|
+
throw new Error("Invalid base64 input: must be a non-empty string");
|
|
1591
|
+
}
|
|
1592
|
+
const cleaned = base64.replace(/\s/g, "");
|
|
1593
|
+
if (!cleaned) {
|
|
1594
|
+
throw new Error("Invalid base64 input: empty after removing whitespace");
|
|
1595
|
+
}
|
|
1596
|
+
try {
|
|
1597
|
+
if (variant === "base64url") {
|
|
1598
|
+
let base64Standard = cleaned.replace(/-/g, "+").replace(/_/g, "/");
|
|
1599
|
+
const padding = (4 - base64Standard.length % 4) % 4;
|
|
1600
|
+
if (padding > 0) {
|
|
1601
|
+
base64Standard += "=".repeat(padding);
|
|
1602
|
+
}
|
|
1603
|
+
return base64js__namespace.toByteArray(base64Standard);
|
|
1604
|
+
}
|
|
1605
|
+
return base64js__namespace.toByteArray(cleaned);
|
|
1606
|
+
} catch (error) {
|
|
1607
|
+
throw new Error(`Failed to decode base64 (variant: ${variant}): ${error instanceof Error ? error.message : String(error)}`);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
function getRandomBytes(size) {
|
|
1611
|
+
return tweetnacl.randomBytes(size);
|
|
1612
|
+
}
|
|
1613
|
+
function generateAESKey() {
|
|
1614
|
+
return getRandomBytes(tweetnacl.secretbox.keyLength);
|
|
1615
|
+
}
|
|
1616
|
+
function generateAESKeyBase64(variant = "base64") {
|
|
1617
|
+
const key = generateAESKey();
|
|
1618
|
+
return encodeBase64(key, variant);
|
|
1619
|
+
}
|
|
1620
|
+
function encryptAES(data, dataKey) {
|
|
1621
|
+
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1622
|
+
throw new Error(`Invalid key length: expected ${tweetnacl.secretbox.keyLength}, got ${dataKey.length}`);
|
|
1623
|
+
}
|
|
1624
|
+
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
1625
|
+
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
1626
|
+
const encrypted = tweetnacl.secretbox(plaintext, nonce, dataKey);
|
|
1627
|
+
const bundle = new Uint8Array(1 + nonce.length + encrypted.length);
|
|
1628
|
+
bundle.set([0], 0);
|
|
1629
|
+
bundle.set(nonce, 1);
|
|
1630
|
+
bundle.set(encrypted, 1 + nonce.length);
|
|
1631
|
+
return bundle;
|
|
1632
|
+
}
|
|
1633
|
+
function decryptAES(bundle, dataKey) {
|
|
1634
|
+
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1635
|
+
return null;
|
|
1636
|
+
}
|
|
1637
|
+
if (bundle.length < 1) {
|
|
1638
|
+
return null;
|
|
1639
|
+
}
|
|
1640
|
+
if (bundle[0] !== 0) {
|
|
1641
|
+
return null;
|
|
1642
|
+
}
|
|
1643
|
+
const minLength = 1 + tweetnacl.secretbox.nonceLength + tweetnacl.secretbox.overheadLength;
|
|
1644
|
+
if (bundle.length < minLength) {
|
|
1645
|
+
return null;
|
|
1646
|
+
}
|
|
1647
|
+
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
1648
|
+
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
1649
|
+
try {
|
|
1650
|
+
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, dataKey);
|
|
1651
|
+
if (!decrypted) {
|
|
1652
|
+
return null;
|
|
1653
|
+
}
|
|
1654
|
+
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
1655
|
+
} catch (error) {
|
|
1656
|
+
return null;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
async function createKeyPairWithUit8Array(masterSecret) {
|
|
1660
|
+
const contentDataKey = await deriveKey(masterSecret, "Agentrix EnCoder", ["content"]);
|
|
1661
|
+
return tweetnacl.box.keyPair.fromSecretKey(contentDataKey);
|
|
1662
|
+
}
|
|
1663
|
+
async function createKeyPair(masterSecret, variant = "base64") {
|
|
1664
|
+
return await createKeyPairWithUit8Array(decodeBase64(masterSecret, variant));
|
|
1665
|
+
}
|
|
1666
|
+
function decryptWithEphemeralKey(encryptedBundle, secretKey) {
|
|
1667
|
+
const ephemeralPublicKey = encryptedBundle.slice(0, 32);
|
|
1668
|
+
const nonce = encryptedBundle.slice(32, 32 + tweetnacl.box.nonceLength);
|
|
1669
|
+
const encrypted = encryptedBundle.slice(32 + tweetnacl.box.nonceLength);
|
|
1670
|
+
const decrypted = tweetnacl.box.open(encrypted, nonce, ephemeralPublicKey, secretKey);
|
|
1671
|
+
if (!decrypted) {
|
|
1672
|
+
return null;
|
|
1673
|
+
}
|
|
1674
|
+
return decrypted;
|
|
1675
|
+
}
|
|
1676
|
+
function encryptWithEphemeralKey(data, publicKey) {
|
|
1677
|
+
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
1678
|
+
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
1679
|
+
const encrypted = tweetnacl.box(data, nonce, publicKey, ephemeralKeyPair.secretKey);
|
|
1680
|
+
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
1681
|
+
result.set(ephemeralKeyPair.publicKey, 0);
|
|
1682
|
+
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
1683
|
+
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
1684
|
+
return result;
|
|
1685
|
+
}
|
|
1686
|
+
function encryptSdkMessage(message, dataKey) {
|
|
1687
|
+
const encryptedWithVersion = encryptAES(message, dataKey);
|
|
1688
|
+
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
1689
|
+
return encodeBase64(encryptedWithoutVersion);
|
|
1690
|
+
}
|
|
1691
|
+
function decryptSdkMessage(encryptedMessage, dataKey) {
|
|
1692
|
+
try {
|
|
1693
|
+
const encryptedWithoutVersion = decodeBase64(encryptedMessage);
|
|
1694
|
+
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
1695
|
+
encryptedWithVersion.set([0], 0);
|
|
1696
|
+
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
1697
|
+
return decryptAES(encryptedWithVersion, dataKey);
|
|
1698
|
+
} catch (error) {
|
|
1699
|
+
return null;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
function encryptMachineEncryptionKey(machinePublicKey, aesKey, userPublicKey) {
|
|
1703
|
+
if (machinePublicKey.length !== 32) {
|
|
1704
|
+
throw new Error(`Invalid machine public key length: expected 32, got ${machinePublicKey.length}`);
|
|
1705
|
+
}
|
|
1706
|
+
if (aesKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1707
|
+
throw new Error(`Invalid AES key length: expected ${tweetnacl.secretbox.keyLength}, got ${aesKey.length}`);
|
|
1708
|
+
}
|
|
1709
|
+
if (userPublicKey.length !== 32) {
|
|
1710
|
+
throw new Error(`Invalid user public key length: expected 32, got ${userPublicKey.length}`);
|
|
1711
|
+
}
|
|
1712
|
+
const combined = new Uint8Array(machinePublicKey.length + aesKey.length);
|
|
1713
|
+
combined.set(machinePublicKey, 0);
|
|
1714
|
+
combined.set(aesKey, machinePublicKey.length);
|
|
1715
|
+
const encrypted = encryptWithEphemeralKey(combined, userPublicKey);
|
|
1716
|
+
return encodeBase64(encrypted);
|
|
1717
|
+
}
|
|
1718
|
+
function decryptMachineEncryptionKey(encryptedData, userPrivateKey) {
|
|
1719
|
+
if (userPrivateKey.length !== 32) {
|
|
1720
|
+
return null;
|
|
1721
|
+
}
|
|
1722
|
+
try {
|
|
1723
|
+
const encryptedBundle = decodeBase64(encryptedData);
|
|
1724
|
+
const decrypted = decryptWithEphemeralKey(encryptedBundle, userPrivateKey);
|
|
1725
|
+
if (!decrypted) {
|
|
1726
|
+
return null;
|
|
1727
|
+
}
|
|
1728
|
+
const expectedLength = 32 + tweetnacl.secretbox.keyLength;
|
|
1729
|
+
if (decrypted.length !== expectedLength) {
|
|
1730
|
+
return null;
|
|
1731
|
+
}
|
|
1732
|
+
const machinePublicKey = decrypted.slice(0, 32);
|
|
1733
|
+
const aesKey = decrypted.slice(32);
|
|
1734
|
+
return { machinePublicKey, aesKey };
|
|
1735
|
+
} catch (error) {
|
|
1736
|
+
return null;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
function encryptFileContent(fileContentBase64, dataKey) {
|
|
1740
|
+
const encryptedWithVersion = encryptAES(fileContentBase64, dataKey);
|
|
1741
|
+
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
1742
|
+
return encodeBase64(encryptedWithoutVersion);
|
|
1743
|
+
}
|
|
1744
|
+
function decryptFileContent(encryptedContent, dataKey) {
|
|
1745
|
+
try {
|
|
1746
|
+
const encryptedWithoutVersion = decodeBase64(encryptedContent);
|
|
1747
|
+
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
1748
|
+
encryptedWithVersion.set([0], 0);
|
|
1749
|
+
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
1750
|
+
return decryptAES(encryptedWithVersion, dataKey);
|
|
1751
|
+
} catch (error) {
|
|
1752
|
+
return null;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
exports.AddChatMemberRequestSchema = AddChatMemberRequestSchema;
|
|
1757
|
+
exports.AddChatMemberResponseSchema = AddChatMemberResponseSchema;
|
|
1758
|
+
exports.AgentConfigValidationError = AgentConfigValidationError;
|
|
1759
|
+
exports.AgentError = AgentError;
|
|
1760
|
+
exports.AgentLoadError = AgentLoadError;
|
|
1761
|
+
exports.AgentMetadataSchema = AgentMetadataSchema;
|
|
1762
|
+
exports.AgentNotFoundError = AgentNotFoundError;
|
|
1763
|
+
exports.AgentSchema = AgentSchema;
|
|
1764
|
+
exports.AgentTypeSchema = AgentTypeSchema;
|
|
1765
|
+
exports.ApiErrorSchema = ApiErrorSchema;
|
|
1766
|
+
exports.ApiServerAliveEventSchema = ApiServerAliveEventSchema;
|
|
1767
|
+
exports.AppAliveEventSchema = AppAliveEventSchema;
|
|
1768
|
+
exports.ApprovalStatusResponseSchema = ApprovalStatusResponseSchema;
|
|
1769
|
+
exports.BillingStatsResponseSchema = BillingStatsResponseSchema;
|
|
1770
|
+
exports.BranchSchema = BranchSchema;
|
|
1771
|
+
exports.CancelTaskRequestSchema = CancelTaskRequestSchema;
|
|
1772
|
+
exports.CancelTaskResponseSchema = CancelTaskResponseSchema;
|
|
1773
|
+
exports.ChangeTaskTitleEventSchema = ChangeTaskTitleEventSchema;
|
|
1774
|
+
exports.ChargeTransactionSchema = ChargeTransactionSchema;
|
|
1775
|
+
exports.ChatMemberInputSchema = ChatMemberInputSchema;
|
|
1776
|
+
exports.ChatMemberSchema = ChatMemberSchema;
|
|
1777
|
+
exports.ChatSchema = ChatSchema;
|
|
1778
|
+
exports.ChatTypeSchema = ChatTypeSchema;
|
|
1779
|
+
exports.ChatWithMembersSchema = ChatWithMembersSchema;
|
|
1780
|
+
exports.ClaudeConfigSchema = ClaudeConfigSchema;
|
|
1781
|
+
exports.CloudJoinApprovalRequestSchema = CloudJoinApprovalRequestSchema;
|
|
1782
|
+
exports.CloudJoinRequestSchema = CloudJoinRequestSchema;
|
|
1783
|
+
exports.CloudJoinResultQuerySchema = CloudJoinResultQuerySchema;
|
|
1784
|
+
exports.CloudJoinStatusQuerySchema = CloudJoinStatusQuerySchema;
|
|
1785
|
+
exports.CloudMachineSchema = CloudMachineSchema;
|
|
1786
|
+
exports.CloudSchema = CloudSchema;
|
|
1787
|
+
exports.ConfirmUploadRequestSchema = ConfirmUploadRequestSchema;
|
|
1788
|
+
exports.ConfirmUploadResponseSchema = ConfirmUploadResponseSchema;
|
|
1789
|
+
exports.ConsumeTransactionSchema = ConsumeTransactionSchema;
|
|
1790
|
+
exports.CreateAgentRequestSchema = CreateAgentRequestSchema;
|
|
1791
|
+
exports.CreateAgentResponseSchema = CreateAgentResponseSchema;
|
|
1792
|
+
exports.CreateChatRequestSchema = CreateChatRequestSchema;
|
|
1793
|
+
exports.CreateChatResponseSchema = CreateChatResponseSchema;
|
|
1794
|
+
exports.CreateCloudRequestSchema = CreateCloudRequestSchema;
|
|
1795
|
+
exports.CreateCloudResponseSchema = CreateCloudResponseSchema;
|
|
1796
|
+
exports.CreateMergeRequestResponseSchema = CreateMergeRequestResponseSchema;
|
|
1797
|
+
exports.CreateMergeRequestSchema = CreateMergeRequestSchema;
|
|
1798
|
+
exports.CreateOAuthServerRequestSchema = CreateOAuthServerRequestSchema;
|
|
1799
|
+
exports.CreateOAuthServerResponseSchema = CreateOAuthServerResponseSchema;
|
|
1800
|
+
exports.CreditExhaustedEventSchema = CreditExhaustedEventSchema;
|
|
1801
|
+
exports.CreditsPackageSchema = CreditsPackageSchema;
|
|
1802
|
+
exports.DateSchema = DateSchema;
|
|
1803
|
+
exports.DeleteAgentResponseSchema = DeleteAgentResponseSchema;
|
|
1804
|
+
exports.DeleteOAuthServerResponseSchema = DeleteOAuthServerResponseSchema;
|
|
1805
|
+
exports.EventAckSchema = EventAckSchema;
|
|
1806
|
+
exports.EventSchemaMap = EventSchemaMap;
|
|
1807
|
+
exports.FRAMEWORK_TYPES = FRAMEWORK_TYPES;
|
|
1808
|
+
exports.FileItemSchema = FileItemSchema;
|
|
1809
|
+
exports.FileStatsSchema = FileStatsSchema;
|
|
1810
|
+
exports.FileVisibilitySchema = FileVisibilitySchema;
|
|
1811
|
+
exports.FrameworkNotSupportedError = FrameworkNotSupportedError;
|
|
1812
|
+
exports.GetAgentResponseSchema = GetAgentResponseSchema;
|
|
1813
|
+
exports.GetChatResponseSchema = GetChatResponseSchema;
|
|
1814
|
+
exports.GetGitUrlQuerySchema = GetGitUrlQuerySchema;
|
|
1815
|
+
exports.GetGitUrlResponseSchema = GetGitUrlResponseSchema;
|
|
1816
|
+
exports.GetInstallUrlResponseSchema = GetInstallUrlResponseSchema;
|
|
1817
|
+
exports.GetOAuthServerResponseSchema = GetOAuthServerResponseSchema;
|
|
1818
|
+
exports.GetRepositoryResponseSchema = GetRepositoryResponseSchema;
|
|
1819
|
+
exports.GetUploadUrlsRequestSchema = GetUploadUrlsRequestSchema;
|
|
1820
|
+
exports.GetUploadUrlsResponseSchema = GetUploadUrlsResponseSchema;
|
|
1821
|
+
exports.GitHubIssueListItemSchema = GitHubIssueListItemSchema;
|
|
1822
|
+
exports.GitHubIssueSchema = GitHubIssueSchema;
|
|
1823
|
+
exports.IdSchema = IdSchema;
|
|
1824
|
+
exports.ListAgentsResponseSchema = ListAgentsResponseSchema;
|
|
1825
|
+
exports.ListBranchesResponseSchema = ListBranchesResponseSchema;
|
|
1826
|
+
exports.ListChatMembersResponseSchema = ListChatMembersResponseSchema;
|
|
1827
|
+
exports.ListChatTasksResponseSchema = ListChatTasksResponseSchema;
|
|
1828
|
+
exports.ListChatsResponseSchema = ListChatsResponseSchema;
|
|
1829
|
+
exports.ListFilesQuerySchema = ListFilesQuerySchema;
|
|
1830
|
+
exports.ListFilesResponseSchema = ListFilesResponseSchema;
|
|
1831
|
+
exports.ListIssuesQuerySchema = ListIssuesQuerySchema;
|
|
1832
|
+
exports.ListIssuesResponseSchema = ListIssuesResponseSchema;
|
|
1833
|
+
exports.ListMachinesResponseSchema = ListMachinesResponseSchema;
|
|
1834
|
+
exports.ListOAuthServersQuerySchema = ListOAuthServersQuerySchema;
|
|
1835
|
+
exports.ListOAuthServersResponseSchema = ListOAuthServersResponseSchema;
|
|
1836
|
+
exports.ListPackagesQuerySchema = ListPackagesQuerySchema;
|
|
1837
|
+
exports.ListPackagesResponseSchema = ListPackagesResponseSchema;
|
|
1838
|
+
exports.ListRepositoriesResponseSchema = ListRepositoriesResponseSchema;
|
|
1839
|
+
exports.ListTasksResponseSchema = ListTasksResponseSchema;
|
|
1840
|
+
exports.ListTransactionsQuerySchema = ListTransactionsQuerySchema;
|
|
1841
|
+
exports.ListTransactionsResponseSchema = ListTransactionsResponseSchema;
|
|
1842
|
+
exports.LocalMachineSchema = LocalMachineSchema;
|
|
1843
|
+
exports.LogoutResponseSchema = LogoutResponseSchema;
|
|
1844
|
+
exports.MCPServerConfigSchema = MCPServerConfigSchema;
|
|
1845
|
+
exports.MachineAliveEventSchema = MachineAliveEventSchema;
|
|
1846
|
+
exports.MachineApprovalRequestSchema = MachineApprovalRequestSchema;
|
|
1847
|
+
exports.MachineApprovalStatusQuerySchema = MachineApprovalStatusQuerySchema;
|
|
1848
|
+
exports.MachineAuthAuthorizedResponseSchema = MachineAuthAuthorizedResponseSchema;
|
|
1849
|
+
exports.MachineAuthRequestSchema = MachineAuthRequestSchema;
|
|
1850
|
+
exports.MachineAuthResultQuerySchema = MachineAuthResultQuerySchema;
|
|
1851
|
+
exports.MergeRequestEventSchema = MergeRequestEventSchema;
|
|
1852
|
+
exports.MissingAgentFileError = MissingAgentFileError;
|
|
1853
|
+
exports.OAuthAccountInfoSchema = OAuthAccountInfoSchema;
|
|
1854
|
+
exports.OAuthBindCallbackResponseSchema = OAuthBindCallbackResponseSchema;
|
|
1855
|
+
exports.OAuthBindQuerySchema = OAuthBindQuerySchema;
|
|
1856
|
+
exports.OAuthBindResponseSchema = OAuthBindResponseSchema;
|
|
1857
|
+
exports.OAuthCallbackQuerySchema = OAuthCallbackQuerySchema;
|
|
1858
|
+
exports.OAuthCallbackResponseSchema = OAuthCallbackResponseSchema;
|
|
1859
|
+
exports.OAuthLoginQuerySchema = OAuthLoginQuerySchema;
|
|
1860
|
+
exports.OAuthServerPublicSchema = OAuthServerPublicSchema;
|
|
1861
|
+
exports.OAuthServerSchema = OAuthServerSchema;
|
|
1862
|
+
exports.OAuthUnbindResponseSchema = OAuthUnbindResponseSchema;
|
|
1863
|
+
exports.PaginatedResponseSchema = PaginatedResponseSchema;
|
|
1864
|
+
exports.PermissionResponseRequestSchema = PermissionResponseRequestSchema;
|
|
1865
|
+
exports.PermissionResponseResponseSchema = PermissionResponseResponseSchema;
|
|
1866
|
+
exports.ProjectDirectoryResponseSchema = ProjectDirectoryResponseSchema;
|
|
1867
|
+
exports.ProjectEntrySchema = ProjectEntrySchema;
|
|
1868
|
+
exports.QueryEventsRequestSchema = QueryEventsRequestSchema;
|
|
1869
|
+
exports.RechargeResponseSchema = RechargeResponseSchema;
|
|
1870
|
+
exports.RemoveChatMemberRequestSchema = RemoveChatMemberRequestSchema;
|
|
1871
|
+
exports.RepositorySchema = RepositorySchema;
|
|
1872
|
+
exports.RequirePermissionResponseSchema = RequirePermissionResponseSchema;
|
|
1873
|
+
exports.RequirePermissionSchema = RequirePermissionSchema;
|
|
1874
|
+
exports.ResetSecretRequestSchema = ResetSecretRequestSchema;
|
|
1875
|
+
exports.ResetSecretResponseSchema = ResetSecretResponseSchema;
|
|
1876
|
+
exports.ResumeTaskRequestSchema = ResumeTaskRequestSchema;
|
|
1877
|
+
exports.ResumeTaskResponseSchema = ResumeTaskResponseSchema;
|
|
1878
|
+
exports.ShutdownMachineSchema = ShutdownMachineSchema;
|
|
1879
|
+
exports.SignatureAuthRequestSchema = SignatureAuthRequestSchema;
|
|
1880
|
+
exports.SignatureAuthResponseSchema = SignatureAuthResponseSchema;
|
|
1881
|
+
exports.SimpleSuccessSchema = SimpleSuccessSchema;
|
|
1882
|
+
exports.SkillConfigSchema = SkillConfigSchema;
|
|
1883
|
+
exports.StartTaskRequestSchema = StartTaskRequestSchema;
|
|
1884
|
+
exports.StartTaskResponseSchema = StartTaskResponseSchema;
|
|
1885
|
+
exports.StatsQuerySchema = StatsQuerySchema;
|
|
1886
|
+
exports.StopTaskRequestSchema = StopTaskRequestSchema;
|
|
1887
|
+
exports.StopTaskResponseSchema = StopTaskResponseSchema;
|
|
1888
|
+
exports.StopTaskSchema = StopTaskSchema;
|
|
1889
|
+
exports.SyncCloudMachineResponseSchema = SyncCloudMachineResponseSchema;
|
|
1890
|
+
exports.SyncLocalMachineResponseSchema = SyncLocalMachineResponseSchema;
|
|
1891
|
+
exports.SyncMachineRequestSchema = SyncMachineRequestSchema;
|
|
1892
|
+
exports.SystemMessageSchema = SystemMessageSchema;
|
|
1893
|
+
exports.TaskArtifactsUpdatedEventSchema = TaskArtifactsUpdatedEventSchema;
|
|
1894
|
+
exports.TaskItemSchema = TaskItemSchema;
|
|
1895
|
+
exports.TaskMessageSchema = TaskMessageSchema;
|
|
1896
|
+
exports.TaskTransactionsResponseSchema = TaskTransactionsResponseSchema;
|
|
1897
|
+
exports.ToggleOAuthServerRequestSchema = ToggleOAuthServerRequestSchema;
|
|
1898
|
+
exports.ToggleOAuthServerResponseSchema = ToggleOAuthServerResponseSchema;
|
|
1899
|
+
exports.TransactionSchema = TransactionSchema;
|
|
1900
|
+
exports.UpdateAgentRequestSchema = UpdateAgentRequestSchema;
|
|
1901
|
+
exports.UpdateAgentResponseSchema = UpdateAgentResponseSchema;
|
|
1902
|
+
exports.UpdateOAuthServerRequestSchema = UpdateOAuthServerRequestSchema;
|
|
1903
|
+
exports.UpdateOAuthServerResponseSchema = UpdateOAuthServerResponseSchema;
|
|
1904
|
+
exports.UpdateTaskAgentSessionIdEventSchema = UpdateTaskAgentSessionIdEventSchema;
|
|
1905
|
+
exports.UploadUrlResultSchema = UploadUrlResultSchema;
|
|
1906
|
+
exports.UserBalanceResponseSchema = UserBalanceResponseSchema;
|
|
1907
|
+
exports.UserBasicInfoSchema = UserBasicInfoSchema;
|
|
1908
|
+
exports.UserProfileResponseSchema = UserProfileResponseSchema;
|
|
1909
|
+
exports.UserWithOAuthAccountsSchema = UserWithOAuthAccountsSchema;
|
|
1910
|
+
exports.WorkerAliveEventSchema = WorkerAliveEventSchema;
|
|
1911
|
+
exports.WorkerExitSchema = WorkerExitSchema;
|
|
1912
|
+
exports.WorkerInitializingSchema = WorkerInitializingSchema;
|
|
1913
|
+
exports.WorkerReadySchema = WorkerReadySchema;
|
|
1914
|
+
exports.WorkerRunningSchema = WorkerRunningSchema;
|
|
1915
|
+
exports.WorkspaceFileRequestSchema = WorkspaceFileRequestSchema;
|
|
1916
|
+
exports.WorkspaceFileResponseSchema = WorkspaceFileResponseSchema;
|
|
1917
|
+
exports.assertAgentExists = assertAgentExists;
|
|
1918
|
+
exports.assertFileExists = assertFileExists;
|
|
1919
|
+
exports.baseTaskSchema = baseTaskSchema;
|
|
1920
|
+
exports.cancelTaskRequestSchema = cancelTaskRequestSchema;
|
|
1921
|
+
exports.cancelTaskSchema = cancelTaskSchema;
|
|
1922
|
+
exports.createEventId = createEventId;
|
|
1923
|
+
exports.createKeyPair = createKeyPair;
|
|
1924
|
+
exports.createKeyPairWithUit8Array = createKeyPairWithUit8Array;
|
|
1925
|
+
exports.createMergeRequestSchema = createMergeRequestSchema;
|
|
1926
|
+
exports.createTaskSchema = createTaskSchema;
|
|
1927
|
+
exports.decodeBase64 = decodeBase64;
|
|
1928
|
+
exports.decryptAES = decryptAES;
|
|
1929
|
+
exports.decryptFileContent = decryptFileContent;
|
|
1930
|
+
exports.decryptMachineEncryptionKey = decryptMachineEncryptionKey;
|
|
1931
|
+
exports.decryptSdkMessage = decryptSdkMessage;
|
|
1932
|
+
exports.decryptWithEphemeralKey = decryptWithEphemeralKey;
|
|
1933
|
+
exports.encodeBase64 = encodeBase64;
|
|
1934
|
+
exports.encodeBase64Url = encodeBase64Url;
|
|
1935
|
+
exports.encryptAES = encryptAES;
|
|
1936
|
+
exports.encryptFileContent = encryptFileContent;
|
|
1937
|
+
exports.encryptMachineEncryptionKey = encryptMachineEncryptionKey;
|
|
1938
|
+
exports.encryptSdkMessage = encryptSdkMessage;
|
|
1939
|
+
exports.encryptWithEphemeralKey = encryptWithEphemeralKey;
|
|
1940
|
+
exports.generateAESKey = generateAESKey;
|
|
1941
|
+
exports.generateAESKeyBase64 = generateAESKeyBase64;
|
|
1942
|
+
exports.getAgentContext = getAgentContext;
|
|
1943
|
+
exports.getRandomBytes = getRandomBytes;
|
|
1944
|
+
exports.loadAgentConfig = loadAgentConfig;
|
|
1945
|
+
exports.loadMcpServers = loadMcpServers;
|
|
1946
|
+
exports.machineAuth = machineAuth;
|
|
1947
|
+
exports.permissionResponseRequestSchema = permissionResponseRequestSchema;
|
|
1948
|
+
exports.resumeTaskRequestSchema = resumeTaskRequestSchema;
|
|
1949
|
+
exports.resumeTaskSchema = resumeTaskSchema;
|
|
1950
|
+
exports.setAgentContext = setAgentContext;
|
|
1951
|
+
exports.startTaskSchema = startTaskSchema;
|
|
1952
|
+
exports.stopTaskRequestSchema = stopTaskRequestSchema;
|
|
1953
|
+
exports.userAuth = userAuth;
|
|
1954
|
+
exports.validateAgentDirectory = validateAgentDirectory;
|
|
1955
|
+
exports.validateFrameworkDirectory = validateFrameworkDirectory;
|
|
1956
|
+
exports.workerAuth = workerAuth;
|
|
1957
|
+
exports.workerTaskEvents = workerTaskEvents;
|