@verentis/sdk 0.2.3 → 0.2.5

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.cts CHANGED
@@ -26,6 +26,195 @@ interface HeaderActionRegistration {
26
26
  type HeaderActionHandler = () => void | HeaderActionResult | Promise<void | HeaderActionResult>;
27
27
  declare function isHeaderAction(value: unknown): value is HeaderAction;
28
28
 
29
+ type BridgeEventType = HostToAppMessage['type'];
30
+ /** Handles a host message; the resolved value (structured-cloneable, ideally JSON) is the reply. */
31
+ type HostMessageHandler = (payload: unknown) => unknown | Promise<unknown>;
32
+ /** Channel names declared in the manifest `spec.messages`. */
33
+ declare const HOST_MESSAGE_CHANNEL_PATTERN: RegExp;
34
+ type BridgeListener = (data: HostToAppMessage) => void;
35
+ /**
36
+ * PostMessage bridge for communication between an app (iframe) and the
37
+ * workspace host. Handles the initialization handshake, token lifecycle,
38
+ * and app-to-host events (navigate, resize, dirty, etc.).
39
+ */
40
+ declare class Bridge {
41
+ private readonly expectedHostOrigin?;
42
+ private listeners;
43
+ private _initResolve;
44
+ private _initReject;
45
+ private _initTimer;
46
+ private _initPromise;
47
+ private _hostOrigin;
48
+ private _messageHandler;
49
+ private _destroyed;
50
+ private sessionId;
51
+ private actions;
52
+ private requests;
53
+ private hostMessageHandlers;
54
+ private hostMessageRequests;
55
+ private wopiRequests;
56
+ private collaborationRequests;
57
+ constructor(expectedHostOrigin?: string | undefined);
58
+ /** Post `verentis:ready` to the host to start the handshake */
59
+ sendReady(capabilities?: string[]): void;
60
+ /** Wait for the host to send `verentis:init` with context and token */
61
+ waitForInit(): Promise<{
62
+ context: AppContext;
63
+ token: TokenInfo;
64
+ }>;
65
+ /** Get the host origin (available after init) */
66
+ get hostOrigin(): string | null;
67
+ /** Send a message to the host */
68
+ postToHost(message: AppToHostMessage): void;
69
+ /**
70
+ * Navigate to another location in the workspace.
71
+ *
72
+ * @param path A workspace file path (e.g. `/reports/q1.json`) or an absolute
73
+ * http(s) URL. External URLs require the app to declare the
74
+ * `navigation:external` capability in its manifest.
75
+ * @param options Navigation options. Set `newTab: true` to open the target in
76
+ * a new browser tab instead of the current one.
77
+ */
78
+ navigate(path: string, options?: NavigateOptions): void;
79
+ /** Request iframe resize */
80
+ resize(height: number): void;
81
+ /** Update the title displayed by the host */
82
+ setTitle(title: string): void;
83
+ /** Signal unsaved changes to the host */
84
+ setDirty(isDirty: boolean): void;
85
+ /** The trusted parent selects the approved installation, document and action. */
86
+ requestWopiLaunch(): Promise<WopiLaunch>;
87
+ /** Recover only the target selected by a completed server-owned derived operation. */
88
+ requestWopiContinuation(): Promise<WopiContinuation>;
89
+ getWopiStatus(): Promise<WopiSaveStatus>;
90
+ requestWopiSave(generation: number): Promise<WopiSaveCheckpoint>;
91
+ closeWopiSession(): Promise<void>;
92
+ private requestWopi;
93
+ requestNativeCollaboration(command: NativeCollaborationCommand): Promise<unknown>;
94
+ registerAction(descriptor: HeaderAction, handler: HeaderActionHandler): HeaderActionRegistration;
95
+ private publishActions;
96
+ private invokeAction;
97
+ /**
98
+ * Handle messages the workspace sends on a channel declared in the manifest `spec.messages` — for
99
+ * example an agent asking the open app to select a record. The handler's return value is the reply;
100
+ * a thrown error is reported back as the failure. May be called before the init handshake.
101
+ */
102
+ onHostMessage(channel: string, handler: HostMessageHandler): () => void;
103
+ private receiveHostMessage;
104
+ /** Subscribe to a specific message type from the host */
105
+ on(type: BridgeEventType, listener: BridgeListener): () => void;
106
+ /** Clean up event listeners */
107
+ destroy(): void;
108
+ private handleMessage;
109
+ }
110
+
111
+ interface NativeElement {
112
+ id: string;
113
+ version: number;
114
+ versionNonce?: number;
115
+ isDeleted?: boolean;
116
+ [key: string]: unknown;
117
+ }
118
+ interface NativeFile {
119
+ id: string;
120
+ dataURL: string;
121
+ mimeType: string;
122
+ created: number;
123
+ lastRetrieved?: number;
124
+ }
125
+ interface NativeScene {
126
+ elements: NativeElement[];
127
+ files: Record<string, NativeFile>;
128
+ appState: Record<string, unknown>;
129
+ }
130
+ interface NativePointer {
131
+ x: number;
132
+ y: number;
133
+ }
134
+ interface NativeParticipant {
135
+ id: string;
136
+ name: string;
137
+ readOnly: boolean;
138
+ pointer: NativePointer | null;
139
+ /** `agent` marks an agent acting on behalf of a user (same principal, separate connection). */
140
+ kind?: 'user' | 'agent';
141
+ }
142
+ interface NativeSnapshot {
143
+ sequence: number;
144
+ savedSequence: number;
145
+ revision: string;
146
+ readOnly: boolean;
147
+ scene: NativeScene;
148
+ participants: NativeParticipant[];
149
+ }
150
+ interface NativeSaveReceipt {
151
+ generation: number;
152
+ correlation: string;
153
+ revision: string;
154
+ }
155
+ interface NativeSaveResult extends NativeSnapshot {
156
+ receipt: NativeSaveReceipt;
157
+ }
158
+ interface NativeChangeSet {
159
+ operationId: string;
160
+ changes: Array<{
161
+ id: string;
162
+ expectedVersion: number | null;
163
+ element: NativeElement | null;
164
+ }>;
165
+ files?: Record<string, NativeFile>;
166
+ appState?: Record<string, unknown>;
167
+ appStateExpectedSequence?: number;
168
+ }
169
+ type NativeCollaborationCommand = {
170
+ operation: 'join' | 'snapshot' | 'close';
171
+ } | {
172
+ operation: 'apply';
173
+ changes: NativeChangeSet;
174
+ } | {
175
+ operation: 'presence';
176
+ pointer: NativePointer | null;
177
+ } | {
178
+ operation: 'save';
179
+ generation: number;
180
+ correlation: string;
181
+ };
182
+ interface NativeCollaborationRequest {
183
+ type: 'verentis:collaboration:request';
184
+ version: 1;
185
+ sessionId: string;
186
+ requestId: string;
187
+ command: NativeCollaborationCommand;
188
+ }
189
+ interface NativeCollaborationResponse {
190
+ type: 'verentis:collaboration:response';
191
+ version: 1;
192
+ sessionId: string;
193
+ requestId: string;
194
+ result?: NativeSnapshot | NativeSaveResult | null;
195
+ error?: string;
196
+ code?: string;
197
+ }
198
+ declare class NativeCollaborationError extends Error {
199
+ readonly code: string;
200
+ constructor(message: string, code: string);
201
+ }
202
+ declare function isNativeSnapshot(value: unknown): value is NativeSnapshot;
203
+ declare function isNativeSaveResult(value: unknown): value is NativeSaveResult;
204
+ declare function validateNativeCommand(command: NativeCollaborationCommand): void;
205
+ /** Native authority is always selected by the installed workspace host, never by the iframe. */
206
+ declare class NativeCollaborationClient {
207
+ private readonly bridge;
208
+ constructor(bridge: Bridge | null);
209
+ private snapshotRequest;
210
+ join(): Promise<NativeSnapshot>;
211
+ snapshot(): Promise<NativeSnapshot>;
212
+ apply(changes: NativeChangeSet): Promise<NativeSnapshot>;
213
+ presence(value: NativePointer | null): Promise<NativeSnapshot>;
214
+ save(generation: number, correlation: string): Promise<NativeSaveResult>;
215
+ close(): Promise<void>;
216
+ }
217
+
29
218
  interface VerentisMessage {
30
219
  type: `verentis:${string}`;
31
220
  version: 1;
@@ -57,28 +246,73 @@ interface VerentisActionResultMessage extends VerentisMessage {
57
246
  result?: HeaderActionResult;
58
247
  error?: string;
59
248
  }
249
+ /**
250
+ * A message from the workspace (typically an agent acting for the user) on a channel the app declares in
251
+ * its manifest `spec.messages`. Handled with `bridge.onHostMessage(channel, handler)`.
252
+ */
253
+ interface VerentisHostMessage extends VerentisMessage {
254
+ type: 'verentis:host:message';
255
+ sessionId: string;
256
+ requestId: string;
257
+ channel: string;
258
+ payload?: unknown;
259
+ }
260
+ interface VerentisHostReplyMessage extends VerentisMessage {
261
+ type: 'verentis:host:reply';
262
+ sessionId: string;
263
+ requestId: string;
264
+ channel: string;
265
+ result?: unknown;
266
+ error?: string;
267
+ }
60
268
  interface VerentisTokenRefreshedMessage extends VerentisMessage {
61
269
  type: 'verentis:token:refreshed';
62
270
  requestId: string;
63
271
  token: TokenInfo;
64
272
  }
65
- /** Single-use credential for the installation's independently registered backend. */
66
- interface AppBackendCredential {
67
- delegationId: string;
68
- backendClientId: string;
69
- launchCredential: string;
70
- expiresAt: string;
273
+ /** Nonsecret active-document metadata. CODE already holds its own scoped credential. */
274
+ interface WopiContinuation {
275
+ sessionId: string;
276
+ workspaceId: string;
277
+ branch: string;
278
+ nodeId: string;
279
+ accessTokenTtl: number;
280
+ fileId: string;
281
+ format: string;
282
+ readOnly: boolean;
283
+ name: string;
71
284
  }
72
- interface VerentisBackendCredentialRequest extends VerentisMessage {
73
- type: 'verentis:backend:request';
285
+ /** Initial document-scoped collaboration authority, never a platform OAuth credential. */
286
+ interface WopiLaunch extends WopiContinuation {
287
+ action: string;
288
+ accessToken: string;
289
+ editorOrigin: string;
290
+ wopiSource: string;
291
+ }
292
+ interface WopiSaveCheckpoint {
293
+ generation: number;
294
+ correlation: string;
295
+ revision?: string | null;
296
+ }
297
+ interface WopiSaveStatus {
298
+ state: string;
299
+ revision: string;
300
+ readOnly: boolean;
301
+ receipt: WopiSaveCheckpoint | null;
302
+ continuationAvailable?: boolean;
303
+ }
304
+ interface VerentisWopiRequest extends VerentisMessage {
305
+ type: 'verentis:wopi:request';
74
306
  requestId: string;
75
307
  sessionId: string;
308
+ operation: 'launch' | 'status' | 'save' | 'close' | 'continue';
309
+ generation?: number;
76
310
  }
77
- interface VerentisBackendCredentialResponse extends VerentisMessage {
78
- type: 'verentis:backend:response';
311
+ interface VerentisWopiResponse extends VerentisMessage {
312
+ type: 'verentis:wopi:response';
79
313
  requestId: string;
80
314
  sessionId: string;
81
- credential?: AppBackendCredential;
315
+ result?: WopiLaunch | WopiContinuation | WopiSaveCheckpoint | WopiSaveStatus | null;
82
316
  error?: string;
83
317
  }
84
318
  interface VerentisFileChangedMessage extends VerentisMessage {
@@ -118,19 +352,26 @@ interface VerentisDirtyMessage extends VerentisMessage {
118
352
  type: 'verentis:dirty';
119
353
  isDirty: boolean;
120
354
  }
121
- type HostToAppMessage = VerentisInitMessage | VerentisActionInvokeMessage | VerentisTokenRefreshedMessage | VerentisFileChangedMessage | VerentisThemeMessage | VerentisBackendCredentialResponse;
122
- type AppToHostMessage = VerentisReadyMessage | VerentisActionsSetMessage | VerentisActionResultMessage | VerentisTokenRefreshMessage | VerentisNavigateMessage | VerentisResizeMessage | VerentisTitleMessage | VerentisDirtyMessage | VerentisBackendCredentialRequest;
355
+ type HostToAppMessage = VerentisInitMessage | VerentisActionInvokeMessage | VerentisHostMessage | VerentisTokenRefreshedMessage | VerentisFileChangedMessage | VerentisThemeMessage | VerentisWopiResponse | NativeCollaborationResponse;
356
+ type AppToHostMessage = VerentisReadyMessage | VerentisActionsSetMessage | VerentisActionResultMessage | VerentisHostReplyMessage | VerentisTokenRefreshMessage | VerentisNavigateMessage | VerentisResizeMessage | VerentisTitleMessage | VerentisDirtyMessage | VerentisWopiRequest | NativeCollaborationRequest;
123
357
  type AppSurface = 'file' | 'workspace';
124
358
  interface AppContextBase {
359
+ application?: AppApplicationContext;
125
360
  workspace: WorkspaceInfo;
126
361
  entryPoint?: EntryPointInfo;
127
362
  apiUrl: string;
128
363
  installation?: {
129
364
  id: string;
130
- backendClientId: string;
131
- authorizationGeneration: string;
365
+ backendClientId?: string;
366
+ authorizationGeneration?: string;
367
+ wopiEnabled?: boolean;
132
368
  };
133
369
  }
370
+ interface AppApplicationContext {
371
+ manifestPath: string;
372
+ manifestNodeId: string;
373
+ branch: string;
374
+ }
134
375
  /** Context for an application opened against a workspace file. */
135
376
  interface FileAppContext extends AppContextBase {
136
377
  surface: 'file';
@@ -225,6 +466,33 @@ interface FileEntry {
225
466
  version?: string;
226
467
  etag?: string;
227
468
  children?: FileEntry[];
469
+ /** Stable node identity, when supplied by the path metadata API. */
470
+ nodeId?: string;
471
+ }
472
+ interface NodeFileMetadata {
473
+ nodeId: string;
474
+ path: string;
475
+ name: string;
476
+ mimeType: string;
477
+ size?: number | null;
478
+ /** Unquoted opaque content revision; distinct from a path delete head stamp. */
479
+ etag: string;
480
+ version: string;
481
+ children?: PagedResult<FileEntry>;
482
+ }
483
+ interface NodeFileOptions {
484
+ branch: string;
485
+ }
486
+ interface NodeFileContent {
487
+ content: Blob;
488
+ /** Strong quoted ETag returned by the node-content API. */
489
+ revision: string;
490
+ }
491
+ interface WriteNodeFileOptions extends NodeFileOptions {
492
+ content: Blob | string | ArrayBuffer;
493
+ /** Strong quoted revision, or the unquoted etag returned by getNode. */
494
+ revision: string;
495
+ idempotencyKey: string;
228
496
  }
229
497
  interface GetFileOptions {
230
498
  branch?: string;
@@ -237,6 +505,8 @@ interface WriteFileOptions {
237
505
  contentType?: string;
238
506
  filename?: string;
239
507
  branch?: string;
508
+ /** Atomically require no live file at this path; conflicts return HTTP 412. */
509
+ createOnly?: boolean;
240
510
  }
241
511
  interface MoveFileOptions {
242
512
  from: string;
@@ -246,6 +516,10 @@ interface MoveFileOptions {
246
516
  interface DeleteFileOptions {
247
517
  path: string;
248
518
  branch?: string;
519
+ /** Path-binding head stamp, not a node-content revision. */
520
+ headStamp?: string;
521
+ idempotencyKey?: string;
522
+ mode?: 'shallow' | 'deep';
249
523
  }
250
524
  type ArchiveFormat = 'zip' | 'tgz';
251
525
  interface ReadArchiveOptions {
@@ -280,6 +554,64 @@ interface InstalledPackageDescriptor {
280
554
  payloads: InstalledPackagePayload[];
281
555
  }
282
556
  type InstallationMode = 'Extracted' | 'Sealed';
557
+ /** Required dependencies use immutable exact SemVer pins; optional packages are never implicit installs. */
558
+ interface PackageDependency {
559
+ package: string;
560
+ version: string;
561
+ installPath?: string | null;
562
+ optional?: boolean;
563
+ }
564
+ interface InstallationGraphPackage {
565
+ packageId: string;
566
+ packageVersionId: string;
567
+ publisherId: string;
568
+ identity: string;
569
+ publisher: string;
570
+ version: string;
571
+ treeDigest: string;
572
+ artifactFingerprint: string;
573
+ manifestYaml: string;
574
+ verifiedSigningKeyKid?: string | null;
575
+ branch: string;
576
+ installPath: string;
577
+ installMode: InstallationMode;
578
+ reuseInstallationId?: string | null;
579
+ /** Only a previously Failed exact target can be recovered, after a fresh explicit preview. */
580
+ retryInstallationId?: string | null;
581
+ permissions: string[];
582
+ dependencies: PackageDependency[];
583
+ /** Conservative destination reservations, including external install-map/seed roots. */
584
+ installPaths: string[];
585
+ }
586
+ interface InstallationGraphPreview {
587
+ operationId: string;
588
+ workspaceId: string;
589
+ expiresAt: string;
590
+ fingerprint: string;
591
+ /** Topological installation order: required dependencies before their dependents. */
592
+ packages: InstallationGraphPackage[];
593
+ }
594
+ type InstallationGraphOutcomeStatus = 'Pending' | 'Installing' | 'Reused' | 'Installed' | 'InstalledWithError' | 'Failed' | 'NotAttempted';
595
+ interface InstallationGraphResult {
596
+ operationId: string;
597
+ status: 'Preview' | 'Accepted' | 'Completed' | 'Rejected' | 'Failed';
598
+ succeeded: boolean;
599
+ /** The exact durable preview baseline, also available after a lost preview/install response. */
600
+ packages: InstallationGraphPackage[];
601
+ outcomes: {
602
+ identity: string;
603
+ status: InstallationGraphOutcomeStatus;
604
+ installationId?: string | null;
605
+ error?: string | null;
606
+ }[];
607
+ error?: string | null;
608
+ }
609
+ interface PreviewInstallationOptions extends InstallationScopedOptions {
610
+ packageVersion?: string;
611
+ installPath?: string;
612
+ branch?: string;
613
+ installMode?: InstallationMode;
614
+ }
283
615
  type InstallationStatus = 'Pending' | 'Installing' | 'Installed' | 'Updating' | 'Uninstalling' | 'Failed' | 'Uninstalled';
284
616
  interface Installation {
285
617
  id: string;
@@ -459,6 +791,9 @@ interface ApplicationEntryPoint {
459
791
  display?: ApplicationDisplayOptions;
460
792
  }
461
793
  interface ApplicationSpec {
794
+ dependencies?: PackageDependency[];
795
+ /** Publisher-qualified required engine dependency for script-bearing packages. */
796
+ engine?: string;
462
797
  /** Optional iframe UI surface URL. Omit for a headless / file-collection app. */
463
798
  entry?: string;
464
799
  /** Optional application splash URL. Relative values resolve against the selected iframe entry URL. */
@@ -785,7 +1120,8 @@ declare class ApiError extends Error {
785
1120
  readonly status: number;
786
1121
  readonly detail: string;
787
1122
  readonly title?: string | undefined;
788
- constructor(status: number, detail: string, title?: string | undefined);
1123
+ readonly code?: string | undefined;
1124
+ constructor(status: number, detail: string, title?: string | undefined, code?: string | undefined);
789
1125
  }
790
1126
 
791
1127
  /**
@@ -799,6 +1135,8 @@ declare class ContextModule {
799
1135
  private _file;
800
1136
  private _entryPoint;
801
1137
  private _apiUrl;
1138
+ private _application;
1139
+ private _installation;
802
1140
  /** The current workspace */
803
1141
  get workspace(): WorkspaceInfo;
804
1142
  /** The host surface that launched the app */
@@ -813,6 +1151,8 @@ declare class ContextModule {
813
1151
  get entryPoint(): EntryPointInfo | null;
814
1152
  /** Whether an entry point context is available */
815
1153
  get hasEntryPoint(): boolean;
1154
+ get application(): AppApplicationContext | null;
1155
+ get installation(): AppContext['installation'] | null;
816
1156
  /** Update context from the host's init message */
817
1157
  setFromAppContext(ctx: AppContext): void;
818
1158
  /** Set workspace info directly (standalone mode) */
@@ -835,6 +1175,7 @@ declare class HttpTransport {
835
1175
  constructor(baseUrl: string, auth: AuthStrategy, apiVersion?: string);
836
1176
  request<T>(method: string, path: string, options?: RequestOptions): Promise<T>;
837
1177
  requestRaw(method: string, path: string, options?: RequestOptions): Promise<Response>;
1178
+ ensureSuccess(response: Response): Promise<void>;
838
1179
  private buildUrl;
839
1180
  }
840
1181
 
@@ -904,6 +1245,12 @@ declare class FilesModule {
904
1245
  * For directories: returns metadata with children array populated.
905
1246
  */
906
1247
  get(path: string, options?: GetFileOptions): Promise<FileEntry>;
1248
+ /** Read metadata by stable node identity on an explicit branch. */
1249
+ getNode(nodeId: string, options: NodeFileOptions): Promise<NodeFileMetadata>;
1250
+ /** Read bytes and their matching content revision in the same response. */
1251
+ readNodeContent(nodeId: string, options: NodeFileOptions): Promise<NodeFileContent>;
1252
+ /** Replace existing node bytes conditionally; never creates or changes path/MIME. */
1253
+ writeNodeContent(nodeId: string, options: WriteNodeFileOptions): Promise<NodeFileMetadata>;
907
1254
  /**
908
1255
  * Read the raw content of a file as a Blob.
909
1256
  */
@@ -927,6 +1274,8 @@ declare class FilesModule {
927
1274
  * Upload or create a file.
928
1275
  */
929
1276
  write(path: string, options: WriteFileOptions): Promise<void>;
1277
+ /** Create without a read-before-write race or overwrite of an existing live file. */
1278
+ create(path: string, options: WriteFileOptions): Promise<void>;
930
1279
  /**
931
1280
  * Move or rename a file.
932
1281
  */
@@ -943,6 +1292,14 @@ declare class InstallationsModule {
943
1292
  private readonly http;
944
1293
  private readonly workspaceId?;
945
1294
  constructor(http: HttpTransport, workspaceId?: string | undefined);
1295
+ /** Resolve canonical publisher/package identity, never the installation's runtime display name. */
1296
+ resolvePackageId(identity: string, options?: InstallationScopedOptions): Promise<string>;
1297
+ /** Resolves the complete required graph without installing anything or granting capabilities. */
1298
+ preview(packageId: string, options?: PreviewInstallationOptions): Promise<InstallationGraphPreview>;
1299
+ /** Explicit, single-use consent to a displayed preview. Never automatically retries accepted installs. */
1300
+ install(preview: InstallationGraphPreview, consent: true): Promise<InstallationGraphResult>;
1301
+ /** Inspect durable outcomes after a failure or lost response instead of resubmitting consent. */
1302
+ graphResult(operationId: string, options?: InstallationScopedOptions): Promise<InstallationGraphResult>;
946
1303
  list(options?: InstallationListOptions): Promise<PagedResult<Installation>>;
947
1304
  resolve(installPath: string, options?: ResolveInstallationOptions): Promise<InstallationDetail>;
948
1305
  update(id: string, options?: UpdateInstallationOptions): Promise<InstallationLifecycleResult>;
@@ -1012,65 +1369,257 @@ interface NamespacedSettings {
1012
1369
  reset(key: string, options?: SettingsScopedOptions): Promise<void>;
1013
1370
  }
1014
1371
 
1015
- type BridgeEventType = HostToAppMessage['type'];
1016
- type BridgeListener = (data: HostToAppMessage) => void;
1372
+ interface EmailScopedOptions {
1373
+ workspaceId?: string;
1374
+ branch?: 'main';
1375
+ }
1376
+ interface EmailHistoryOptions extends EmailScopedOptions {
1377
+ recordId?: string;
1378
+ installationId?: string;
1379
+ }
1380
+ interface EmailPurpose {
1381
+ name: string;
1382
+ templateId: string;
1383
+ maximumRecipients: number;
1384
+ maximumAttachmentBytes: number;
1385
+ allowsOpenTracking: boolean;
1386
+ allowsClickTracking: boolean;
1387
+ senderRequirement: 'workspace-owned' | 'managed-or-workspace';
1388
+ }
1389
+ interface EmailSenderGrant {
1390
+ purpose: string;
1391
+ senderId: string;
1392
+ senderIdentityDigest?: string;
1393
+ }
1394
+ interface EmailConsentPreview {
1395
+ installationId: string;
1396
+ workspaceId: string;
1397
+ accountId: string;
1398
+ packageId: string;
1399
+ packageVersionId: string;
1400
+ publisherId: string;
1401
+ publisherName: string;
1402
+ version: string;
1403
+ treeDigest: string;
1404
+ signingKeyId: string;
1405
+ installPath: string;
1406
+ branch: string;
1407
+ candidateDigest: string;
1408
+ declaration: {
1409
+ purposes: EmailPurpose[];
1410
+ maximumMessagesPerHour: number;
1411
+ permissions: string[];
1412
+ scopes: string[];
1413
+ manifestDigest: string;
1414
+ };
1415
+ }
1416
+ interface EmailConsent {
1417
+ installationId: string;
1418
+ candidateDigest: string;
1419
+ enabled: boolean;
1420
+ allowOpenTracking: boolean;
1421
+ allowClickTracking: boolean;
1422
+ approvedBy: string;
1423
+ updatedAt: string;
1424
+ senderGrants: EmailSenderGrant[] | null;
1425
+ }
1426
+ interface EmailConsentOptions {
1427
+ senderGrants: EmailSenderGrant[];
1428
+ allowOpenTracking?: boolean;
1429
+ allowClickTracking?: boolean;
1430
+ }
1431
+ interface EmailSenderIdentity {
1432
+ id: string;
1433
+ mode: 'managed' | 'custom';
1434
+ displayName: string;
1435
+ address: string;
1436
+ }
1437
+ interface EmailArtifactOutcome {
1438
+ artifactId: string;
1439
+ sha256: string;
1440
+ byteLength: number;
1441
+ fileName: string;
1442
+ }
1443
+ interface EmailDispatchOptions extends EmailScopedOptions {
1444
+ installationId: string;
1445
+ recordId: string;
1446
+ purpose: string;
1447
+ templateId: string;
1448
+ senderId: string;
1449
+ recipients: string[];
1450
+ artifactIds: string[];
1451
+ idempotencyKey: string;
1452
+ replyTo?: string;
1453
+ }
1454
+ interface EmailDispatchOutcome {
1455
+ id: string;
1456
+ status: 'accepted' | 'delivered' | 'failed' | 'unknown';
1457
+ createdAt: string;
1458
+ failureCode?: string | null;
1459
+ recordId: string;
1460
+ installationId: string;
1461
+ branch: 'main';
1462
+ purpose: string;
1463
+ templateId: string;
1464
+ events: EmailDeliveryEvidence[];
1465
+ }
1466
+ interface EmailDeliveryEvidence {
1467
+ type: 'processed' | 'deferred' | 'delivered' | 'failed' | 'complaint' | 'unsubscribe' | 'open' | 'click';
1468
+ occurredAt: string;
1469
+ }
1470
+
1471
+ /** Signed-package transactional email. Dispatch never accepts HTML, From or a browser invoice snapshot. */
1472
+ declare class EmailModule {
1473
+ private readonly http;
1474
+ private readonly workspaceId?;
1475
+ constructor(http: HttpTransport, workspaceId?: string | undefined);
1476
+ preview(installationId: string, options?: EmailScopedOptions): Promise<EmailConsentPreview>;
1477
+ consents(options?: EmailScopedOptions): Promise<EmailConsent[]>;
1478
+ /** Approve exactly the reviewed signed candidate; tracking stays off unless explicitly opted in. */
1479
+ consent(preview: EmailConsentPreview, approval: true, options: EmailConsentOptions): Promise<EmailConsent>;
1480
+ revoke(consent: EmailConsent, options?: EmailScopedOptions): Promise<EmailConsent>;
1481
+ senders(options?: EmailScopedOptions): Promise<EmailSenderIdentity[]>;
1482
+ invoicePdf(recordId: string, installationId: string, options?: EmailScopedOptions): Promise<EmailArtifactOutcome>;
1483
+ /** Authenticated immutable bytes; no public URL. The caller owns any local object URL it creates. */
1484
+ artifactContent(artifactId: string, options?: EmailScopedOptions): Promise<Blob>;
1485
+ /** A stable key binds this exact request. After a lost response inspect status; never automatically resend. */
1486
+ dispatch(options: EmailDispatchOptions): Promise<EmailDispatchOutcome>;
1487
+ outcome(id: string, options?: EmailScopedOptions): Promise<EmailDispatchOutcome>;
1488
+ history(options?: EmailHistoryOptions): Promise<EmailDispatchOutcome[]>;
1489
+ status(id: string, options?: EmailScopedOptions): Promise<EmailDispatchOutcome>;
1490
+ private workspace;
1491
+ private mainBranch;
1492
+ }
1493
+
1494
+ type BusinessOperation = 'save-record' | 'archive-record' | 'delete-record' | 'restore-record' | 'close-period' | 'issue-invoice' | 'credit-invoice' | 'post-payment' | 'reverse-payment' | 'post-journal' | 'reverse-journal' | 'post-expense' | 'reverse-expense';
1495
+ interface BusinessParameters {
1496
+ periodId?: string;
1497
+ receivableAccountId?: string;
1498
+ incomeAccountId?: string;
1499
+ taxAccountId?: string;
1500
+ date?: string;
1501
+ reason?: string;
1502
+ }
1503
+ interface BusinessCommand {
1504
+ operation: BusinessOperation;
1505
+ idempotencyKey: string;
1506
+ /** Omit only when creating; the server derives a stable ID from this operation key. */
1507
+ recordId?: string;
1508
+ /** Canonical kind, e.g. crm/company. Required for metadata-free creation. */
1509
+ kind?: string;
1510
+ expectedCatalogueRevision?: string;
1511
+ /** Exact strong, quoted canonical revision; omit only for a new record. */
1512
+ expectedRevision?: string;
1513
+ record?: Record<string, unknown>;
1514
+ parameters?: BusinessParameters;
1515
+ }
1516
+ interface BusinessSnapshot {
1517
+ id: string;
1518
+ kind: string;
1519
+ json: string;
1520
+ revision: string;
1521
+ }
1522
+ interface BusinessContext {
1523
+ workspaceId: string;
1524
+ branch: string;
1525
+ catalogueRevision: string | null;
1526
+ settings: BusinessSnapshot[];
1527
+ }
1528
+ interface BusinessCommitResult {
1529
+ operationId: string;
1530
+ committedAt: string;
1531
+ records: BusinessSnapshot[];
1532
+ }
1533
+ interface BusinessOutcomeRequest {
1534
+ operation: BusinessOperation;
1535
+ idempotencyKey: string;
1536
+ requestHash?: string;
1537
+ command?: BusinessCommand;
1538
+ }
1539
+ type BusinessReportName = 'trial-balance' | 'general-ledger' | 'profit-and-loss' | 'balance-sheet' | 'receivables';
1540
+ interface BusinessReportLine {
1541
+ accountId: string;
1542
+ code: string;
1543
+ name: string;
1544
+ accountType: 'asset' | 'liability' | 'equity' | 'income' | 'expense';
1545
+ debitMinor: string;
1546
+ creditMinor: string;
1547
+ balanceMinor: string;
1548
+ }
1549
+ interface BusinessReport {
1550
+ report: BusinessReportName;
1551
+ from: string | null;
1552
+ to: string | null;
1553
+ lines: BusinessReportLine[];
1554
+ entries: BusinessLedgerEntry[];
1555
+ /** Coherent catalogue revision and overdue evaluation date for receivables. */
1556
+ revision?: string;
1557
+ asOf?: string;
1558
+ currency?: string;
1559
+ minorDigits?: number;
1560
+ receivables?: BusinessReceivable[];
1561
+ totals?: BusinessReceivableTotals;
1562
+ }
1563
+ interface BusinessReceivable {
1564
+ invoiceId: string;
1565
+ revision: string;
1566
+ invoiceNumber: string;
1567
+ issueDate: string;
1568
+ dueDate: string;
1569
+ currency: string;
1570
+ minorDigits: number;
1571
+ customer: Record<string, unknown>;
1572
+ customerReference?: Record<string, unknown>;
1573
+ grossAmountMinor: string;
1574
+ creditedAmountMinor: string;
1575
+ paidAmountMinor: string;
1576
+ outstandingAmountMinor: string;
1577
+ overdueAmountMinor: string;
1578
+ isOverdue: boolean;
1579
+ daysOverdue: number;
1580
+ }
1581
+ interface BusinessReceivableTotals {
1582
+ grossAmountMinor: string;
1583
+ creditedAmountMinor: string;
1584
+ paidAmountMinor: string;
1585
+ outstandingAmountMinor: string;
1586
+ overdueAmountMinor: string;
1587
+ }
1588
+ interface BusinessLedgerEntry {
1589
+ journalId: string;
1590
+ date: string;
1591
+ description: string;
1592
+ accountId: string;
1593
+ direction: 'debit' | 'credit';
1594
+ amountMinor: string;
1595
+ runningBalanceMinor: string;
1596
+ }
1597
+
1017
1598
  /**
1018
- * PostMessage bridge for communication between an app (iframe) and the
1019
- * workspace host. Handles the initialization handshake, token lifecycle,
1020
- * and app-to-host events (navigate, resize, dirty, etc.).
1599
+ * Trusted workspace business records, independent of app scripts or generic file writes.
1600
+ * Never automatically retries a command: resolve a lost response with outcome() or
1601
+ * resubmit the exact same command/key to obtain the original durable result.
1021
1602
  */
1022
- declare class Bridge {
1023
- private readonly expectedHostOrigin?;
1024
- private listeners;
1025
- private _initResolve;
1026
- private _initReject;
1027
- private _initTimer;
1028
- private _initPromise;
1029
- private _hostOrigin;
1030
- private _messageHandler;
1031
- private _destroyed;
1032
- private sessionId;
1033
- private actions;
1034
- private requests;
1035
- private backendRequests;
1036
- constructor(expectedHostOrigin?: string | undefined);
1037
- /** Post `verentis:ready` to the host to start the handshake */
1038
- sendReady(capabilities?: string[]): void;
1039
- /** Wait for the host to send `verentis:init` with context and token */
1040
- waitForInit(): Promise<{
1041
- context: AppContext;
1042
- token: TokenInfo;
1043
- }>;
1044
- /** Get the host origin (available after init) */
1045
- get hostOrigin(): string | null;
1046
- /** Send a message to the host */
1047
- postToHost(message: AppToHostMessage): void;
1048
- /**
1049
- * Navigate to another location in the workspace.
1050
- *
1051
- * @param path A workspace file path (e.g. `/reports/q1.json`) or an absolute
1052
- * http(s) URL. External URLs require the app to declare the
1053
- * `navigation:external` capability in its manifest.
1054
- * @param options Navigation options. Set `newTab: true` to open the target in
1055
- * a new browser tab instead of the current one.
1056
- */
1057
- navigate(path: string, options?: NavigateOptions): void;
1058
- /** Request iframe resize */
1059
- resize(height: number): void;
1060
- /** Update the title displayed by the host */
1061
- setTitle(title: string): void;
1062
- /** Signal unsaved changes to the host */
1063
- setDirty(isDirty: boolean): void;
1064
- /** The host, not the app, selects the installation, file, branch and permission ceiling. */
1065
- requestBackendCredential(): Promise<AppBackendCredential>;
1066
- registerAction(descriptor: HeaderAction, handler: HeaderActionHandler): HeaderActionRegistration;
1067
- private publishActions;
1068
- private invokeAction;
1069
- /** Subscribe to a specific message type from the host */
1070
- on(type: BridgeEventType, listener: BridgeListener): () => void;
1071
- /** Clean up event listeners */
1072
- destroy(): void;
1073
- private handleMessage;
1603
+ declare class BusinessModule {
1604
+ private readonly http;
1605
+ private readonly branch;
1606
+ constructor(http: HttpTransport, branch?: string);
1607
+ withBranch(branch: string): BusinessModule;
1608
+ context(): Promise<BusinessContext>;
1609
+ command(command: BusinessCommand): Promise<BusinessCommitResult>;
1610
+ read(id: string): Promise<BusinessSnapshot | null>;
1611
+ list(kind?: string): Promise<BusinessSnapshot[]>;
1612
+ /** null means unresolved, not success; do not invent a new operation key. */
1613
+ outcome(request: BusinessOutcomeRequest): Promise<BusinessCommitResult | null>;
1614
+ /** Recover using the exact original command, without reproducing server fingerprint encoding. */
1615
+ outcomeFor(command: BusinessCommand): Promise<BusinessCommitResult | null>;
1616
+ report(report: BusinessReportName, range?: {
1617
+ from?: string;
1618
+ to?: string;
1619
+ }): Promise<BusinessReport>;
1620
+ /** Retained historical expense receipt bytes, even after the original native file is removed. */
1621
+ receipt(nodeId: string, revision: string): Promise<Blob>;
1622
+ private headers;
1074
1623
  }
1075
1624
 
1076
1625
  /**
@@ -1085,8 +1634,11 @@ declare class VerentisClient {
1085
1634
  installations: InstallationsModule;
1086
1635
  resources: ResourcesModule;
1087
1636
  settings: SettingsModule;
1637
+ email: EmailModule;
1638
+ business: BusinessModule;
1088
1639
  readonly context: ContextModule;
1089
1640
  readonly bridge: Bridge | null;
1641
+ readonly collaboration: NativeCollaborationClient;
1090
1642
  private readonly _auth;
1091
1643
  private _http;
1092
1644
  private _ready;
@@ -1097,6 +1649,12 @@ declare class VerentisClient {
1097
1649
  * In iframe mode this resolves after the host sends `verentis:init`.
1098
1650
  */
1099
1651
  whenReady(): Promise<void>;
1652
+ /**
1653
+ * The current `Authorization` header value, refreshed when near expiry.
1654
+ * Forward it to the app's own backend, which exchanges it at Security's
1655
+ * `/connect/token` (RFC 8693) as the installation's confidential client.
1656
+ */
1657
+ getAuthorizationHeader(): Promise<string | null>;
1100
1658
  /** Clean up resources (timers, event listeners) */
1101
1659
  destroy(): void;
1102
1660
  private initFromBridge;
@@ -1115,6 +1673,36 @@ declare function matchMimeType(pattern: string, mimeType: string): boolean;
1115
1673
  */
1116
1674
  declare function findBestMatch(mimeType: string, bindings: MimeTypeBinding[]): MimeTypeBinding | null;
1117
1675
 
1676
+ interface CollaborationDocumentContext {
1677
+ workspace?: {
1678
+ id?: string;
1679
+ };
1680
+ file?: {
1681
+ nodeId?: string;
1682
+ branch?: string;
1683
+ };
1684
+ }
1685
+ interface CollaborationDocument {
1686
+ sessionId: string;
1687
+ workspaceId: string;
1688
+ branch: string;
1689
+ nodeId: string;
1690
+ fileId: string;
1691
+ name: string;
1692
+ readOnly: boolean;
1693
+ accessTokenTtl: number;
1694
+ }
1695
+ /** An exact origin, not a URL pattern or an authority grant. */
1696
+ declare function exactHttpsOrigin(value: unknown): string;
1697
+ declare function isTrustedMessage(event: {
1698
+ source: unknown;
1699
+ origin: string;
1700
+ }, source: unknown, origin: string): boolean;
1701
+ /** Checks nonsecret launch metadata against the document selected by the trusted host. */
1702
+ declare function validateCollaborationDocument(value: unknown, context: CollaborationDocumentContext, now?: number): CollaborationDocument;
1703
+ /** An editor acknowledgement alone never proves a document was durably saved. */
1704
+ declare function isDurableSaveConfirmed(result: unknown, request: unknown, currentGeneration: number, editorModified: boolean): boolean;
1705
+
1118
1706
  /**
1119
1707
  * Authenticates with a Verentis API key (`vrt_` prefix).
1120
1708
  * The backend detects the `vrt_` prefix in the Bearer token and resolves it
@@ -1202,4 +1790,4 @@ declare class BridgeAuth implements AuthStrategy {
1202
1790
  */
1203
1791
  declare function createVerentisClient(options?: VerentisClientOptions): VerentisClient;
1204
1792
 
1205
- export { ApiError, ApiKeyAuth, type AppBackendCredential, type AppContext, type AppSurface, type AppToHostMessage, type ApplicationDisplayOptions, type ApplicationEntryPoint, type ApplicationFileType, type ApplicationLaunchConfig, type ApplicationManifest, type ApplicationSpec, type ArchiveFormat, type AuthOptions, type AuthStrategy, Bridge, BridgeAuth, type CatalogImage, ContextModule, type DeleteFileOptions, type EngineFileType, type EngineRuntime, type EngineTool, EnginesModule, type EntryPointInfo, type ExecuteEngineOptions, type Execution, type ExecutionEngine, type ExecutionEngineListOptions, type ExecutionListOptions, type ExecutionLogs, type ExecutionMode, type ExecutionResult, type ExecutionScopedOptions, type ExecutionStatus, type ExecutionTrigger, ExecutionsModule, type ExtractUploadOptions, type FileAppContext, type FileEntry, type FileInfo, FilesModule, type GetFileOptions, type HeaderAction, type HeaderActionHandler, type HeaderActionRegistration, type HeaderActionResult, type HostToAppMessage, HttpTransport, type Installation, type InstallationDetail, type InstallationLifecycleResult, type InstallationListOptions, type InstallationMode, type InstallationScopedOptions, type InstallationStatus, InstallationsModule, type InstalledPackageDescriptor, type InstalledPackagePayload, type ManifestMetadata, type MimeTypeBinding, type MoveFileOptions, type NamespacedSettings, type NavigateOptions, type OAuthConfig, type PagedResult, type ReadArchiveOptions, type RequestOptions, type ResolveInstallationOptions, type ResourceMimeTypeBinding, type ResourceRegistration, type ResourceScopedOptions, ResourcesModule, type RunFileOptions, type SandboxOptions, type SettingDeclaration, type SettingDeclarationType, type SettingGroup, type SettingItem, type SettingOption, type SettingPresence, SettingsModule, type SettingsScopedOptions, TokenAuth, type TokenInfo, type UpdateInstallationOptions, type VerentisActionInvokeMessage, type VerentisActionResultMessage, type VerentisActionsSetMessage, type VerentisBackendCredentialRequest, type VerentisBackendCredentialResponse, VerentisClient, type VerentisClientOptions, type VerentisDirtyMessage, type VerentisFileChangedMessage, type VerentisInitMessage, type VerentisMessage, type VerentisNavigateMessage, type VerentisReadyMessage, type VerentisResizeMessage, type VerentisThemeMessage, type VerentisTitleMessage, type VerentisTokenRefreshMessage, type VerentisTokenRefreshedMessage, type WaitOptions, type WorkspaceAppContext, type WorkspaceInfo, type WriteFileOptions, createVerentisClient, findBestMatch, isHeaderAction, isTerminalStatus, matchMimeType };
1793
+ export { ApiError, ApiKeyAuth, type AppApplicationContext, type AppContext, type AppSurface, type AppToHostMessage, type ApplicationDisplayOptions, type ApplicationEntryPoint, type ApplicationFileType, type ApplicationLaunchConfig, type ApplicationManifest, type ApplicationSpec, type ArchiveFormat, type AuthOptions, type AuthStrategy, Bridge, BridgeAuth, type BusinessCommand, type BusinessCommitResult, type BusinessContext, type BusinessLedgerEntry, BusinessModule, type BusinessOperation, type BusinessOutcomeRequest, type BusinessParameters, type BusinessReceivable, type BusinessReceivableTotals, type BusinessReport, type BusinessReportLine, type BusinessReportName, type BusinessSnapshot, type CatalogImage, type CollaborationDocument, type CollaborationDocumentContext, ContextModule, type DeleteFileOptions, type EmailArtifactOutcome, type EmailConsent, type EmailConsentOptions, type EmailConsentPreview, type EmailDeliveryEvidence, type EmailDispatchOptions, type EmailDispatchOutcome, type EmailHistoryOptions, EmailModule, type EmailPurpose, type EmailScopedOptions, type EmailSenderGrant, type EmailSenderIdentity, type EngineFileType, type EngineRuntime, type EngineTool, EnginesModule, type EntryPointInfo, type ExecuteEngineOptions, type Execution, type ExecutionEngine, type ExecutionEngineListOptions, type ExecutionListOptions, type ExecutionLogs, type ExecutionMode, type ExecutionResult, type ExecutionScopedOptions, type ExecutionStatus, type ExecutionTrigger, ExecutionsModule, type ExtractUploadOptions, type FileAppContext, type FileEntry, type FileInfo, FilesModule, type GetFileOptions, HOST_MESSAGE_CHANNEL_PATTERN, type HeaderAction, type HeaderActionHandler, type HeaderActionRegistration, type HeaderActionResult, type HostMessageHandler, type HostToAppMessage, HttpTransport, type Installation, type InstallationDetail, type InstallationGraphOutcomeStatus, type InstallationGraphPackage, type InstallationGraphPreview, type InstallationGraphResult, type InstallationLifecycleResult, type InstallationListOptions, type InstallationMode, type InstallationScopedOptions, type InstallationStatus, InstallationsModule, type InstalledPackageDescriptor, type InstalledPackagePayload, type ManifestMetadata, type MimeTypeBinding, type MoveFileOptions, type NamespacedSettings, type NativeChangeSet, NativeCollaborationClient, type NativeCollaborationCommand, NativeCollaborationError, type NativeCollaborationRequest, type NativeCollaborationResponse, type NativeElement, type NativeFile, type NativeParticipant, type NativePointer, type NativeSaveReceipt, type NativeSaveResult, type NativeScene, type NativeSnapshot, type NavigateOptions, type NodeFileContent, type NodeFileMetadata, type NodeFileOptions, type OAuthConfig, type PackageDependency, type PagedResult, type PreviewInstallationOptions, type ReadArchiveOptions, type RequestOptions, type ResolveInstallationOptions, type ResourceMimeTypeBinding, type ResourceRegistration, type ResourceScopedOptions, ResourcesModule, type RunFileOptions, type SandboxOptions, type SettingDeclaration, type SettingDeclarationType, type SettingGroup, type SettingItem, type SettingOption, type SettingPresence, SettingsModule, type SettingsScopedOptions, TokenAuth, type TokenInfo, type UpdateInstallationOptions, type VerentisActionInvokeMessage, type VerentisActionResultMessage, type VerentisActionsSetMessage, VerentisClient, type VerentisClientOptions, type VerentisDirtyMessage, type VerentisFileChangedMessage, type VerentisHostMessage, type VerentisHostReplyMessage, type VerentisInitMessage, type VerentisMessage, type VerentisNavigateMessage, type VerentisReadyMessage, type VerentisResizeMessage, type VerentisThemeMessage, type VerentisTitleMessage, type VerentisTokenRefreshMessage, type VerentisTokenRefreshedMessage, type VerentisWopiRequest, type VerentisWopiResponse, type WaitOptions, type WopiContinuation, type WopiLaunch, type WopiSaveCheckpoint, type WopiSaveStatus, type WorkspaceAppContext, type WorkspaceInfo, type WriteFileOptions, type WriteNodeFileOptions, createVerentisClient, exactHttpsOrigin, findBestMatch, isDurableSaveConfirmed, isHeaderAction, isNativeSaveResult, isNativeSnapshot, isTerminalStatus, isTrustedMessage, matchMimeType, validateCollaborationDocument, validateNativeCommand };