@byok-sdk/cloud 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,25 @@ logic but no durable database or object-storage driver.
6
6
 
7
7
  Pair it with `@byok-sdk/cloud-dataplane` for Postgres + R2 production storage.
8
8
 
9
+ `authenticateHostedDeviceAssertion()` is the hosted connector-binding auth
10
+ composition. It adapts the current `DeviceDirectory` row and `CloudCrypto` to
11
+ core's single-use authenticator; callers must inject a replay authority and
12
+ trusted deployment bindings. Create durable connector state only after it
13
+ returns a principal. OAuth refresh tokens and the resulting long-lived profile
14
+ remain host-owned and are never stored by this API.
15
+
16
+ ```ts
17
+ const authenticated = await authenticateHostedDeviceAssertion(assertion, {
18
+ devices,
19
+ crypto,
20
+ replay,
21
+ clock,
22
+ expected: { issuer, productId, audience: 'connector-binding' },
23
+ });
24
+ if (authenticated === undefined) throw new Error('unauthorized');
25
+ await connectorProfiles.bind(authenticated.device, providerLogin);
26
+ ```
27
+
9
28
  Hosted compositions enqueue the distinct toolset offer message explicitly:
10
29
 
11
30
  ```ts
@@ -0,0 +1,18 @@
1
+ import { type AuthenticatedDeviceAssertion, type Clock, type DeviceAssertionExpectedBinding, type DeviceAssertionReplayAuthority } from '@byok-sdk/core';
2
+ import type { CloudCrypto } from '../crypto/port';
3
+ import type { DeviceDirectory } from '../stores/ports';
4
+ export interface HostedDeviceAssertionAuthDeps {
5
+ readonly devices: DeviceDirectory;
6
+ readonly crypto: CloudCrypto;
7
+ readonly replay: DeviceAssertionReplayAuthority;
8
+ readonly clock: Clock;
9
+ readonly expected: DeviceAssertionExpectedBinding;
10
+ readonly maxLifetimeMs?: number;
11
+ }
12
+ /**
13
+ * Hosted composition for an assertion exchange endpoint. The returned
14
+ * principal is current device-directory authority; the assertion is consumed
15
+ * before success is returned. Connector sessions minted afterward remain
16
+ * host-owned and are never represented by this short-lived credential.
17
+ */
18
+ export declare function authenticateHostedDeviceAssertion(input: unknown, deps: HostedDeviceAssertionAuthDeps): Promise<AuthenticatedDeviceAssertion | undefined>;
package/dist/cloud.d.ts CHANGED
@@ -14,7 +14,7 @@
14
14
  * quietly undo that — a Running/session map — is asserted absent by
15
15
  * `src/__tests__/constraints.test.ts`.
16
16
  */
17
- import { type BoardItem, type BoardItemInput, type BoardListQuery, type BoardPage, type CapabilityDeclaration, type Clock, type CoreStores, type PresenceHint, type SkillPackStore, type TenantId } from '@byok-sdk/core';
17
+ import { type BoardItem, type BoardItemInput, type BoardListQuery, type BoardPage, type CapabilityDeclaration, type Clock, type CoreStores, type PresenceHint, type SkillPackStore, type TenantId, type TenantReadiness } from '@byok-sdk/core';
18
18
  import type { ActivityTail } from './activity';
19
19
  import type { ApprovalTimelineTail } from './approval-timeline';
20
20
  import { type Envelope, type TaskOfferPayload, type TaskOfferWithToolsetsPayload } from '@byok-sdk/protocol';
@@ -127,17 +127,18 @@ export interface ByokCloud {
127
127
  enqueueOffer(tenant: TenantId, deviceId: string, input: EnqueueOfferInput): Promise<EnqueuedOffer>;
128
128
  /** Host control plane: enqueue the additive fail-closed offer variant that requires local MCP toolsets. */
129
129
  enqueueToolsetOffer(tenant: TenantId, deviceId: string, input: EnqueueToolsetOfferInput): Promise<EnqueuedOffer>;
130
+ /** Host control plane: durably request cancellation by tenant/task id. Idempotent. */
131
+ cancelTask(tenant: TenantId, taskId: string, reason?: string): Promise<TaskAttempt>;
130
132
  readTaskAttempt(tenant: TenantId, taskId: string): Promise<TaskAttempt | undefined>;
131
133
  /** The recorded terminal for a task — the first one, re-encoded canonically under the frozen v1 codec (see `recordTerminal`, `inbound.ts`: the stored body is `encodeEnvelope` of the zod-parsed envelope, not the device's original byte sequence). */
132
134
  readTerminalReceipt(tenant: TenantId, taskId: string): Promise<RequestReceipt | undefined>;
133
135
  /**
134
136
  * Host control plane: the same first terminal, decoded into the typed read
135
137
  * model ({@link TerminalResult}) so a host reads result fields, not envelope
136
- * prose. `undefined` ONLY means no terminal fact is recorded yet:
137
- * first-terminal-wins is inherited from the receipt store
138
- * ({@link ByokCloud.readTerminalReceipt} reads the same row), and a declined
139
- * task records no terminal at all use {@link ByokCloud.readTaskAttempt}
140
- * for that attempt status. An absent `document` covers both a legacy
138
+ * prose. An accepted host cancellation tombstone outranks a later device
139
+ * receipt; the raw receipt remains readable as device evidence through
140
+ * {@link ByokCloud.readTerminalReceipt}. `undefined` means neither fact
141
+ * exists. An absent `document` covers both a legacy
141
142
  * pre-`result-document` daemon build and a daemon with no `resultDocument`
142
143
  * extractor; a receipt whose body is not a terminal envelope throws rather
143
144
  * than returning a best-effort shape.
@@ -151,6 +152,8 @@ export interface ByokCloud {
151
152
  /** Human review authority. Device routes cannot produce `done`. */
152
153
  acceptBoardItem(tenant: TenantId, itemId: string): Promise<BoardItem>;
153
154
  listPresence(tenant: TenantId): Promise<readonly PresenceHint[]>;
155
+ /** SDK-owned observation only; never a scheduler or execution authority. */
156
+ readTenantReadiness(tenant: TenantId): Promise<TenantReadiness>;
154
157
  readActivity(tenant: TenantId, taskId: string): Promise<ActivityTail | undefined>;
155
158
  readApprovalTimeline(tenant: TenantId, taskId: string): Promise<ApprovalTimelineTail | undefined>;
156
159
  }
package/dist/errors.d.ts CHANGED
@@ -41,6 +41,8 @@ export declare const CLOUD_ERROR_CODES: {
41
41
  readonly terminal_receipt_unreadable: 'terminal_receipt_unreadable';
42
42
  /** A progress/activity batch exceeded the configured event or byte ceiling. */
43
43
  readonly activity_batch_too_large: 'activity_batch_too_large';
44
+ /** Host control-plane task lookup is tenant-closed and found no task. */
45
+ readonly task_not_found: 'task_not_found';
44
46
  };
45
47
  export type CloudErrorCode = (typeof CLOUD_ERROR_CODES)[keyof typeof CLOUD_ERROR_CODES];
46
48
  export declare class ByokCloudError extends Error {
package/dist/index.d.ts CHANGED
@@ -34,6 +34,8 @@ export { authenticateBearer, extractBearerToken } from './auth/bearer';
34
34
  export type { BearerAuthDeps } from './auth/bearer';
35
35
  export { DEFAULT_DEVICE_PROOF_CLOCK_SKEW_MS, DEFAULT_DEVICE_PROOF_MAX_LIFETIME_MS, MAX_DEVICE_PROOF_CLOCK_SKEW_MS, MAX_DEVICE_PROOF_MAX_LIFETIME_MS, authenticateDeviceProof, } from './auth/device-proof';
36
36
  export type { AuthenticatedDeviceProof, DeviceProofAuthDeps, DeviceProofRequestBinding, } from './auth/device-proof';
37
+ export { authenticateHostedDeviceAssertion } from './auth/device-assertion';
38
+ export type { HostedDeviceAssertionAuthDeps } from './auth/device-assertion';
37
39
  export { DEVICE_IDENTITY_PROOF_KEY_EPOCH, DEVICE_IDENTITY_PROOF_KEY_ID, PAIRING_CODE_TTL_MS, createAuthPlane, } from './auth/plane';
38
40
  export type { AuthPlane, AuthPlaneDeps, MintedAccessToken, PairInput } from './auth/plane';
39
41
  export { createWebCrypto } from './crypto/web-crypto';
@@ -59,6 +61,6 @@ export { TruthCommitError, isTruthCommitError } from './truth/errors';
59
61
  export type { TruthCommitErrorCode } from './truth/errors';
60
62
  export { CLOUD_STORE_NAMES, TASK_ATTEMPT_STATUSES } from './stores/ports';
61
63
  export { CLOUD_PORT_INTERFACES, CLOUD_PORT_METHODS } from './stores/ports-contract';
62
- export type { BlobContent, BlobContentProxy, BlobDeclaration, BlobObservation, BlobWriteResult, CloudBlobStore, CloudStoreName, CloudStores, DeviceDirectory, DeviceRecord, DeviceRegistration, InboundDedupStore, InboundRateLimiter, NonceStore, PairingCodeClaims, PairingCodeInfo, PairingCodeIssueInput, PairingCodeStore, ProofRequestReceipt, ProofRequestReceiptInput, ProofRequestReceiptStore, RequestReceipt, RequestReceiptStore, TaskAttempt, TaskAttemptStatus, TaskAttemptStore, } from './stores/ports';
63
- export { AllowAllRateLimiter, BLOB_URL_TTL_MS, DEDUP_RING_CAPACITY, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryActivityStore, InMemoryDeviceDirectory, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryRequestReceiptStore, InMemoryProofRequestReceiptStore, InMemoryTaskAttemptStore, NONCE_TTL_MS, createInMemoryBlobs, createInMemoryCloudStores, } from './stores/in-memory/index';
64
+ export type { BlobContent, BlobContentProxy, BlobDeclaration, BlobObservation, BlobWriteResult, CloudBlobStore, CloudStoreName, CloudStores, DeviceDirectory, DeviceRecord, DeviceRegistration, InboundDedupStore, InboundRateLimiter, NonceStore, PairingCodeClaims, PairingCodeInfo, PairingCodeIssueInput, PairingCodeStore, ProofRequestReceipt, ProofRequestReceiptInput, ProofRequestReceiptStore, RequestReceipt, RequestReceiptStore, TaskAttempt, TaskAttemptStatus, TaskAttemptStore, TaskCancellationMutation, TaskCancellationRequest, TaskCancellationStore, } from './stores/ports';
65
+ export { AllowAllRateLimiter, BLOB_URL_TTL_MS, DEDUP_RING_CAPACITY, InMemoryBlobContentProxy, InMemoryCloudBlobStore, InMemoryActivityStore, InMemoryDeviceDirectory, InMemoryInboundDedupStore, InMemoryNonceStore, InMemoryPairingCodeStore, InMemoryRequestReceiptStore, InMemoryProofRequestReceiptStore, InMemoryTaskAttemptStore, InMemoryTaskCancellationStore, NONCE_TTL_MS, createInMemoryBlobs, createInMemoryCloudStores, } from './stores/in-memory/index';
64
66
  export type { InMemoryBlobStoreOptions, InMemoryBlobs, InMemoryCloudComposition, } from './stores/in-memory/index';