@pstdio/pocketcoder-sdk 0.5.0 → 0.6.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.d.ts +575 -218
- package/dist/index.js +592 -380
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,221 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { isIP } from "node:net";
|
|
3
|
-
//#region ../contracts/src/
|
|
3
|
+
//#region ../contracts/src/attachments/attachment.ts
|
|
4
|
+
const ATTACHMENT_MAX_FILE_BYTES = 26214400;
|
|
5
|
+
const ATTACHMENT_CHUNK_BYTES = 524288;
|
|
6
|
+
const AttachmentMediaTypeSchema = z.string().regex(/^[\w.+-]+\/[\w.+-]+$/).max(255);
|
|
7
|
+
const AttachmentDescriptorSchema = z.object({
|
|
8
|
+
id: z.uuid(),
|
|
9
|
+
name: z.string().min(1).max(255),
|
|
10
|
+
path: z.string().min(1),
|
|
11
|
+
media_type: AttachmentMediaTypeSchema,
|
|
12
|
+
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES),
|
|
13
|
+
sha256: z.string().regex(/^[0-9a-f]{64}$/)
|
|
14
|
+
});
|
|
15
|
+
z.looseObject({
|
|
16
|
+
type: z.literal("user"),
|
|
17
|
+
content: z.string(),
|
|
18
|
+
attachment_ids: z.array(z.uuid()).min(1).max(10).refine((ids) => new Set(ids).size === ids.length, "attachment_ids must be unique").optional()
|
|
19
|
+
});
|
|
20
|
+
const MANIFEST_OPEN = "<pocketcoder-attachments>";
|
|
21
|
+
const MANIFEST_CLOSE = "</pocketcoder-attachments>";
|
|
22
|
+
function splitAttachmentManifest(content) {
|
|
23
|
+
const open = content.lastIndexOf(MANIFEST_OPEN);
|
|
24
|
+
if (open < 0 || !content.trimEnd().endsWith(MANIFEST_CLOSE)) return {
|
|
25
|
+
text: content,
|
|
26
|
+
attachments: null
|
|
27
|
+
};
|
|
28
|
+
const close = content.lastIndexOf(MANIFEST_CLOSE);
|
|
29
|
+
const parsed = z.array(AttachmentDescriptorSchema).safeParse(safeJson(content.slice(open + 25, close)));
|
|
30
|
+
if (!parsed.success) return {
|
|
31
|
+
text: content,
|
|
32
|
+
attachments: null
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
text: content.slice(0, open).trimEnd(),
|
|
36
|
+
attachments: parsed.data
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function safeJson(value) {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(value);
|
|
42
|
+
} catch {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const AttachmentStartPayload = z.object({
|
|
47
|
+
operation_id: z.uuid(),
|
|
48
|
+
attachment_id: z.uuid(),
|
|
49
|
+
name: z.string().min(1).max(255),
|
|
50
|
+
media_type: AttachmentMediaTypeSchema,
|
|
51
|
+
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES)
|
|
52
|
+
});
|
|
53
|
+
const AttachmentChunkPayload = z.object({
|
|
54
|
+
operation_id: z.uuid(),
|
|
55
|
+
seq: z.number().int().nonnegative(),
|
|
56
|
+
content_b64: z.string().max(Math.ceil(ATTACHMENT_CHUNK_BYTES / 3) * 4 + 4)
|
|
57
|
+
});
|
|
58
|
+
const AttachmentFinishPayload = z.object({ operation_id: z.uuid() });
|
|
59
|
+
const AttachmentAbortPayload = z.object({
|
|
60
|
+
operation_id: z.uuid(),
|
|
61
|
+
reason: z.string().max(512)
|
|
62
|
+
});
|
|
63
|
+
const AttachmentResolvePayload = z.object({
|
|
64
|
+
operation_id: z.uuid(),
|
|
65
|
+
attachment_ids: z.array(z.uuid()).min(1).max(10)
|
|
66
|
+
});
|
|
67
|
+
const AttachmentAckPayload = z.object({
|
|
68
|
+
operation_id: z.uuid(),
|
|
69
|
+
seq: z.number().int().nonnegative(),
|
|
70
|
+
received_bytes: z.number().int().nonnegative()
|
|
71
|
+
});
|
|
72
|
+
const AttachmentResultPayload = z.object({
|
|
73
|
+
operation_id: z.uuid(),
|
|
74
|
+
status: z.enum([
|
|
75
|
+
"created",
|
|
76
|
+
"existing",
|
|
77
|
+
"conflict",
|
|
78
|
+
"failed"
|
|
79
|
+
]),
|
|
80
|
+
descriptor: AttachmentDescriptorSchema.optional(),
|
|
81
|
+
failure_code: z.enum([
|
|
82
|
+
"invalid",
|
|
83
|
+
"too_large",
|
|
84
|
+
"sequence",
|
|
85
|
+
"io",
|
|
86
|
+
"interrupted"
|
|
87
|
+
]).optional(),
|
|
88
|
+
detail: z.string().max(512).optional()
|
|
89
|
+
});
|
|
90
|
+
const AttachmentResolvedPayload = z.object({
|
|
91
|
+
operation_id: z.uuid(),
|
|
92
|
+
descriptors: z.array(AttachmentDescriptorSchema).optional(),
|
|
93
|
+
missing_id: z.uuid().optional()
|
|
94
|
+
});
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region ../contracts/src/common/scopes.ts
|
|
97
|
+
const SCOPES = [
|
|
98
|
+
"templates:read",
|
|
99
|
+
"workspaces:create",
|
|
100
|
+
"workspaces:read",
|
|
101
|
+
"workspaces:cancel",
|
|
102
|
+
"workspaces:purge",
|
|
103
|
+
"workspaces:recover",
|
|
104
|
+
"keys:read",
|
|
105
|
+
"keys:write",
|
|
106
|
+
"workspaces:preserve",
|
|
107
|
+
"workspaces:restore",
|
|
108
|
+
"checkpoints:read",
|
|
109
|
+
"checkpoints:delete",
|
|
110
|
+
"outputs:read",
|
|
111
|
+
"conversations:read",
|
|
112
|
+
"conversations:write",
|
|
113
|
+
"conversations:delete",
|
|
114
|
+
"services:relay",
|
|
115
|
+
"attachments:write",
|
|
116
|
+
"logs:read",
|
|
117
|
+
"network:read",
|
|
118
|
+
"terminal:attach",
|
|
119
|
+
"terminal:read",
|
|
120
|
+
"admin"
|
|
121
|
+
];
|
|
122
|
+
z.strictObject({
|
|
123
|
+
request_id: z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/),
|
|
124
|
+
scopes: z.array(z.enum(SCOPES)).min(1).max(SCOPES.length),
|
|
125
|
+
expires_at: z.iso.datetime()
|
|
126
|
+
});
|
|
127
|
+
const KeyResourceSchema = z.object({
|
|
128
|
+
id: z.uuid(),
|
|
129
|
+
principal_id: z.uuid(),
|
|
130
|
+
scopes: z.array(z.string()),
|
|
131
|
+
effective_scopes: z.array(z.string()),
|
|
132
|
+
managed_principal_ids: z.array(z.uuid()),
|
|
133
|
+
issuance_request_id: z.string().nullable(),
|
|
134
|
+
created_at: z.iso.datetime(),
|
|
135
|
+
expires_at: z.iso.datetime().nullable(),
|
|
136
|
+
revoked_at: z.iso.datetime().nullable(),
|
|
137
|
+
last_used_at: z.iso.datetime().nullable()
|
|
138
|
+
});
|
|
139
|
+
const KeyIssueResponseSchema = z.object({
|
|
140
|
+
key: KeyResourceSchema,
|
|
141
|
+
token: z.string().nullable()
|
|
142
|
+
});
|
|
143
|
+
const KeyListResponseSchema = z.object({
|
|
144
|
+
items: z.array(KeyResourceSchema),
|
|
145
|
+
next_cursor: z.uuid().nullable()
|
|
146
|
+
});
|
|
147
|
+
//#endregion
|
|
148
|
+
//#region ../contracts/src/common/duration.ts
|
|
149
|
+
const DURATION_RE = /^(\d+)(ms|s|m|h)$/;
|
|
150
|
+
function isDuration(value) {
|
|
151
|
+
return DURATION_RE.test(value);
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region ../contracts/src/common/errors.ts
|
|
155
|
+
const ERROR_CODES = {
|
|
156
|
+
"auth.invalid_key": 401,
|
|
157
|
+
"auth.missing_scope": 403,
|
|
158
|
+
"auth.disabled_principal": 403,
|
|
159
|
+
"principal.not_found": 404,
|
|
160
|
+
"key.not_found": 404,
|
|
161
|
+
"validation.invalid": 400,
|
|
162
|
+
"idempotency.conflict": 409,
|
|
163
|
+
"capacity.queue_full": 429,
|
|
164
|
+
"capacity.waiters_full": 429,
|
|
165
|
+
"template.not_found": 404,
|
|
166
|
+
"template.version_not_found": 404,
|
|
167
|
+
"template.not_authorized": 403,
|
|
168
|
+
"workspace.not_found": 404,
|
|
169
|
+
"workspace.external_id_conflict": 409,
|
|
170
|
+
"workspace.not_ready": 409,
|
|
171
|
+
"workspace.terminal": 410,
|
|
172
|
+
"workspace.disconnected": 503,
|
|
173
|
+
"terminal.not_declared": 422,
|
|
174
|
+
"terminal.session_limit": 409,
|
|
175
|
+
"terminal.session_not_found": 404,
|
|
176
|
+
"terminal.session_closed": 409,
|
|
177
|
+
"terminal.protocol_unsupported": 426,
|
|
178
|
+
"workspace.persistence_not_enabled": 409,
|
|
179
|
+
"workspace.preserving": 409,
|
|
180
|
+
"checkpoint.not_found": 404,
|
|
181
|
+
"checkpoint.not_ready": 409,
|
|
182
|
+
"checkpoint.none_ready": 409,
|
|
183
|
+
"checkpoint.corrupt": 409,
|
|
184
|
+
"checkpoint.quota_exceeded": 413,
|
|
185
|
+
"checkpoint.in_use": 409,
|
|
186
|
+
"restore.template_not_authorized": 403,
|
|
187
|
+
"restore.image_unavailable": 409,
|
|
188
|
+
"restore.incompatible": 409,
|
|
189
|
+
"resume.unsupported": 409,
|
|
190
|
+
"conversation.expired": 410,
|
|
191
|
+
"conversation.deleted": 410,
|
|
192
|
+
"operation.conflict": 409,
|
|
193
|
+
"source.not_allowed": 422,
|
|
194
|
+
"source.invalid_revision": 422,
|
|
195
|
+
"secret.unavailable": 503,
|
|
196
|
+
"storage.capacity_exhausted": 507,
|
|
197
|
+
"relay.body_too_large": 413,
|
|
198
|
+
"relay.route_not_allowed": 422,
|
|
199
|
+
"relay.streaming_unsupported": 409,
|
|
200
|
+
"relay.deadline_exceeded": 504,
|
|
201
|
+
"relay.upstream_error": 502,
|
|
202
|
+
"attachment.invalid": 400,
|
|
203
|
+
"attachment.too_large": 413,
|
|
204
|
+
"attachment.not_found": 404,
|
|
205
|
+
"attachment.conflict": 409,
|
|
206
|
+
"attachment.unsupported": 409,
|
|
207
|
+
"attachment.interrupted": 503,
|
|
208
|
+
"internal.error": 500
|
|
209
|
+
};
|
|
210
|
+
const errorCodes = Object.keys(ERROR_CODES);
|
|
211
|
+
const ErrorEnvelopeSchema = z.object({ error: z.object({
|
|
212
|
+
code: z.enum(errorCodes),
|
|
213
|
+
message: z.string().min(1),
|
|
214
|
+
request_id: z.string().min(1),
|
|
215
|
+
details: z.record(z.string(), z.unknown()).optional()
|
|
216
|
+
}) });
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region ../contracts/src/common/pagination.ts
|
|
4
219
|
const CursorSchema = z.string().min(1).max(2048);
|
|
5
220
|
function CursorPageSchema(item) {
|
|
6
221
|
return z.object({
|
|
@@ -15,7 +230,74 @@ function CursorQuerySchema(maxLimit, defaultLimit) {
|
|
|
15
230
|
});
|
|
16
231
|
}
|
|
17
232
|
//#endregion
|
|
18
|
-
//#region ../contracts/src/
|
|
233
|
+
//#region ../contracts/src/conversations/facts.ts
|
|
234
|
+
const ConversationFactSchema = z.discriminatedUnion("type", [
|
|
235
|
+
z.object({ type: z.literal("intermediate") }),
|
|
236
|
+
z.object({ type: z.literal("final_response") }),
|
|
237
|
+
z.object({ type: z.literal("tool_only") }),
|
|
238
|
+
z.object({
|
|
239
|
+
type: z.literal("activity_started"),
|
|
240
|
+
activity_id: z.uuid(),
|
|
241
|
+
kind: z.enum([
|
|
242
|
+
"tool",
|
|
243
|
+
"attachment",
|
|
244
|
+
"workspace",
|
|
245
|
+
"retrieval"
|
|
246
|
+
]),
|
|
247
|
+
label: z.string().min(1).max(160),
|
|
248
|
+
started_at: z.iso.datetime().nullable()
|
|
249
|
+
}),
|
|
250
|
+
z.object({
|
|
251
|
+
type: z.literal("activity_finished"),
|
|
252
|
+
activity_id: z.uuid(),
|
|
253
|
+
ended_at: z.iso.datetime().nullable(),
|
|
254
|
+
outcome: z.enum([
|
|
255
|
+
"completed",
|
|
256
|
+
"failed",
|
|
257
|
+
"interrupted",
|
|
258
|
+
"canceled"
|
|
259
|
+
])
|
|
260
|
+
}),
|
|
261
|
+
z.object({
|
|
262
|
+
type: z.literal("turn_terminal"),
|
|
263
|
+
outcome: z.enum([
|
|
264
|
+
"completed",
|
|
265
|
+
"failed",
|
|
266
|
+
"interrupted",
|
|
267
|
+
"canceled",
|
|
268
|
+
"lost"
|
|
269
|
+
])
|
|
270
|
+
})
|
|
271
|
+
]);
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region ../contracts/src/conversations/identity.ts
|
|
274
|
+
const ConversationRequestIdentitySchema = z.object({
|
|
275
|
+
schema: z.literal("pocketcoder.conversation/v2"),
|
|
276
|
+
authority: z.enum(["external", "generic"]),
|
|
277
|
+
conversation_id: z.uuid(),
|
|
278
|
+
request_id: z.uuid(),
|
|
279
|
+
turn_id: z.uuid(),
|
|
280
|
+
request_fingerprint: z.string().regex(/^[0-9a-f]{64}$/)
|
|
281
|
+
});
|
|
282
|
+
const ConversationRequestReceiptSchema = z.object({
|
|
283
|
+
kind: z.enum(["accepted", "replayed"]),
|
|
284
|
+
identity: ConversationRequestIdentitySchema,
|
|
285
|
+
accepted_at: z.iso.datetime()
|
|
286
|
+
});
|
|
287
|
+
const ConversationMessageIdentitySchema = ConversationRequestIdentitySchema.extend({
|
|
288
|
+
event_id: z.uuid(),
|
|
289
|
+
message_id: z.string().min(1).max(256),
|
|
290
|
+
sequence: z.number().int().nonnegative(),
|
|
291
|
+
revision: z.number().int().positive(),
|
|
292
|
+
fact: ConversationFactSchema.optional()
|
|
293
|
+
});
|
|
294
|
+
const ConversationProtocolSupportSchema = z.object({
|
|
295
|
+
schema: z.literal("pocketcoder.conversation/v2"),
|
|
296
|
+
request_identity_authorities: z.array(z.enum(["external", "generic"])),
|
|
297
|
+
producer_capabilities: z.null()
|
|
298
|
+
});
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region ../contracts/src/conversations/conversation.ts
|
|
19
301
|
const CONVERSATION_ROLES = [
|
|
20
302
|
"user",
|
|
21
303
|
"assistant",
|
|
@@ -28,14 +310,21 @@ const ConversationMessageInputSchema = z.object({
|
|
|
28
310
|
role: z.enum(CONVERSATION_ROLES),
|
|
29
311
|
content: z.string().max(262144),
|
|
30
312
|
occurred_at: z.iso.datetime(),
|
|
31
|
-
metadata: ConversationMetadataSchema.default({})
|
|
313
|
+
metadata: ConversationMetadataSchema.default({}),
|
|
314
|
+
identity: ConversationMessageIdentitySchema.nullable().optional()
|
|
315
|
+
});
|
|
316
|
+
const ConversationMessageResourceSchema = ConversationMessageInputSchema.extend({
|
|
317
|
+
seq: z.number().int().positive(),
|
|
318
|
+
identity: ConversationMessageIdentitySchema.nullable().default(null)
|
|
32
319
|
});
|
|
33
|
-
const ConversationMessageResourceSchema = ConversationMessageInputSchema.extend({ seq: z.number().int().positive() });
|
|
34
320
|
CursorQuerySchema(200, 100);
|
|
35
|
-
const ConversationPageSchema = CursorPageSchema(ConversationMessageResourceSchema).extend({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
321
|
+
const ConversationPageSchema = CursorPageSchema(ConversationMessageResourceSchema).extend({
|
|
322
|
+
protocol: ConversationProtocolSupportSchema.nullable().default(null),
|
|
323
|
+
retention: z.object({
|
|
324
|
+
status: z.literal("retained"),
|
|
325
|
+
expires_at: z.iso.datetime().nullable()
|
|
326
|
+
})
|
|
327
|
+
});
|
|
39
328
|
const ConversationResumeOutcomeSchema = z.object({
|
|
40
329
|
status: z.literal("supported"),
|
|
41
330
|
reason: z.null(),
|
|
@@ -43,13 +332,61 @@ const ConversationResumeOutcomeSchema = z.object({
|
|
|
43
332
|
checkpoint_id: z.uuid()
|
|
44
333
|
});
|
|
45
334
|
//#endregion
|
|
46
|
-
//#region ../contracts/src/
|
|
47
|
-
const
|
|
48
|
-
function
|
|
49
|
-
|
|
335
|
+
//#region ../contracts/src/network/network.ts
|
|
336
|
+
const DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
337
|
+
function isDomain(value) {
|
|
338
|
+
const domain = value.startsWith("*.") ? value.slice(2) : value;
|
|
339
|
+
return domain.length <= 253 && !domain.endsWith(".") && isIP(domain) === 0 && domain.split(".").length >= 2 && domain.split(".").every((label) => DOMAIN_LABEL.test(label));
|
|
50
340
|
}
|
|
341
|
+
const NetworkRuleSchema = z.object({
|
|
342
|
+
domain: z.string().refine(isDomain, "expected a lowercase ASCII domain or leading *. wildcard"),
|
|
343
|
+
ports: z.array(z.number().int().min(1).max(65535)).min(1).max(32).default([80, 443]),
|
|
344
|
+
allowPrivate: z.boolean().default(false)
|
|
345
|
+
}).superRefine((rule, ctx) => {
|
|
346
|
+
if (new Set(rule.ports).size !== rule.ports.length) ctx.addIssue({
|
|
347
|
+
code: "custom",
|
|
348
|
+
path: ["ports"],
|
|
349
|
+
message: "ports must be unique"
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
const UnrestrictedNetworkPolicySchema = z.object({ mode: z.literal("unrestricted") });
|
|
353
|
+
const RestrictedNetworkPolicySchema = z.object({
|
|
354
|
+
mode: z.literal("restricted"),
|
|
355
|
+
allow: z.array(NetworkRuleSchema).max(256).default([])
|
|
356
|
+
});
|
|
357
|
+
const NetworkPolicySchema = z.preprocess((value) => value ?? { mode: "unrestricted" }, z.discriminatedUnion("mode", [UnrestrictedNetworkPolicySchema, RestrictedNetworkPolicySchema]));
|
|
358
|
+
const NETWORK_STATES = [
|
|
359
|
+
"disabled",
|
|
360
|
+
"starting",
|
|
361
|
+
"ready",
|
|
362
|
+
"degraded"
|
|
363
|
+
];
|
|
364
|
+
const NetworkEventInputSchema = z.object({
|
|
365
|
+
source_seq: z.number().int().positive(),
|
|
366
|
+
occurred_at: z.iso.datetime(),
|
|
367
|
+
decision: z.enum(["allow", "deny"]),
|
|
368
|
+
transport: z.enum(["http", "https"]),
|
|
369
|
+
host: z.string().min(1).max(253),
|
|
370
|
+
port: z.number().int().min(1).max(65535),
|
|
371
|
+
method: z.string().max(32).nullable().default(null),
|
|
372
|
+
path: z.string().max(2048).refine((path) => !path.includes("?") && !path.includes("#"), "path cannot contain query or fragment").nullable().default(null),
|
|
373
|
+
matched_rule: z.string().max(512).nullable().default(null),
|
|
374
|
+
reason: z.string().min(1).max(128)
|
|
375
|
+
});
|
|
376
|
+
z.object({
|
|
377
|
+
source_session_id: z.uuid(),
|
|
378
|
+
events: z.array(NetworkEventInputSchema).min(1).max(100)
|
|
379
|
+
});
|
|
380
|
+
const NetworkEventSchema = NetworkEventInputSchema.omit({ source_seq: true }).extend({
|
|
381
|
+
seq: z.number().int().positive(),
|
|
382
|
+
workspace_id: z.uuid(),
|
|
383
|
+
source_session_id: z.uuid(),
|
|
384
|
+
source_seq: z.number().int().positive()
|
|
385
|
+
});
|
|
386
|
+
CursorQuerySchema(200, 100);
|
|
387
|
+
const NetworkEventPageSchema = CursorPageSchema(NetworkEventSchema);
|
|
51
388
|
//#endregion
|
|
52
|
-
//#region ../contracts/src/persistence.ts
|
|
389
|
+
//#region ../contracts/src/persistence/persistence.ts
|
|
53
390
|
const DurationValueSchema = z.string().refine(isDuration, { message: "expected a duration like 15s, 20m, or 2h" });
|
|
54
391
|
const LAUNCH_MODES = ["create", "restore"];
|
|
55
392
|
const CONVERSATION_RESTORE_CAPABILITIES = [
|
|
@@ -117,7 +454,8 @@ const OPERATION_KINDS = [
|
|
|
117
454
|
"preserve",
|
|
118
455
|
"restore",
|
|
119
456
|
"verify",
|
|
120
|
-
"delete"
|
|
457
|
+
"delete",
|
|
458
|
+
"purge"
|
|
121
459
|
];
|
|
122
460
|
const OPERATION_STATES = [
|
|
123
461
|
"pending",
|
|
@@ -194,61 +532,7 @@ z.object({
|
|
|
194
532
|
file_count: z.number().int().nonnegative()
|
|
195
533
|
});
|
|
196
534
|
//#endregion
|
|
197
|
-
//#region ../contracts/src/
|
|
198
|
-
const DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
199
|
-
function isDomain(value) {
|
|
200
|
-
const domain = value.startsWith("*.") ? value.slice(2) : value;
|
|
201
|
-
return domain.length <= 253 && !domain.endsWith(".") && isIP(domain) === 0 && domain.split(".").length >= 2 && domain.split(".").every((label) => DOMAIN_LABEL.test(label));
|
|
202
|
-
}
|
|
203
|
-
const NetworkRuleSchema = z.object({
|
|
204
|
-
domain: z.string().refine(isDomain, "expected a lowercase ASCII domain or leading *. wildcard"),
|
|
205
|
-
ports: z.array(z.number().int().min(1).max(65535)).min(1).max(32).default([80, 443]),
|
|
206
|
-
allowPrivate: z.boolean().default(false)
|
|
207
|
-
}).superRefine((rule, ctx) => {
|
|
208
|
-
if (new Set(rule.ports).size !== rule.ports.length) ctx.addIssue({
|
|
209
|
-
code: "custom",
|
|
210
|
-
path: ["ports"],
|
|
211
|
-
message: "ports must be unique"
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
const UnrestrictedNetworkPolicySchema = z.object({ mode: z.literal("unrestricted") });
|
|
215
|
-
const RestrictedNetworkPolicySchema = z.object({
|
|
216
|
-
mode: z.literal("restricted"),
|
|
217
|
-
allow: z.array(NetworkRuleSchema).max(256).default([])
|
|
218
|
-
});
|
|
219
|
-
const NetworkPolicySchema = z.preprocess((value) => value ?? { mode: "unrestricted" }, z.discriminatedUnion("mode", [UnrestrictedNetworkPolicySchema, RestrictedNetworkPolicySchema]));
|
|
220
|
-
const NETWORK_STATES = [
|
|
221
|
-
"disabled",
|
|
222
|
-
"starting",
|
|
223
|
-
"ready",
|
|
224
|
-
"degraded"
|
|
225
|
-
];
|
|
226
|
-
const NetworkEventInputSchema = z.object({
|
|
227
|
-
source_seq: z.number().int().positive(),
|
|
228
|
-
occurred_at: z.iso.datetime(),
|
|
229
|
-
decision: z.enum(["allow", "deny"]),
|
|
230
|
-
transport: z.enum(["http", "https"]),
|
|
231
|
-
host: z.string().min(1).max(253),
|
|
232
|
-
port: z.number().int().min(1).max(65535),
|
|
233
|
-
method: z.string().max(32).nullable().default(null),
|
|
234
|
-
path: z.string().max(2048).refine((path) => !path.includes("?") && !path.includes("#"), "path cannot contain query or fragment").nullable().default(null),
|
|
235
|
-
matched_rule: z.string().max(512).nullable().default(null),
|
|
236
|
-
reason: z.string().min(1).max(128)
|
|
237
|
-
});
|
|
238
|
-
z.object({
|
|
239
|
-
source_session_id: z.uuid(),
|
|
240
|
-
events: z.array(NetworkEventInputSchema).min(1).max(100)
|
|
241
|
-
});
|
|
242
|
-
const NetworkEventSchema = NetworkEventInputSchema.omit({ source_seq: true }).extend({
|
|
243
|
-
seq: z.number().int().positive(),
|
|
244
|
-
workspace_id: z.uuid(),
|
|
245
|
-
source_session_id: z.uuid(),
|
|
246
|
-
source_seq: z.number().int().positive()
|
|
247
|
-
});
|
|
248
|
-
CursorQuerySchema(200, 100);
|
|
249
|
-
const NetworkEventPageSchema = CursorPageSchema(NetworkEventSchema);
|
|
250
|
-
//#endregion
|
|
251
|
-
//#region ../contracts/src/workspace.ts
|
|
535
|
+
//#region ../contracts/src/workspaces/workspace.ts
|
|
252
536
|
const WORKSPACE_STATES = [
|
|
253
537
|
"queued",
|
|
254
538
|
"provisioning",
|
|
@@ -377,7 +661,7 @@ z.object({
|
|
|
377
661
|
cursor: z.string().optional()
|
|
378
662
|
});
|
|
379
663
|
//#endregion
|
|
380
|
-
//#region ../contracts/src/api.ts
|
|
664
|
+
//#region ../contracts/src/protocol/api.ts
|
|
381
665
|
const TemplatePageSchema = CursorPageSchema(z.object({
|
|
382
666
|
name: z.string(),
|
|
383
667
|
version: z.string(),
|
|
@@ -438,161 +722,6 @@ const StoragePruneResultSchema = z.object({
|
|
|
438
722
|
skipped: z.number().int().nonnegative(),
|
|
439
723
|
transcripts_deleted: z.number().int().nonnegative()
|
|
440
724
|
});
|
|
441
|
-
//#endregion
|
|
442
|
-
//#region ../contracts/src/attachment.ts
|
|
443
|
-
const ATTACHMENT_MAX_FILE_BYTES = 26214400;
|
|
444
|
-
const ATTACHMENT_CHUNK_BYTES = 524288;
|
|
445
|
-
const AttachmentMediaTypeSchema = z.string().regex(/^[\w.+-]+\/[\w.+-]+$/).max(255);
|
|
446
|
-
const AttachmentDescriptorSchema = z.object({
|
|
447
|
-
id: z.uuid(),
|
|
448
|
-
name: z.string().min(1).max(255),
|
|
449
|
-
path: z.string().min(1),
|
|
450
|
-
media_type: AttachmentMediaTypeSchema,
|
|
451
|
-
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES),
|
|
452
|
-
sha256: z.string().regex(/^[0-9a-f]{64}$/)
|
|
453
|
-
});
|
|
454
|
-
z.looseObject({
|
|
455
|
-
type: z.literal("user"),
|
|
456
|
-
content: z.string(),
|
|
457
|
-
attachment_ids: z.array(z.uuid()).min(1).max(10).refine((ids) => new Set(ids).size === ids.length, "attachment_ids must be unique").optional()
|
|
458
|
-
});
|
|
459
|
-
const MANIFEST_OPEN = "<pocketcoder-attachments>";
|
|
460
|
-
const MANIFEST_CLOSE = "</pocketcoder-attachments>";
|
|
461
|
-
function splitAttachmentManifest(content) {
|
|
462
|
-
const open = content.lastIndexOf(MANIFEST_OPEN);
|
|
463
|
-
if (open < 0 || !content.trimEnd().endsWith(MANIFEST_CLOSE)) return {
|
|
464
|
-
text: content,
|
|
465
|
-
attachments: null
|
|
466
|
-
};
|
|
467
|
-
const close = content.lastIndexOf(MANIFEST_CLOSE);
|
|
468
|
-
const parsed = z.array(AttachmentDescriptorSchema).safeParse(safeJson(content.slice(open + 25, close)));
|
|
469
|
-
if (!parsed.success) return {
|
|
470
|
-
text: content,
|
|
471
|
-
attachments: null
|
|
472
|
-
};
|
|
473
|
-
return {
|
|
474
|
-
text: content.slice(0, open).trimEnd(),
|
|
475
|
-
attachments: parsed.data
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
function safeJson(value) {
|
|
479
|
-
try {
|
|
480
|
-
return JSON.parse(value);
|
|
481
|
-
} catch {
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
const AttachmentStartPayload = z.object({
|
|
486
|
-
operation_id: z.uuid(),
|
|
487
|
-
attachment_id: z.uuid(),
|
|
488
|
-
name: z.string().min(1).max(255),
|
|
489
|
-
media_type: AttachmentMediaTypeSchema,
|
|
490
|
-
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES)
|
|
491
|
-
});
|
|
492
|
-
const AttachmentChunkPayload = z.object({
|
|
493
|
-
operation_id: z.uuid(),
|
|
494
|
-
seq: z.number().int().nonnegative(),
|
|
495
|
-
content_b64: z.string().max(Math.ceil(ATTACHMENT_CHUNK_BYTES / 3) * 4 + 4)
|
|
496
|
-
});
|
|
497
|
-
const AttachmentFinishPayload = z.object({ operation_id: z.uuid() });
|
|
498
|
-
const AttachmentAbortPayload = z.object({
|
|
499
|
-
operation_id: z.uuid(),
|
|
500
|
-
reason: z.string().max(512)
|
|
501
|
-
});
|
|
502
|
-
const AttachmentResolvePayload = z.object({
|
|
503
|
-
operation_id: z.uuid(),
|
|
504
|
-
attachment_ids: z.array(z.uuid()).min(1).max(10)
|
|
505
|
-
});
|
|
506
|
-
const AttachmentAckPayload = z.object({
|
|
507
|
-
operation_id: z.uuid(),
|
|
508
|
-
seq: z.number().int().nonnegative(),
|
|
509
|
-
received_bytes: z.number().int().nonnegative()
|
|
510
|
-
});
|
|
511
|
-
const AttachmentResultPayload = z.object({
|
|
512
|
-
operation_id: z.uuid(),
|
|
513
|
-
status: z.enum([
|
|
514
|
-
"created",
|
|
515
|
-
"existing",
|
|
516
|
-
"conflict",
|
|
517
|
-
"failed"
|
|
518
|
-
]),
|
|
519
|
-
descriptor: AttachmentDescriptorSchema.optional(),
|
|
520
|
-
failure_code: z.enum([
|
|
521
|
-
"invalid",
|
|
522
|
-
"too_large",
|
|
523
|
-
"sequence",
|
|
524
|
-
"io",
|
|
525
|
-
"interrupted"
|
|
526
|
-
]).optional(),
|
|
527
|
-
detail: z.string().max(512).optional()
|
|
528
|
-
});
|
|
529
|
-
const AttachmentResolvedPayload = z.object({
|
|
530
|
-
operation_id: z.uuid(),
|
|
531
|
-
descriptors: z.array(AttachmentDescriptorSchema).optional(),
|
|
532
|
-
missing_id: z.uuid().optional()
|
|
533
|
-
});
|
|
534
|
-
//#endregion
|
|
535
|
-
//#region ../contracts/src/errors.ts
|
|
536
|
-
const ERROR_CODES = {
|
|
537
|
-
"auth.invalid_key": 401,
|
|
538
|
-
"auth.missing_scope": 403,
|
|
539
|
-
"auth.disabled_principal": 403,
|
|
540
|
-
"validation.invalid": 400,
|
|
541
|
-
"idempotency.conflict": 409,
|
|
542
|
-
"capacity.queue_full": 429,
|
|
543
|
-
"capacity.waiters_full": 429,
|
|
544
|
-
"template.not_found": 404,
|
|
545
|
-
"template.version_not_found": 404,
|
|
546
|
-
"template.not_authorized": 403,
|
|
547
|
-
"workspace.not_found": 404,
|
|
548
|
-
"workspace.external_id_conflict": 409,
|
|
549
|
-
"workspace.not_ready": 409,
|
|
550
|
-
"workspace.terminal": 410,
|
|
551
|
-
"workspace.disconnected": 503,
|
|
552
|
-
"terminal.not_declared": 422,
|
|
553
|
-
"terminal.session_limit": 409,
|
|
554
|
-
"terminal.session_not_found": 404,
|
|
555
|
-
"terminal.session_closed": 409,
|
|
556
|
-
"terminal.protocol_unsupported": 426,
|
|
557
|
-
"workspace.persistence_not_enabled": 409,
|
|
558
|
-
"workspace.preserving": 409,
|
|
559
|
-
"checkpoint.not_found": 404,
|
|
560
|
-
"checkpoint.not_ready": 409,
|
|
561
|
-
"checkpoint.none_ready": 409,
|
|
562
|
-
"checkpoint.corrupt": 409,
|
|
563
|
-
"checkpoint.quota_exceeded": 413,
|
|
564
|
-
"checkpoint.in_use": 409,
|
|
565
|
-
"restore.template_not_authorized": 403,
|
|
566
|
-
"restore.image_unavailable": 409,
|
|
567
|
-
"restore.incompatible": 409,
|
|
568
|
-
"resume.unsupported": 409,
|
|
569
|
-
"conversation.expired": 410,
|
|
570
|
-
"conversation.deleted": 410,
|
|
571
|
-
"operation.conflict": 409,
|
|
572
|
-
"source.not_allowed": 422,
|
|
573
|
-
"source.invalid_revision": 422,
|
|
574
|
-
"secret.unavailable": 503,
|
|
575
|
-
"storage.capacity_exhausted": 507,
|
|
576
|
-
"relay.body_too_large": 413,
|
|
577
|
-
"relay.route_not_allowed": 422,
|
|
578
|
-
"relay.streaming_unsupported": 409,
|
|
579
|
-
"relay.deadline_exceeded": 504,
|
|
580
|
-
"relay.upstream_error": 502,
|
|
581
|
-
"attachment.invalid": 400,
|
|
582
|
-
"attachment.too_large": 413,
|
|
583
|
-
"attachment.not_found": 404,
|
|
584
|
-
"attachment.conflict": 409,
|
|
585
|
-
"attachment.unsupported": 409,
|
|
586
|
-
"attachment.interrupted": 503,
|
|
587
|
-
"internal.error": 500
|
|
588
|
-
};
|
|
589
|
-
const errorCodes = Object.keys(ERROR_CODES);
|
|
590
|
-
const ErrorEnvelopeSchema = z.object({ error: z.object({
|
|
591
|
-
code: z.enum(errorCodes),
|
|
592
|
-
message: z.string().min(1),
|
|
593
|
-
request_id: z.string().min(1),
|
|
594
|
-
details: z.record(z.string(), z.unknown()).optional()
|
|
595
|
-
}) });
|
|
596
725
|
WORKSPACE_STATES.map((s) => `workspace.${s}`);
|
|
597
726
|
z.object({
|
|
598
727
|
id: z.uuid(),
|
|
@@ -624,7 +753,7 @@ z.object({
|
|
|
624
753
|
})
|
|
625
754
|
});
|
|
626
755
|
//#endregion
|
|
627
|
-
//#region ../contracts/src/logs.ts
|
|
756
|
+
//#region ../contracts/src/protocol/logs.ts
|
|
628
757
|
const LogChunkSchema = z.object({
|
|
629
758
|
seq: z.number().int().positive(),
|
|
630
759
|
stream: z.string(),
|
|
@@ -634,47 +763,14 @@ const LogChunkSchema = z.object({
|
|
|
634
763
|
CursorQuerySchema(1e3, 200);
|
|
635
764
|
const LogPageSchema = CursorPageSchema(LogChunkSchema);
|
|
636
765
|
//#endregion
|
|
637
|
-
//#region ../contracts/src/
|
|
638
|
-
const ProxyStreamStartPayload = z.object({
|
|
639
|
-
request_id: z.uuid(),
|
|
640
|
-
status: z.number().int().min(100).max(599),
|
|
641
|
-
headers: z.record(z.string(), z.string())
|
|
642
|
-
});
|
|
643
|
-
const ProxyStreamChunkPayload = z.object({
|
|
644
|
-
request_id: z.uuid(),
|
|
645
|
-
seq: z.number().int().nonnegative(),
|
|
646
|
-
content_b64: z.string().max(87400)
|
|
647
|
-
});
|
|
648
|
-
const ProxyStreamEndPayload = z.object({
|
|
649
|
-
request_id: z.uuid(),
|
|
650
|
-
error_code: z.enum([
|
|
651
|
-
"unreachable",
|
|
652
|
-
"deadline",
|
|
653
|
-
"too_large"
|
|
654
|
-
]).optional()
|
|
655
|
-
});
|
|
656
|
-
const ProxyStreamAckPayload = z.object({
|
|
657
|
-
request_id: z.uuid(),
|
|
658
|
-
seq: z.number().int().nonnegative()
|
|
659
|
-
});
|
|
660
|
-
const ProxyStreamCancelPayload = z.object({
|
|
661
|
-
request_id: z.uuid(),
|
|
662
|
-
reason: z.enum([
|
|
663
|
-
"downstream_closed",
|
|
664
|
-
"deadline",
|
|
665
|
-
"too_large",
|
|
666
|
-
"workspace_disconnected"
|
|
667
|
-
])
|
|
668
|
-
});
|
|
669
|
-
//#endregion
|
|
670
|
-
//#region ../contracts/src/template-constants.ts
|
|
766
|
+
//#region ../contracts/src/templates/template-constants.ts
|
|
671
767
|
function isAbsolutePath(value) {
|
|
672
768
|
return value.startsWith("/") && ![...value].some((character) => character.codePointAt(0) === 0);
|
|
673
769
|
}
|
|
674
770
|
const SECRET_ENV_PATTERN = /(SECRET|TOKEN|PASSWORD|PASSWD|API_?KEY|PRIVATE_?KEY|CREDENTIAL)/i;
|
|
675
771
|
const SECRET_REFERENCE_PREFIX = "secretRef:";
|
|
676
772
|
//#endregion
|
|
677
|
-
//#region ../contracts/src/template-schema.ts
|
|
773
|
+
//#region ../contracts/src/templates/template-schema.ts
|
|
678
774
|
const NAME_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
679
775
|
const SEMVER_RE = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
|
|
680
776
|
const IMAGE_DIGEST_RE = /^[^\s@]+@sha256:[0-9a-f]{64}$/;
|
|
@@ -864,7 +960,7 @@ const TemplateManifestBaseSchema = z.object({
|
|
|
864
960
|
spec: TemplateSpecSchema
|
|
865
961
|
});
|
|
866
962
|
//#endregion
|
|
867
|
-
//#region ../contracts/src/template-runtime.ts
|
|
963
|
+
//#region ../contracts/src/templates/template-runtime.ts
|
|
868
964
|
const LEGACY_AGENTAPI_SERVICE = ServiceSchema.parse({
|
|
869
965
|
baseUrl: "http://127.0.0.1:3284",
|
|
870
966
|
routes: [
|
|
@@ -920,7 +1016,7 @@ function templateServices(spec) {
|
|
|
920
1016
|
return isAgentApiNative(spec) ? { agent: AGENTAPI_SERVICE } : spec.services;
|
|
921
1017
|
}
|
|
922
1018
|
//#endregion
|
|
923
|
-
//#region ../contracts/src/template-validation.ts
|
|
1019
|
+
//#region ../contracts/src/templates/template-validation.ts
|
|
924
1020
|
function envSources(spec) {
|
|
925
1021
|
const sources = [[["spec", "env"], spec.env], [isAgentApiNative(spec) ? [
|
|
926
1022
|
"spec",
|
|
@@ -1259,12 +1355,14 @@ TemplateManifestBaseSchema.superRefine((manifest, ctx) => {
|
|
|
1259
1355
|
validateTemplateSpec(manifest.spec, ctx);
|
|
1260
1356
|
});
|
|
1261
1357
|
//#endregion
|
|
1262
|
-
//#region ../contracts/src/terminal.ts
|
|
1358
|
+
//#region ../contracts/src/terminals/terminal.ts
|
|
1263
1359
|
const TERMINAL_CHUNK_BYTES = 32768;
|
|
1264
1360
|
const TERMINAL_REPLAY_BUFFER_BYTES = 65536;
|
|
1265
1361
|
function base64Schema(maxBytes) {
|
|
1266
1362
|
return z.string().regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/).refine((value) => {
|
|
1267
|
-
|
|
1363
|
+
let padding = 0;
|
|
1364
|
+
if (value.endsWith("==")) padding = 2;
|
|
1365
|
+
else if (value.endsWith("=")) padding = 1;
|
|
1268
1366
|
return value.length / 4 * 3 - padding <= maxBytes;
|
|
1269
1367
|
}, `decoded payload must not exceed ${maxBytes} bytes`);
|
|
1270
1368
|
}
|
|
@@ -1368,8 +1466,41 @@ const TerminalSessionSchema = z.object({
|
|
|
1368
1466
|
bytes_in: z.number().int().nonnegative(),
|
|
1369
1467
|
bytes_out: z.number().int().nonnegative()
|
|
1370
1468
|
});
|
|
1371
|
-
CursorQuerySchema(200, 50);
|
|
1372
|
-
const TerminalSessionPageSchema = CursorPageSchema(TerminalSessionSchema);
|
|
1469
|
+
CursorQuerySchema(200, 50);
|
|
1470
|
+
const TerminalSessionPageSchema = CursorPageSchema(TerminalSessionSchema);
|
|
1471
|
+
//#endregion
|
|
1472
|
+
//#region ../contracts/src/protocol/protocol-stream.ts
|
|
1473
|
+
const ProxyStreamStartPayload = z.object({
|
|
1474
|
+
request_id: z.uuid(),
|
|
1475
|
+
status: z.number().int().min(100).max(599),
|
|
1476
|
+
headers: z.record(z.string(), z.string())
|
|
1477
|
+
});
|
|
1478
|
+
const ProxyStreamChunkPayload = z.object({
|
|
1479
|
+
request_id: z.uuid(),
|
|
1480
|
+
seq: z.number().int().nonnegative(),
|
|
1481
|
+
content_b64: z.string().max(87400)
|
|
1482
|
+
});
|
|
1483
|
+
const ProxyStreamEndPayload = z.object({
|
|
1484
|
+
request_id: z.uuid(),
|
|
1485
|
+
error_code: z.enum([
|
|
1486
|
+
"unreachable",
|
|
1487
|
+
"deadline",
|
|
1488
|
+
"too_large"
|
|
1489
|
+
]).optional()
|
|
1490
|
+
});
|
|
1491
|
+
const ProxyStreamAckPayload = z.object({
|
|
1492
|
+
request_id: z.uuid(),
|
|
1493
|
+
seq: z.number().int().nonnegative()
|
|
1494
|
+
});
|
|
1495
|
+
const ProxyStreamCancelPayload = z.object({
|
|
1496
|
+
request_id: z.uuid(),
|
|
1497
|
+
reason: z.enum([
|
|
1498
|
+
"downstream_closed",
|
|
1499
|
+
"deadline",
|
|
1500
|
+
"too_large",
|
|
1501
|
+
"workspace_disconnected"
|
|
1502
|
+
])
|
|
1503
|
+
});
|
|
1373
1504
|
const ProviderInputSchema = z.object({
|
|
1374
1505
|
workspace_id: z.uuid(),
|
|
1375
1506
|
server_url: z.string(),
|
|
@@ -1779,7 +1910,7 @@ z.discriminatedUnion("type", [
|
|
|
1779
1910
|
})
|
|
1780
1911
|
]);
|
|
1781
1912
|
//#endregion
|
|
1782
|
-
//#region src/admin.ts
|
|
1913
|
+
//#region src/resources/admin/admin.ts
|
|
1783
1914
|
var AdministrationApi = class {
|
|
1784
1915
|
transport;
|
|
1785
1916
|
constructor(transport) {
|
|
@@ -1799,7 +1930,7 @@ var AdministrationApi = class {
|
|
|
1799
1930
|
}
|
|
1800
1931
|
};
|
|
1801
1932
|
//#endregion
|
|
1802
|
-
//#region src/errors.ts
|
|
1933
|
+
//#region src/transport/errors.ts
|
|
1803
1934
|
z.enum(["client.non_json_response", "client.invalid_response"]);
|
|
1804
1935
|
var PocketCoderError = class extends Error {
|
|
1805
1936
|
code;
|
|
@@ -1856,7 +1987,7 @@ function responseError(response, body) {
|
|
|
1856
1987
|
});
|
|
1857
1988
|
}
|
|
1858
1989
|
//#endregion
|
|
1859
|
-
//#region src/attachments.ts
|
|
1990
|
+
//#region src/resources/attachments/attachments.ts
|
|
1860
1991
|
const DEFAULT_READY_TIMEOUT_MS = 12e4;
|
|
1861
1992
|
function contentDisposition(name) {
|
|
1862
1993
|
const clean = name.replace(/[\r\n]/g, "");
|
|
@@ -1929,7 +2060,7 @@ var AgentApi = class {
|
|
|
1929
2060
|
}
|
|
1930
2061
|
};
|
|
1931
2062
|
//#endregion
|
|
1932
|
-
//#region src/common.ts
|
|
2063
|
+
//#region src/transport/common.ts
|
|
1933
2064
|
function queryString(values) {
|
|
1934
2065
|
const params = new URLSearchParams();
|
|
1935
2066
|
for (const [key, value] of Object.entries(values)) if (value !== void 0) params.set(key, String(value));
|
|
@@ -1942,7 +2073,7 @@ function page(body) {
|
|
|
1942
2073
|
};
|
|
1943
2074
|
}
|
|
1944
2075
|
//#endregion
|
|
1945
|
-
//#region src/checkpoints.ts
|
|
2076
|
+
//#region src/resources/checkpoints/checkpoints.ts
|
|
1946
2077
|
var CheckpointsApi = class {
|
|
1947
2078
|
transport;
|
|
1948
2079
|
constructor(transport) {
|
|
@@ -1990,21 +2121,33 @@ var OperationsApi = class {
|
|
|
1990
2121
|
}
|
|
1991
2122
|
};
|
|
1992
2123
|
//#endregion
|
|
1993
|
-
//#region src/conversations.ts
|
|
2124
|
+
//#region src/resources/conversations/conversations.ts
|
|
1994
2125
|
var ConversationsApi = class {
|
|
1995
2126
|
transport;
|
|
1996
2127
|
constructor(transport) {
|
|
1997
2128
|
this.transport = transport;
|
|
1998
2129
|
}
|
|
1999
2130
|
async list(id, query = {}, options = {}) {
|
|
2000
|
-
|
|
2131
|
+
const body = await this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/conversation?${queryString({
|
|
2001
2132
|
cursor: query.cursor,
|
|
2002
2133
|
limit: query.limit ?? 100
|
|
2003
|
-
})}`, ConversationPageSchema, options)
|
|
2134
|
+
})}`, ConversationPageSchema, options);
|
|
2135
|
+
return {
|
|
2136
|
+
...page(body),
|
|
2137
|
+
protocol: body.protocol,
|
|
2138
|
+
retention: body.retention
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
async acceptRequest(id, identity, options = {}) {
|
|
2142
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/conversation/requests`, ConversationRequestReceiptSchema, {
|
|
2143
|
+
...options,
|
|
2144
|
+
method: "POST",
|
|
2145
|
+
body: JSON.stringify(identity)
|
|
2146
|
+
});
|
|
2004
2147
|
}
|
|
2005
2148
|
};
|
|
2006
2149
|
//#endregion
|
|
2007
|
-
//#region src/diagnostics.ts
|
|
2150
|
+
//#region src/resources/diagnostics/diagnostics.ts
|
|
2008
2151
|
var WorkspaceCursorApi = class {
|
|
2009
2152
|
transport;
|
|
2010
2153
|
resource;
|
|
@@ -2037,7 +2180,69 @@ var OutputsApi = class extends WorkspaceCursorApi {
|
|
|
2037
2180
|
}
|
|
2038
2181
|
};
|
|
2039
2182
|
//#endregion
|
|
2040
|
-
//#region src/
|
|
2183
|
+
//#region src/resources/keys/keys.ts
|
|
2184
|
+
var KeysApi = class {
|
|
2185
|
+
transport;
|
|
2186
|
+
constructor(transport) {
|
|
2187
|
+
this.transport = transport;
|
|
2188
|
+
}
|
|
2189
|
+
list(principalId, query = {}, options = {}) {
|
|
2190
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys?${queryString({
|
|
2191
|
+
limit: query.limit,
|
|
2192
|
+
cursor: query.cursor,
|
|
2193
|
+
request_id: query.requestId
|
|
2194
|
+
})}`, KeyListResponseSchema, options);
|
|
2195
|
+
}
|
|
2196
|
+
async *all(principalId, query = {}, options = {}) {
|
|
2197
|
+
let cursor;
|
|
2198
|
+
do {
|
|
2199
|
+
const page = await this.list(principalId, {
|
|
2200
|
+
...query,
|
|
2201
|
+
cursor
|
|
2202
|
+
}, options);
|
|
2203
|
+
yield* page.items;
|
|
2204
|
+
cursor = page.next_cursor ?? void 0;
|
|
2205
|
+
} while (cursor);
|
|
2206
|
+
}
|
|
2207
|
+
issue(principalId, input, options = {}) {
|
|
2208
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys`, KeyIssueResponseSchema, {
|
|
2209
|
+
method: "POST",
|
|
2210
|
+
body: JSON.stringify(input),
|
|
2211
|
+
signal: options.signal
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2214
|
+
revoke(principalId, keyId, options = {}) {
|
|
2215
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys/${encodeURIComponent(keyId)}`, z.object({ revoked: z.literal(true) }), {
|
|
2216
|
+
method: "DELETE",
|
|
2217
|
+
signal: options.signal
|
|
2218
|
+
});
|
|
2219
|
+
}
|
|
2220
|
+
revokeAll(principalId, options = {}) {
|
|
2221
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys`, z.object({ revoked: z.literal(true) }), {
|
|
2222
|
+
method: "DELETE",
|
|
2223
|
+
signal: options.signal
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
2227
|
+
var RecoveryApi = class {
|
|
2228
|
+
transport;
|
|
2229
|
+
constructor(transport) {
|
|
2230
|
+
this.transport = transport;
|
|
2231
|
+
}
|
|
2232
|
+
purge(principalId, workspaceId, executionKey, options = {}) {
|
|
2233
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/workspaces/${encodeURIComponent(workspaceId)}/purge`, OperationResourceSchema, {
|
|
2234
|
+
method: "POST",
|
|
2235
|
+
headers: { "Idempotency-Key": executionKey },
|
|
2236
|
+
body: "{}",
|
|
2237
|
+
signal: options.signal
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
operation(principalId, operationId, options = {}) {
|
|
2241
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/operations/${encodeURIComponent(operationId)}`, OperationResourceSchema, options);
|
|
2242
|
+
}
|
|
2243
|
+
};
|
|
2244
|
+
//#endregion
|
|
2245
|
+
//#region src/resources/templates/templates.ts
|
|
2041
2246
|
var TemplatesApi = class {
|
|
2042
2247
|
transport;
|
|
2043
2248
|
constructor(transport) {
|
|
@@ -2054,7 +2259,7 @@ var TemplatesApi = class {
|
|
|
2054
2259
|
}
|
|
2055
2260
|
};
|
|
2056
2261
|
//#endregion
|
|
2057
|
-
//#region src/terminals.ts
|
|
2262
|
+
//#region src/resources/terminals/terminals.ts
|
|
2058
2263
|
var TerminalConnection = class {
|
|
2059
2264
|
socket;
|
|
2060
2265
|
messageListeners = /* @__PURE__ */ new Set();
|
|
@@ -2156,7 +2361,109 @@ var TerminalsApi = class {
|
|
|
2156
2361
|
}
|
|
2157
2362
|
};
|
|
2158
2363
|
//#endregion
|
|
2159
|
-
//#region src/
|
|
2364
|
+
//#region src/resources/workspaces/workspaces.ts
|
|
2365
|
+
const TERMINAL_WORKSPACE_STATES = new Set(TERMINAL_STATES);
|
|
2366
|
+
var WorkspacesApi = class {
|
|
2367
|
+
transport;
|
|
2368
|
+
constructor(transport) {
|
|
2369
|
+
this.transport = transport;
|
|
2370
|
+
}
|
|
2371
|
+
async list(query = {}, options = {}) {
|
|
2372
|
+
return page(await this.transport.request(`/v1/workspaces?${queryString({
|
|
2373
|
+
state: query.state,
|
|
2374
|
+
template: query.template,
|
|
2375
|
+
external_id: query.externalId,
|
|
2376
|
+
limit: query.limit ?? 50,
|
|
2377
|
+
cursor: query.cursor
|
|
2378
|
+
})}`, WorkspacePageSchema, options));
|
|
2379
|
+
}
|
|
2380
|
+
async *all(query = {}, options = {}) {
|
|
2381
|
+
let cursor;
|
|
2382
|
+
do {
|
|
2383
|
+
const current = await this.list({
|
|
2384
|
+
...query,
|
|
2385
|
+
cursor
|
|
2386
|
+
}, options);
|
|
2387
|
+
for (const workspace of current.items) yield workspace;
|
|
2388
|
+
cursor = current.nextCursor ?? void 0;
|
|
2389
|
+
} while (cursor);
|
|
2390
|
+
}
|
|
2391
|
+
get(id, options = {}) {
|
|
2392
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}`, WorkspaceResourceSchema, options);
|
|
2393
|
+
}
|
|
2394
|
+
create(input, options = {}) {
|
|
2395
|
+
const body = {
|
|
2396
|
+
external_id: input.externalId,
|
|
2397
|
+
template: {
|
|
2398
|
+
name: input.templateName,
|
|
2399
|
+
...input.templateVersion ? { version: input.templateVersion } : {}
|
|
2400
|
+
},
|
|
2401
|
+
...input.launchInput ? { launch_input: input.launchInput } : {},
|
|
2402
|
+
...input.metadata ? { metadata: input.metadata } : {},
|
|
2403
|
+
...input.source ? { source: input.source } : {}
|
|
2404
|
+
};
|
|
2405
|
+
return this.transport.request("/v1/workspaces", WorkspaceResourceSchema, {
|
|
2406
|
+
method: "POST",
|
|
2407
|
+
signal: options.signal,
|
|
2408
|
+
headers: { "Idempotency-Key": input.idempotencyKey ?? input.externalId },
|
|
2409
|
+
body: JSON.stringify(body)
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
cancel(id, options = {}) {
|
|
2413
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/cancel`, WorkspaceResourceSchema, {
|
|
2414
|
+
method: "POST",
|
|
2415
|
+
signal: options.signal
|
|
2416
|
+
});
|
|
2417
|
+
}
|
|
2418
|
+
change(id, after, wait, options = {}) {
|
|
2419
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/changes?after=${after}&wait=${wait}`, WorkspaceChangeSchema, options);
|
|
2420
|
+
}
|
|
2421
|
+
async waitForReady(initial, timeoutMs, options = {}) {
|
|
2422
|
+
const deadline = Date.now() + timeoutMs;
|
|
2423
|
+
let workspace = initial;
|
|
2424
|
+
while (workspace.state !== "ready") {
|
|
2425
|
+
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2426
|
+
const remainingMs = deadline - Date.now();
|
|
2427
|
+
if (remainingMs <= 0) throw new Error(`workspace ${workspace.id} did not become ready within ${timeoutMs}ms`);
|
|
2428
|
+
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2429
|
+
options.onTick?.(workspace);
|
|
2430
|
+
}
|
|
2431
|
+
return workspace;
|
|
2432
|
+
}
|
|
2433
|
+
async waitForAgentInput(id, timeoutMs, options = {}) {
|
|
2434
|
+
const deadline = Date.now() + timeoutMs;
|
|
2435
|
+
let workspace = await this.get(id, options);
|
|
2436
|
+
while (workspace.agent_state !== "stable") {
|
|
2437
|
+
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2438
|
+
const remainingMs = deadline - Date.now();
|
|
2439
|
+
if (remainingMs <= 0) throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs);
|
|
2440
|
+
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2441
|
+
}
|
|
2442
|
+
return workspace;
|
|
2443
|
+
}
|
|
2444
|
+
preserve(id, input, key, options = {}) {
|
|
2445
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
|
|
2446
|
+
}
|
|
2447
|
+
purge(id, key, options = {}) {
|
|
2448
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/purge`, {}, key, OperationResourceSchema, options);
|
|
2449
|
+
}
|
|
2450
|
+
recreate(id, input, key, options = {}) {
|
|
2451
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/recreate`, input, key, RestoreResponseSchema, options);
|
|
2452
|
+
}
|
|
2453
|
+
resume(id, input, key, options = {}) {
|
|
2454
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/resume`, input, key, ResumeResponseSchema, options);
|
|
2455
|
+
}
|
|
2456
|
+
jsonOperation(path, input, key, schema, options) {
|
|
2457
|
+
return this.transport.request(path, schema, {
|
|
2458
|
+
method: "POST",
|
|
2459
|
+
signal: options.signal,
|
|
2460
|
+
headers: { "Idempotency-Key": key },
|
|
2461
|
+
body: JSON.stringify(input)
|
|
2462
|
+
});
|
|
2463
|
+
}
|
|
2464
|
+
};
|
|
2465
|
+
//#endregion
|
|
2466
|
+
//#region src/transport/transport.ts
|
|
2160
2467
|
function baseUrlOf(value) {
|
|
2161
2468
|
let url;
|
|
2162
2469
|
try {
|
|
@@ -2273,105 +2580,6 @@ async function delay(milliseconds, signal) {
|
|
|
2273
2580
|
});
|
|
2274
2581
|
}
|
|
2275
2582
|
//#endregion
|
|
2276
|
-
//#region src/workspaces.ts
|
|
2277
|
-
const TERMINAL_WORKSPACE_STATES = new Set(TERMINAL_STATES);
|
|
2278
|
-
var WorkspacesApi = class {
|
|
2279
|
-
transport;
|
|
2280
|
-
constructor(transport) {
|
|
2281
|
-
this.transport = transport;
|
|
2282
|
-
}
|
|
2283
|
-
async list(query = {}, options = {}) {
|
|
2284
|
-
return page(await this.transport.request(`/v1/workspaces?${queryString({
|
|
2285
|
-
state: query.state,
|
|
2286
|
-
template: query.template,
|
|
2287
|
-
external_id: query.externalId,
|
|
2288
|
-
limit: query.limit ?? 50,
|
|
2289
|
-
cursor: query.cursor
|
|
2290
|
-
})}`, WorkspacePageSchema, options));
|
|
2291
|
-
}
|
|
2292
|
-
async *all(query = {}, options = {}) {
|
|
2293
|
-
let cursor;
|
|
2294
|
-
do {
|
|
2295
|
-
const current = await this.list({
|
|
2296
|
-
...query,
|
|
2297
|
-
cursor
|
|
2298
|
-
}, options);
|
|
2299
|
-
for (const workspace of current.items) yield workspace;
|
|
2300
|
-
cursor = current.nextCursor ?? void 0;
|
|
2301
|
-
} while (cursor);
|
|
2302
|
-
}
|
|
2303
|
-
get(id, options = {}) {
|
|
2304
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}`, WorkspaceResourceSchema, options);
|
|
2305
|
-
}
|
|
2306
|
-
create(input, options = {}) {
|
|
2307
|
-
const body = {
|
|
2308
|
-
external_id: input.externalId,
|
|
2309
|
-
template: {
|
|
2310
|
-
name: input.templateName,
|
|
2311
|
-
...input.templateVersion ? { version: input.templateVersion } : {}
|
|
2312
|
-
},
|
|
2313
|
-
...input.launchInput ? { launch_input: input.launchInput } : {},
|
|
2314
|
-
...input.metadata ? { metadata: input.metadata } : {},
|
|
2315
|
-
...input.source ? { source: input.source } : {}
|
|
2316
|
-
};
|
|
2317
|
-
return this.transport.request("/v1/workspaces", WorkspaceResourceSchema, {
|
|
2318
|
-
method: "POST",
|
|
2319
|
-
signal: options.signal,
|
|
2320
|
-
headers: { "Idempotency-Key": input.idempotencyKey ?? input.externalId },
|
|
2321
|
-
body: JSON.stringify(body)
|
|
2322
|
-
});
|
|
2323
|
-
}
|
|
2324
|
-
cancel(id, options = {}) {
|
|
2325
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/cancel`, WorkspaceResourceSchema, {
|
|
2326
|
-
method: "POST",
|
|
2327
|
-
signal: options.signal
|
|
2328
|
-
});
|
|
2329
|
-
}
|
|
2330
|
-
change(id, after, wait, options = {}) {
|
|
2331
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/changes?after=${after}&wait=${wait}`, WorkspaceChangeSchema, options);
|
|
2332
|
-
}
|
|
2333
|
-
async waitForReady(initial, timeoutMs, options = {}) {
|
|
2334
|
-
const deadline = Date.now() + timeoutMs;
|
|
2335
|
-
let workspace = initial;
|
|
2336
|
-
while (workspace.state !== "ready") {
|
|
2337
|
-
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2338
|
-
const remainingMs = deadline - Date.now();
|
|
2339
|
-
if (remainingMs <= 0) throw new Error(`workspace ${workspace.id} did not become ready within ${timeoutMs}ms`);
|
|
2340
|
-
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2341
|
-
options.onTick?.(workspace);
|
|
2342
|
-
}
|
|
2343
|
-
return workspace;
|
|
2344
|
-
}
|
|
2345
|
-
async waitForAgentInput(id, timeoutMs, options = {}) {
|
|
2346
|
-
const deadline = Date.now() + timeoutMs;
|
|
2347
|
-
let workspace = await this.get(id, options);
|
|
2348
|
-
while (workspace.agent_state !== "stable") {
|
|
2349
|
-
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2350
|
-
const remainingMs = deadline - Date.now();
|
|
2351
|
-
if (remainingMs <= 0) throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs);
|
|
2352
|
-
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2353
|
-
}
|
|
2354
|
-
return workspace;
|
|
2355
|
-
}
|
|
2356
|
-
preserve(id, input, key, options = {}) {
|
|
2357
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
|
|
2358
|
-
}
|
|
2359
|
-
recreate(id, input, key, options = {}) {
|
|
2360
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/recreate`, input, key, RestoreResponseSchema, options);
|
|
2361
|
-
}
|
|
2362
|
-
resume(id, input, key, options = {}) {
|
|
2363
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/resume`, input, key, ResumeResponseSchema, options);
|
|
2364
|
-
}
|
|
2365
|
-
jsonOperation(path, input, key, schema, options) {
|
|
2366
|
-
return this.transport.request(path, schema, {
|
|
2367
|
-
method: "POST",
|
|
2368
|
-
signal: options.signal,
|
|
2369
|
-
headers: { "Idempotency-Key": key },
|
|
2370
|
-
body: JSON.stringify(input)
|
|
2371
|
-
});
|
|
2372
|
-
}
|
|
2373
|
-
};
|
|
2374
|
-
//#endregion
|
|
2375
2583
|
//#region src/client.ts
|
|
2376
2584
|
var PocketCoderClient = class {
|
|
2377
2585
|
transport;
|
|
@@ -2387,6 +2595,8 @@ var PocketCoderClient = class {
|
|
|
2387
2595
|
outputs;
|
|
2388
2596
|
administration;
|
|
2389
2597
|
terminals;
|
|
2598
|
+
keys;
|
|
2599
|
+
recovery;
|
|
2390
2600
|
constructor(config, fetchImpl = fetch) {
|
|
2391
2601
|
this.transport = new PocketCoderTransport(config, fetchImpl);
|
|
2392
2602
|
this.templates = new TemplatesApi(this.transport);
|
|
@@ -2401,13 +2611,15 @@ var PocketCoderClient = class {
|
|
|
2401
2611
|
this.outputs = new OutputsApi(this.transport);
|
|
2402
2612
|
this.administration = new AdministrationApi(this.transport);
|
|
2403
2613
|
this.terminals = new TerminalsApi(this.transport);
|
|
2614
|
+
this.keys = new KeysApi(this.transport);
|
|
2615
|
+
this.recovery = new RecoveryApi(this.transport);
|
|
2404
2616
|
}
|
|
2405
2617
|
raw(path, init = {}) {
|
|
2406
2618
|
return this.transport.raw(path, init);
|
|
2407
2619
|
}
|
|
2408
2620
|
};
|
|
2409
2621
|
//#endregion
|
|
2410
|
-
//#region src/workspace-turn-resolver.ts
|
|
2622
|
+
//#region src/resources/workspaces/workspace-turn-resolver.ts
|
|
2411
2623
|
const ERROR_MESSAGES = {
|
|
2412
2624
|
not_resumable: "workspace cannot be resumed",
|
|
2413
2625
|
resume_handler_missing: "workspace resume handler is not configured",
|
|
@@ -2551,4 +2763,4 @@ var WorkspaceTurnResolver = class {
|
|
|
2551
2763
|
}
|
|
2552
2764
|
};
|
|
2553
2765
|
//#endregion
|
|
2554
|
-
export { AdministrationApi, AgentApi, AgentNotReadyError, AttachmentsApi, CheckpointsApi, ConversationGoneError, ConversationsApi, LogsApi, NetworkEventsApi, OperationsApi, OutputsApi, PocketCoderClient, PocketCoderError, TERMINAL_WORKSPACE_STATES, TemplatesApi, TerminalConnection, TerminalsApi, WorkspaceTerminalError, WorkspaceTurnResolutionError, WorkspaceTurnResolver, WorkspacesApi, isPocketCoderErrorCode, splitAttachmentManifest };
|
|
2766
|
+
export { AdministrationApi, AgentApi, AgentNotReadyError, AttachmentsApi, CheckpointsApi, ConversationGoneError, ConversationsApi, KeysApi, LogsApi, NetworkEventsApi, OperationsApi, OutputsApi, PocketCoderClient, PocketCoderError, RecoveryApi, TERMINAL_WORKSPACE_STATES, TemplatesApi, TerminalConnection, TerminalsApi, WorkspaceTerminalError, WorkspaceTurnResolutionError, WorkspaceTurnResolver, WorkspacesApi, isPocketCoderErrorCode, splitAttachmentManifest };
|