@byok-sdk/server 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blob-store.d.ts +23 -11
- package/dist/hub.d.ts +17 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +388 -59
- package/dist/index.js.map +1 -1
- package/dist/pairing.d.ts +29 -0
- package/dist/sqlite-blob-store.d.ts +8 -4
- package/dist/types.d.ts +6 -0
- package/dist/ws-server.d.ts +3 -0
- package/package.json +3 -3
package/dist/blob-store.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TenantId } from './auth';
|
|
1
2
|
/**
|
|
2
3
|
* Blob flows (docs/protocol.md §7): `POST /byok/blobs` declares a blob and
|
|
3
4
|
* gets back a presigned upload URL; the caller `PUT`s the bytes there
|
|
@@ -8,9 +9,9 @@
|
|
|
8
9
|
*
|
|
9
10
|
* `BlobStore` is interface-shaped so a SaaS can swap in a real object-store
|
|
10
11
|
* (S3/GCS/R2 presigned URLs) later; {@link LocalDiskBlobStore} is the M1
|
|
11
|
-
* reference implementation (single-process,
|
|
12
|
-
* disk) — good enough for local dev and the SDK's own tests,
|
|
13
|
-
*
|
|
12
|
+
* reference implementation (single-process, persisted metadata + files on
|
|
13
|
+
* disk) — good enough for local dev and the SDK's own tests, including a
|
|
14
|
+
* restart of the same directory; it is not multi-process storage.
|
|
14
15
|
*/
|
|
15
16
|
export interface CreateUploadInput {
|
|
16
17
|
size: number;
|
|
@@ -28,19 +29,25 @@ export interface ReadContentResult {
|
|
|
28
29
|
data: Buffer;
|
|
29
30
|
contentType: string;
|
|
30
31
|
}
|
|
32
|
+
/** The upload reservation HTTP must resolve before it starts retaining bytes. */
|
|
33
|
+
export interface BlobUploadReservation {
|
|
34
|
+
size: number;
|
|
35
|
+
}
|
|
31
36
|
export declare class BlobDeclarationConflictError extends Error {
|
|
32
37
|
constructor(blobId: string);
|
|
33
38
|
}
|
|
34
39
|
export interface BlobStore {
|
|
35
40
|
/** Declare a blob before upload; an explicit id makes the declaration idempotent across host restart. */
|
|
36
|
-
createUpload(input: CreateUploadInput, blobId?: string): Promise<{
|
|
41
|
+
createUpload(tenantId: TenantId, input: CreateUploadInput, blobId?: string): Promise<{
|
|
37
42
|
blobId: string;
|
|
38
43
|
uploadUrl: string;
|
|
39
44
|
}>;
|
|
40
45
|
/** A presigned GET URL for a blob that has finished uploading, or `undefined` if unknown/not yet uploaded. */
|
|
41
|
-
getDownloadUrl(blobId: string): Promise<string | undefined>;
|
|
46
|
+
getDownloadUrl(tenantId: TenantId, blobId: string): Promise<string | undefined>;
|
|
42
47
|
/** Whether `blobId` is known *and* has finished uploading. */
|
|
43
|
-
exists(blobId: string): Promise<boolean>;
|
|
48
|
+
exists(tenantId: TenantId, blobId: string): Promise<boolean>;
|
|
49
|
+
/** Resolve a capability URL's immutable declared size before consuming its body. */
|
|
50
|
+
getUploadReservation(blobId: string): Promise<BlobUploadReservation | undefined>;
|
|
44
51
|
/** Verify a presigned content URL's `sig`/`exp` query params for `action`. */
|
|
45
52
|
verifySignedUrl(blobId: string, action: 'put' | 'get', sig: string, exp: number): boolean;
|
|
46
53
|
/** Accept uploaded bytes; rejects (without storing) on size/hash mismatch against the `createUpload` declaration. */
|
|
@@ -54,24 +61,29 @@ export interface LocalDiskBlobStoreOptions {
|
|
|
54
61
|
/** How long a presigned upload/download URL stays valid, ms. Default 15 minutes. */
|
|
55
62
|
urlTtlMs?: number;
|
|
56
63
|
}
|
|
57
|
-
/** Local-disk reference {@link BlobStore}:
|
|
64
|
+
/** Local-disk reference {@link BlobStore}: persisted metadata/content and HMAC-signed expiring URLs. */
|
|
58
65
|
export declare class LocalDiskBlobStore implements BlobStore {
|
|
59
|
-
private
|
|
66
|
+
private secret;
|
|
60
67
|
private readonly directory;
|
|
68
|
+
private readonly metadataPath;
|
|
61
69
|
private readonly urlTtlMs;
|
|
62
70
|
private readonly blobs;
|
|
63
71
|
private readonly ready;
|
|
72
|
+
private metadataWriteTail;
|
|
64
73
|
constructor(opts?: LocalDiskBlobStoreOptions);
|
|
65
|
-
createUpload(input: CreateUploadInput, requestedBlobId?: string): Promise<{
|
|
74
|
+
createUpload(tenantId: TenantId, input: CreateUploadInput, requestedBlobId?: string): Promise<{
|
|
66
75
|
blobId: string;
|
|
67
76
|
uploadUrl: string;
|
|
68
77
|
}>;
|
|
69
|
-
getDownloadUrl(blobId: string): Promise<string | undefined>;
|
|
70
|
-
exists(blobId: string): Promise<boolean>;
|
|
78
|
+
getDownloadUrl(tenantId: TenantId, blobId: string): Promise<string | undefined>;
|
|
79
|
+
exists(tenantId: TenantId, blobId: string): Promise<boolean>;
|
|
80
|
+
getUploadReservation(blobId: string): Promise<BlobUploadReservation | undefined>;
|
|
71
81
|
verifySignedUrl(blobId: string, action: 'put' | 'get', sig: string, exp: number): boolean;
|
|
72
82
|
writeContent(blobId: string, data: Buffer): Promise<WriteContentResult>;
|
|
73
83
|
readContent(blobId: string): Promise<ReadContentResult | undefined>;
|
|
74
84
|
private pathFor;
|
|
85
|
+
private loadMetadata;
|
|
86
|
+
private persistMetadata;
|
|
75
87
|
private computeSig;
|
|
76
88
|
private signUrl;
|
|
77
89
|
}
|
package/dist/hub.d.ts
CHANGED
|
@@ -194,6 +194,12 @@ export declare class AgentHomeProjectionCompletionError extends Error {
|
|
|
194
194
|
readonly code: AgentHomeProjectionCompletionErrorCode;
|
|
195
195
|
constructor(code: AgentHomeProjectionCompletionErrorCode, message: string);
|
|
196
196
|
}
|
|
197
|
+
/** A requested delivery cursor predates controls this bounded hub can recover. */
|
|
198
|
+
export declare class ReplayGapError extends Error {
|
|
199
|
+
readonly cursor: number;
|
|
200
|
+
readonly recoverableFrom: number;
|
|
201
|
+
constructor(cursor: number, recoverableFrom: number);
|
|
202
|
+
}
|
|
197
203
|
export declare class ConnectionHub {
|
|
198
204
|
private readonly taskStore;
|
|
199
205
|
private readonly devices;
|
|
@@ -211,6 +217,7 @@ export declare class ConnectionHub {
|
|
|
211
217
|
private readonly rateLimiter;
|
|
212
218
|
private readonly agentMessage?;
|
|
213
219
|
private readonly connections;
|
|
220
|
+
private readonly connectionEpochs;
|
|
214
221
|
private readonly outboxes;
|
|
215
222
|
/** Idempotency window per device (N3) — recent inbound envelope ids, capped at {@link DEDUP_RING_CAPACITY}. */
|
|
216
223
|
private readonly dedupRings;
|
|
@@ -302,7 +309,9 @@ export declare class ConnectionHub {
|
|
|
302
309
|
* connection this hub never learns capabilities for simply reads back
|
|
303
310
|
* `undefined` from {@link getDeviceCapabilities}.
|
|
304
311
|
*/
|
|
305
|
-
registerConnection(deviceId: string, ws: WebSocket, runtimes: RuntimeInfo[] | undefined, capabilities?: readonly string[], configuredToolsets?: readonly ToolsetId[], clientVersion?: string):
|
|
312
|
+
registerConnection(deviceId: string, ws: WebSocket, runtimes: RuntimeInfo[] | undefined, capabilities?: readonly string[], configuredToolsets?: readonly ToolsetId[], clientVersion?: string): number;
|
|
313
|
+
/** True only while this exact WS registration remains the device authority. */
|
|
314
|
+
isCurrentConnection(deviceId: string, ws: WebSocket, epoch: number): boolean;
|
|
306
315
|
sendConnAck(deviceId: string, capabilities: string[]): void;
|
|
307
316
|
/**
|
|
308
317
|
* Reconnection procedure step 3 (§9): redeliver, in `seq` order, every
|
|
@@ -897,10 +906,17 @@ export declare class ConnectionHub {
|
|
|
897
906
|
* on any future reconnect/poll.
|
|
898
907
|
*/
|
|
899
908
|
private collectRelevant;
|
|
909
|
+
/**
|
|
910
|
+
* A caller at `recoverableFrom - 1` can still receive the first retained
|
|
911
|
+
* control. Anything earlier would be a partial tail and must fail closed.
|
|
912
|
+
*/
|
|
913
|
+
assertReplayAvailable(deviceId: string, cursor: number, pendingOutbound?: number): void;
|
|
914
|
+
private isRecoverableEntry;
|
|
900
915
|
private isTaskTerminal;
|
|
901
916
|
/** The highest `seq` assigned to `deviceId` so far — the redelivery cursor to hand back on a poll/reconnect. */
|
|
902
917
|
private currentCursor;
|
|
903
918
|
private getOrCreateOutbox;
|
|
919
|
+
private nextConnectionEpoch;
|
|
904
920
|
listMachines(): MachineInfo[];
|
|
905
921
|
/**
|
|
906
922
|
* M5 (approval targeting, hello-capability plumbing): the capability flags
|
package/dist/index.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export { SteerRejectedError } from './hub';
|
|
|
26
26
|
export type { SteerRejectionCode } from './hub';
|
|
27
27
|
export { AgentHomeProjectionCompletionError } from './hub';
|
|
28
28
|
export type { AgentHomeProjectionCompletionErrorCode } from './hub';
|
|
29
|
-
export { PairingCodeInvalidError } from './pairing';
|
|
30
|
-
export type { PairingCodeClaims, PairingCodeInfo } from './pairing';
|
|
29
|
+
export { PairingAttemptConflictError, PairingCodeInvalidError } from './pairing';
|
|
30
|
+
export type { PairingAttemptBinding, PairingCodeClaims, PairingCodeInfo, PairingCompletion } from './pairing';
|
|
31
31
|
export type { AccessTokenClaims, AuthenticatedDevice, DeviceRecord, TenantId, TokenSigner, } from './auth';
|
|
32
32
|
/**
|
|
33
33
|
* S1: `DeviceRegistry` itself is deliberately NOT exported. Its
|
|
@@ -38,7 +38,7 @@ export type { AccessTokenClaims, AuthenticatedDevice, DeviceRecord, TenantId, To
|
|
|
38
38
|
* cross-tenant device oracle for free.
|
|
39
39
|
*/
|
|
40
40
|
export { createHmacTokenSigner } from './auth';
|
|
41
|
-
export type { BlobStore, CreateUploadInput, ReadContentResult, WriteContentResult, } from './blob-store';
|
|
41
|
+
export type { BlobStore, BlobUploadReservation, CreateUploadInput, ReadContentResult, WriteContentResult, } from './blob-store';
|
|
42
42
|
export { LocalDiskBlobStore } from './blob-store';
|
|
43
43
|
export type { SqliteTaskStoreOptions } from './sqlite-task-store';
|
|
44
44
|
export { SqliteTaskStore } from './sqlite-task-store';
|