@xema/omni-protocol 0.1.25 → 0.1.27

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
@@ -65,7 +65,7 @@ clean result is read for what it covers and not for the whole contract; `assertR
65
65
  subjects)` is the paired assertion.
66
66
 
67
67
  ```ts
68
- const context = { protocolVersion: OMNI_PROTOCOL_VERSION, sessionId: "session-1", host: stillHost(report) };
68
+ const context = { protocolVersion: OMNI_PROTOCOL_VERSION, loginId: "session-1", host: stillHost(report) };
69
69
  const result = await exerciseAdapter(adapter, context, { collectOnly: true });
70
70
  expect(result.violations).toEqual([]);
71
71
  expect(result.disconnectWasClean).toBe(true);
package/dist/index.d.ts CHANGED
@@ -54,19 +54,19 @@ export interface ProtocolViolation {
54
54
  message: string;
55
55
  }
56
56
  export type AuthenticationMethod = "browser-sso" | "credentials";
57
- export interface BrowserAccessPolicy {
57
+ export interface BrowserAccess {
58
58
  /** The decision when no list entry matches. */
59
59
  mode: "allow-all" | "block-all";
60
60
  allowList?: string[];
61
61
  blockList?: string[];
62
62
  }
63
63
  export interface PersonalBrowserCapability {
64
- access: BrowserAccessPolicy;
64
+ access: BrowserAccess;
65
65
  accessPolicyScope?: "initial-url" | "all-navigation";
66
66
  }
67
- export type DialDestinationPolicy = "contacts-only" | "any-number";
67
+ export type DialDestinations = "contacts-only" | "any-number";
68
68
  export interface DialCapability {
69
- destinationPolicy: DialDestinationPolicy;
69
+ destinations: DialDestinations;
70
70
  }
71
71
  /** Every idle capability a provider may declare. Only voice may `dial`; the channel arm says so. */
72
72
  export declare const IDLE_CAPABILITIES: readonly ["dial", "personalBrowser", "calendar", "contacts"];
@@ -111,8 +111,8 @@ export interface Manifest<C extends Channel = Channel> {
111
111
  phaseLabels?: TaskPhaseLabels;
112
112
  /** Keyed by `taskType`. An entry replaces the channel default outright rather than merging. */
113
113
  taskTypePresentation?: Record<string, TaskTypePresentation>;
114
- /** The organisation's whole ladder, stated outright, `person` included. Omitted for the typical four, `DEFAULT_TIERS`. */
115
- orgTiers?: TierDeclaration[];
114
+ /** The organisation's whole ladder, stated outright, `person` included. Omitted for the typical four, `DEFAULT_LEVELS`. */
115
+ orgLevels?: LevelDeclaration[];
116
116
  }
117
117
  export interface SecretStore {
118
118
  get(key: string): Promise<string | undefined>;
@@ -121,8 +121,8 @@ export interface SecretStore {
121
121
  }
122
122
  export interface AuthenticationContext {
123
123
  protocolVersion: number;
124
- /** Omni's identity for this login. The same value arrives later as `ConnectContext.sessionId`. */
125
- sessionId: string;
124
+ /** Omni's identity for this login. The same value arrives later as `ConnectContext.loginId`. */
125
+ loginId: string;
126
126
  /** Scoped to this provider's manifest id. */
127
127
  secrets: SecretStore;
128
128
  signal?: AbortSignal;
@@ -155,7 +155,7 @@ export interface TeamCapabilities {
155
155
  * of who the agent is on this provider: the provider knows the roles and says so at sign-in.
156
156
  * Current as of the latest `authenticated` state, never fixed for the login.
157
157
  */
158
- export interface SessionCapabilities {
158
+ export interface UserCapabilities {
159
159
  /** This login may request a break. Requires the four break methods. */
160
160
  breaks?: true;
161
161
  /** The choices the team left to this person, with where each stands. Omitted when there are none. Requires `setPreference`. */
@@ -175,12 +175,12 @@ export type AuthenticationState = {
175
175
  } | {
176
176
  status: "authenticated";
177
177
  identity: User;
178
- capabilities: SessionCapabilities;
178
+ capabilities: UserCapabilities;
179
179
  expiresAt?: IsoTimestamp;
180
180
  } | {
181
181
  status: "refreshing";
182
182
  identity: User;
183
- capabilities: SessionCapabilities;
183
+ capabilities: UserCapabilities;
184
184
  } | {
185
185
  status: "expired";
186
186
  identity?: User;
@@ -230,7 +230,7 @@ export type CompleteAuthenticationRequest = {
230
230
  export type CompleteAuthenticationResult = {
231
231
  status: "authenticated";
232
232
  identity: User;
233
- capabilities: SessionCapabilities;
233
+ capabilities: UserCapabilities;
234
234
  expiresAt?: IsoTimestamp;
235
235
  } | {
236
236
  status: "rejected";
@@ -295,10 +295,6 @@ export type HostAudioOutput = {
295
295
  /** What Omni's own chrome shows of a task browser's URL: nothing, the domain, or all of it. */
296
296
  export type UrlVisibility = "full" | "domain" | "hidden";
297
297
  export interface HostReport {
298
- /** What the agent can see of a task browser's URL in Omni's chrome. Task browsers only; the personal browser is the agent's. */
299
- browsers: {
300
- urlVisibility: UrlVisibility;
301
- };
302
298
  /** Whether the host has a network interface up. Not a claim that anything is reachable: the adapter knows its own platform's reachability better than the host does. */
303
299
  online: boolean;
304
300
  audio?: {
@@ -314,7 +310,7 @@ export interface Host {
314
310
  export interface ConnectContext {
315
311
  protocolVersion: number;
316
312
  /** The session that authenticated this connection. */
317
- sessionId: string;
313
+ loginId: string;
318
314
  /** Omni-side policy: whether the agent's tasks are accepted without asking them. */
319
315
  autoAcceptTasks?: boolean;
320
316
  /**
@@ -325,13 +321,13 @@ export interface ConnectContext {
325
321
  signal?: AbortSignal;
326
322
  log?: (entry: unknown) => void;
327
323
  }
328
- export type ConnectionStatus = "connecting" | "active" | "error";
324
+ export type TransportStatus = "connecting" | "active" | "error";
329
325
  /**
330
326
  * What revives a connection that reported `error`: `reconnect` -- the login is good, dispose this
331
327
  * connection and call `connect()` again -- or `reauthenticate` -- run the authentication flow
332
328
  * first. The adapter knows which; the host acts on its word.
333
329
  */
334
- export type ConnectionRecovery = "reconnect" | "reauthenticate";
330
+ export type TransportRecovery = "reconnect" | "reauthenticate";
335
331
  /** Every field is optional: a provider sends what it knows and omits what it does not. */
336
332
  export interface Contact {
337
333
  name?: string;
@@ -346,7 +342,8 @@ export interface ScheduledActivity {
346
342
  title: string;
347
343
  startsAt: IsoTimestamp;
348
344
  endsAt?: IsoTimestamp;
349
- contact?: Contact;
345
+ /** The person the activity reaches -- a callback's customer. */
346
+ party?: Contact;
350
347
  attributes?: Attribute[];
351
348
  }
352
349
  export interface DispositionCode {
@@ -354,7 +351,7 @@ export interface DispositionCode {
354
351
  label: string;
355
352
  group?: string;
356
353
  }
357
- export interface DispositionPolicy {
354
+ export interface DispositionRules {
358
355
  required?: boolean;
359
356
  notes?: "required" | "optional" | "hidden";
360
357
  codes?: DispositionCode[];
@@ -373,7 +370,7 @@ export interface DestinationDirectory {
373
370
  export interface CustomCapability {
374
371
  id: string;
375
372
  ui: {
376
- kind: "button" | "toggle" | "menu-item";
373
+ control: "button" | "toggle" | "menu-item";
377
374
  label: string;
378
375
  placement: "primary" | "secondary" | "overflow";
379
376
  /** Where the control's work renders: inline in the workspace, or as a page of its own. Inline when absent. */
@@ -386,7 +383,7 @@ export interface CustomCapability {
386
383
  }
387
384
  export interface SharedTaskCapabilities {
388
385
  browsers?: true;
389
- dispositions?: true | DispositionPolicy;
386
+ dispositions?: true | DispositionRules;
390
387
  custom?: CustomCapability[];
391
388
  }
392
389
  /**
@@ -429,24 +426,32 @@ export declare const BROWSER_ISOLATION_SCHEMES: {
429
426
  readonly TASK_TYPE_NAME__TAB_NAME: "TaskTypeName.TabName";
430
427
  };
431
428
  export type BrowserIsolationScheme = (typeof BROWSER_ISOLATION_SCHEMES)[keyof typeof BROWSER_ISOLATION_SCHEMES];
432
- export interface TaskBrowserBase {
429
+ /** One tab, in either workspace. */
430
+ export interface Browser {
433
431
  id: string;
434
432
  name: string;
435
- purpose: string;
436
433
  /** `http:` or `https:` only. */
437
434
  url: string;
438
435
  }
439
436
  /**
440
- * The union is what makes a reusing browser with no scheme fail to compile rather than inherit
441
- * a default -- which is how two tasks end up sharing a session nobody intended.
437
+ * A tab the task brought: fixed at the task's definition -- count and details -- with why it is
438
+ * there, whether its session is shared across tasks, and whether the agent may read its URL. The
439
+ * union is what makes a reusing browser with no scheme fail to compile rather than inherit a
440
+ * default -- which is how two tasks end up sharing a session nobody intended.
442
441
  */
443
- export type TaskBrowser = TaskBrowserBase & ({
444
- reuse: false;
442
+ export type TaskBrowser = Browser & {
443
+ purpose: string;
444
+ /** Hide this tab's URL from the agent in Omni's chrome. Omitted, the URL shows as any browser's does; a provider says `hidden` where the URL carries what the agent may not read. */
445
+ urlVisibility?: UrlVisibility;
446
+ } & ({
447
+ sharedSession: false;
445
448
  isolationScheme?: never;
446
449
  } | {
447
- reuse: true;
450
+ sharedSession: true;
448
451
  isolationScheme: BrowserIsolationScheme;
449
452
  });
453
+ /** A tab the agent opened in the personal workspace: theirs, as many as they like, and never on the wire. */
454
+ export type PersonalBrowser = Browser;
450
455
  export declare const ALLOWED_BROWSER_URL_SCHEMES: readonly ["http:", "https:"];
451
456
  export declare function isAllowedBrowserUrl(url: string): boolean;
452
457
  export type TaskPhase =
@@ -469,7 +474,7 @@ export type TaskAttribute = TaskAttributeBase & ({
469
474
  value: string;
470
475
  } | {
471
476
  type: "contact";
472
- contact: Contact;
477
+ party: Contact;
473
478
  } | {
474
479
  type: "timestamp";
475
480
  at: IsoTimestamp;
@@ -500,10 +505,10 @@ export interface TaskHandlingStep {
500
505
  */
501
506
  export type TaskCompletion = {
502
507
  completionMode: "agent-command";
503
- completionAllowance?: DurationSeconds;
508
+ wrapAllowance?: DurationSeconds;
504
509
  } | {
505
510
  completionMode: "provider-automatic";
506
- completionAllowance: DurationSeconds;
511
+ wrapAllowance: DurationSeconds;
507
512
  };
508
513
  /**
509
514
  * A consultation in progress on a task: who is being consulted, and since when where the provider
@@ -520,7 +525,7 @@ export interface TaskConsultation {
520
525
  * `requested` while nobody has joined; `joined`, with `leadId`, once somebody has.
521
526
  */
522
527
  export interface TaskLead {
523
- status: "requested" | "joined";
528
+ stage: "requested" | "joined";
524
529
  leadId?: UserId;
525
530
  note?: string;
526
531
  since: IsoTimestamp;
@@ -535,21 +540,21 @@ export interface TaskAssisting {
535
540
  since: IsoTimestamp;
536
541
  }
537
542
  /**
538
- * A tier of the organisation's structure, by the id its manifest declares -- or one of the four
539
- * a typical organisation has, `DEFAULT_TIERS`, when the manifest declares no ladder. The protocol
540
- * never describes the chain: which tiers a person passes through is the structure's to know.
543
+ * A level of the organisation's structure, by the id its manifest declares -- or one of the four
544
+ * a typical organisation has, `DEFAULT_LEVELS`, when the manifest declares no ladder. The protocol
545
+ * never describes the chain: which levels a person passes through is the structure's to know.
541
546
  */
542
- export type Tier = string;
543
- /** A tier the structure has, with the label a desk shows for "who decided". */
544
- export interface TierDeclaration {
545
- id: Tier;
547
+ export type Level = string;
548
+ /** A level the structure has, with the label a desk shows for "who decided". */
549
+ export interface LevelDeclaration {
550
+ id: Level;
546
551
  label: string;
547
552
  }
548
553
  /**
549
- * The tiers a typical organisation has: the ladder in force when a manifest declares no
550
- * `orgTiers`. A manifest that declares any states its whole ladder outright.
554
+ * The levels a typical organisation has: the ladder in force when a manifest declares no
555
+ * `orgLevels`. A manifest that declares any states its whole ladder outright.
551
556
  */
552
- export declare const DEFAULT_TIERS: readonly [{
557
+ export declare const DEFAULT_LEVELS: readonly [{
553
558
  readonly id: "org";
554
559
  readonly label: "Your organisation";
555
560
  }, {
@@ -563,14 +568,14 @@ export declare const DEFAULT_TIERS: readonly [{
563
568
  readonly label: "You";
564
569
  }];
565
570
  /** The ladder in force for a manifest: exactly what it declares, or the defaults when it declares none. */
566
- export declare function effectiveTiers(declared: readonly TierDeclaration[] | undefined): TierDeclaration[];
571
+ export declare function effectiveLevels(declared: readonly LevelDeclaration[] | undefined): LevelDeclaration[];
567
572
  /**
568
- * Something the queue could allow, locked above the person: the tier that made it unchangeable,
569
- * and why if they said. `person` never locks their own value, and the queue is not a tier --
573
+ * Something the queue could allow, locked above the person: the level that made it unchangeable,
574
+ * and why if they said. `person` never locks their own value, and the queue is not a level --
570
575
  * what the queue does not allow at all is simply absent.
571
576
  */
572
577
  export interface Locked {
573
- lockedBy: Tier;
578
+ lockedBy: Level;
574
579
  reason?: string;
575
580
  }
576
581
  /**
@@ -586,7 +591,8 @@ export type Task<C extends Channel = Channel> = {
586
591
  taskType: string;
587
592
  capabilities: TaskCapabilities<C>;
588
593
  browsers: TaskBrowser[];
589
- contact?: Contact;
594
+ /** The person or entity on the other end of this task. Who the task is with; `contacts` on the snapshot is the directory. */
595
+ party?: Contact;
590
596
  phase: TaskPhase;
591
597
  /** The identifier an agent reads back to a customer, where the provider has one. */
592
598
  reference?: string;
@@ -782,7 +788,7 @@ export interface BreakReason {
782
788
  label: string;
783
789
  group?: string;
784
790
  kind?: BreakKind;
785
- /** Survives `accepting: false`: a mandatory rest is not something a busy hour can cancel. */
791
+ /** Survives `mayAsk: false`: a mandatory rest is not something a busy hour can cancel. */
786
792
  alwaysAvailable?: true;
787
793
  }
788
794
  export interface BreakRequest {
@@ -809,8 +815,8 @@ export type ImposedBreak = {
809
815
  export interface BreakState {
810
816
  approval: BreakApproval;
811
817
  /** Whether the agent may ask at all. Distinct from the fate of a request already made. */
812
- accepting: boolean;
813
- /** Shown when `accepting` is false, such as "Busy hours". */
818
+ mayAsk: boolean;
819
+ /** Shown when `mayAsk` is false, such as "Busy hours". */
814
820
  refusedReason?: string;
815
821
  decisionReason?: string;
816
822
  retryAfterMs?: number;
@@ -883,7 +889,7 @@ export interface TeamRoster {
883
889
  export type PolicyKey = Exclude<keyof TaskCapabilities<"voice">, keyof SharedTaskCapabilities> | Exclude<keyof TaskCapabilities<"chat">, keyof SharedTaskCapabilities> | Exclude<keyof TaskCapabilities<"email">, keyof SharedTaskCapabilities> | "dial" | `skill:${string}`;
884
890
  /** On for everyone, off for everyone, or the agent's own choice. Only `hold`, `mute` and skills may be `agent`. */
885
891
  export type TeamPolicySetting = "on" | "off" | "agent";
886
- /** One policy as the lead sees it: the setting, who set it, and `lockedBy` when a tier above the team made it theirs to keep. */
892
+ /** One policy as the lead sees it: the setting, who set it, and `lockedBy` when a level above the team made it theirs to keep. */
887
893
  export interface TeamPolicy extends Resolved {
888
894
  setting: TeamPolicySetting;
889
895
  }
@@ -937,7 +943,7 @@ export interface TeamBreakCommandRequest {
937
943
  * `ended` once primary handling's audio ended, and the field omitted while none should be. The
938
944
  * provider's word -- a desk attaches and renders audio from it, never from its own senses.
939
945
  */
940
- export type TaskMediaState = "ready" | "ended";
946
+ export type TaskMediaState = "started" | "ended";
941
947
  export interface VoiceMediaSession {
942
948
  remoteAudio: MediaStream;
943
949
  setMuted(muted: boolean): void;
@@ -959,27 +965,27 @@ export type OpenMediaResult = {
959
965
  /**
960
966
  * What the team may leave to the person: a capability by its own name -- `hold`, `mute` -- or a
961
967
  * skill by its provider id. The same key as in `Task.capabilities`, because it is the same
962
- * capability seen at another tier. Callback and new call are never the person's; they are the
968
+ * capability seen at another level. Callback and new call are never the person's; they are the
963
969
  * team's, on or off, within what the queue allows.
964
970
  */
965
971
  export type PreferenceId = "hold" | "mute" | `skill:${string}`;
966
972
  /**
967
- * Who stated a value as it stands: a tier -- `person` among them -- or `provisioning`, the
968
- * protocol's own word for "no tier has said anything and the provider's default applies".
973
+ * Who stated a value as it stands: a level -- `person` among them -- or `provisioning`, the
974
+ * protocol's own word for "no level has said anything and the provider's default applies".
969
975
  * Nothing is hidden for want of a row.
970
976
  */
971
- export type SetBy = Tier | "provisioning";
977
+ export type SetBy = Level | "provider";
972
978
  /** What every resolved value carries: who set it, and who locked it if anyone did. */
973
979
  export interface Resolved {
974
980
  setBy: SetBy;
975
- lockedBy?: Tier;
981
+ lockedBy?: Level;
976
982
  /** Given with `lockedBy`, where whoever locked it said why. */
977
983
  reason?: string;
978
984
  }
979
985
  /**
980
986
  * One choice the team may leave to the person, with where it stands and who set it. The provider
981
987
  * keeps it: it is the person's across sessions, written through `setPreference`. Listed whether
982
- * or not anyone has stated it, and even when a tier above has since locked it.
988
+ * or not anyone has stated it, and even when a level above has since locked it.
983
989
  */
984
990
  export interface AgentPreference extends Resolved {
985
991
  id: PreferenceId;
@@ -1001,8 +1007,8 @@ export type PreferenceResult = {
1001
1007
  failure: ProtocolFailure;
1002
1008
  };
1003
1009
  export interface Snapshot<C extends Channel = Channel> {
1004
- status: ConnectionStatus;
1005
- sessionId: string;
1010
+ transport: TransportStatus;
1011
+ loginId: string;
1006
1012
  break: BreakState;
1007
1013
  /** Every task currently owned by this agent for this provider. */
1008
1014
  tasks: Task<C>[];
@@ -1027,7 +1033,7 @@ export interface SummaryMetric {
1027
1033
  label: string;
1028
1034
  value: string;
1029
1035
  }
1030
- export interface ProviderSummary {
1036
+ export interface QueueSummary {
1031
1037
  title: string;
1032
1038
  subtitle?: string;
1033
1039
  waitingCount: number;
@@ -1039,13 +1045,13 @@ export type ProviderEvent<C extends Channel = Channel> = {
1039
1045
  reason: "reconnected" | "provider-requested";
1040
1046
  snapshot: Snapshot<C>;
1041
1047
  } | {
1042
- type: "provider-status";
1048
+ type: "transport-status";
1043
1049
  status: "connecting" | "active";
1044
1050
  message?: string;
1045
1051
  } | {
1046
- type: "provider-status";
1052
+ type: "transport-status";
1047
1053
  status: "error";
1048
- recovery: ConnectionRecovery;
1054
+ recovery: TransportRecovery;
1049
1055
  message?: string;
1050
1056
  } | {
1051
1057
  type: "break-state";
@@ -1060,7 +1066,7 @@ export type ProviderEvent<C extends Channel = Channel> = {
1060
1066
  type: "task-updated";
1061
1067
  task: Task<C>;
1062
1068
  } | {
1063
- type: "task-media-ready";
1069
+ type: "task-media-started";
1064
1070
  taskId: TaskId;
1065
1071
  } | {
1066
1072
  type: "task-media-ended";
@@ -1076,8 +1082,8 @@ export type ProviderEvent<C extends Channel = Channel> = {
1076
1082
  announcedAt: IsoTimestamp;
1077
1083
  expiresAt?: IsoTimestamp;
1078
1084
  } | {
1079
- type: "provider-summary";
1080
- summary: ProviderSummary;
1085
+ type: "queue-summary";
1086
+ summary: QueueSummary;
1081
1087
  } | {
1082
1088
  type: "team-updated";
1083
1089
  team: TeamRoster;
@@ -1096,7 +1102,7 @@ export type ProviderEvent<C extends Channel = Channel> = {
1096
1102
  export interface ProviderEventEnvelope<C extends Channel = Channel> {
1097
1103
  id: string;
1098
1104
  /** The login this belongs to. */
1099
- sessionId: string;
1105
+ loginId: string;
1100
1106
  occurredAt: IsoTimestamp;
1101
1107
  event: ProviderEvent<C>;
1102
1108
  }
@@ -1221,11 +1227,11 @@ export interface BrowserSessionKeyInput {
1221
1227
  * guard -- comparing the identity -- never fires on a demotion, because the thing that changed is
1222
1228
  * not the thing being compared. Key order does not matter, and `team: {}` is not `team` absent.
1223
1229
  */
1224
- export declare function sameCapabilities(a: SessionCapabilities, b: SessionCapabilities): boolean;
1230
+ export declare function sameCapabilities(a: UserCapabilities, b: UserCapabilities): boolean;
1225
1231
  /**
1226
1232
  * The storage-profile key a reusing browser shares, or `undefined` where it shares nothing.
1227
1233
  *
1228
- * Fails closed. A browser with `reuse: false` has no key; nor does a reusing one whose scheme is
1234
+ * Fails closed. A browser with `sharedSession: false` has no key; nor does a reusing one whose scheme is
1229
1235
  * missing or unknown -- the type forbids that, but an adapter compiled against another version can
1230
1236
  * still send it, and the safe reading is "do not share", never "share with everyone named the
1231
1237
  * same". Every part is encoded, separator included, before joining, so a tab called `a.b`
package/dist/index.js CHANGED
@@ -51,18 +51,18 @@ export function isAllowedBrowserUrl(url) {
51
51
  }
52
52
  }
53
53
  /**
54
- * The tiers a typical organisation has: the ladder in force when a manifest declares no
55
- * `orgTiers`. A manifest that declares any states its whole ladder outright.
54
+ * The levels a typical organisation has: the ladder in force when a manifest declares no
55
+ * `orgLevels`. A manifest that declares any states its whole ladder outright.
56
56
  */
57
- export const DEFAULT_TIERS = [
57
+ export const DEFAULT_LEVELS = [
58
58
  { id: "org", label: "Your organisation" },
59
59
  { id: "site", label: "Your site" },
60
60
  { id: "team", label: "Your team" },
61
61
  { id: "person", label: "You" },
62
62
  ];
63
63
  /** The ladder in force for a manifest: exactly what it declares, or the defaults when it declares none. */
64
- export function effectiveTiers(declared) {
65
- return [...(declared ?? DEFAULT_TIERS)];
64
+ export function effectiveLevels(declared) {
65
+ return [...(declared ?? DEFAULT_LEVELS)];
66
66
  }
67
67
  // ---------------------------------------------------------------------------
68
68
  // Task commands.
@@ -157,7 +157,7 @@ export function sameCapabilities(a, b) {
157
157
  /**
158
158
  * The storage-profile key a reusing browser shares, or `undefined` where it shares nothing.
159
159
  *
160
- * Fails closed. A browser with `reuse: false` has no key; nor does a reusing one whose scheme is
160
+ * Fails closed. A browser with `sharedSession: false` has no key; nor does a reusing one whose scheme is
161
161
  * missing or unknown -- the type forbids that, but an adapter compiled against another version can
162
162
  * still send it, and the safe reading is "do not share", never "share with everyone named the
163
163
  * same". Every part is encoded, separator included, before joining, so a tab called `a.b`
@@ -165,7 +165,7 @@ export function sameCapabilities(a, b) {
165
165
  */
166
166
  export function browserSessionKey(input) {
167
167
  const { providerId, taskId, taskType, browser } = input;
168
- if (browser.reuse !== true)
168
+ if (browser.sharedSession !== true)
169
169
  return undefined;
170
170
  // `encodeURIComponent` leaves `.` untouched, and `.` is the separator: a raw join would let
171
171
  // provider `Acme.Voice` with type `Support` forge the key of `Acme` with `Voice.Support`.
package/dist/testing.d.ts CHANGED
@@ -120,7 +120,7 @@ export declare class BreakStream {
120
120
  export declare function assertBreakFollowsItsRequests(envelopes: readonly ProviderEventEnvelope[], snapshot?: Snapshot): void;
121
121
  /**
122
122
  * The media follows the task and never decides it. Given a provider's stream -- optionally seeded
123
- * with the snapshot it began from -- every task is introduced once, `task-media-ready` and
123
+ * with the snapshot it began from -- every task is introduced once, `task-media-started` and
124
124
  * `task-media-ended` alternate on work that has begun, media ends only where it arrived, and what
125
125
  * follows the media ending is `completing` or `task-ended`.
126
126
  */
@@ -162,11 +162,11 @@ export declare function assertBreakBeginsAfterTask(steps: readonly BreakOnTaskSt
162
162
  * nothing down when the provider set a clock. `toleranceMs` absorbs scheduler jitter in a real
163
163
  * implementation; pass 0 to demand an exact match.
164
164
  */
165
- export declare function assertWrapTimeout(task: Pick<TaskCompletion, "completionMode" | "completionAllowance">, mediaEndedAt: string, observedDeadline: string | undefined, toleranceMs?: number): void;
165
+ export declare function assertWrapTimeout(task: Pick<TaskCompletion, "completionMode" | "wrapAllowance">, mediaEndedAt: string, observedDeadline: string | undefined, toleranceMs?: number): void;
166
166
  /** One browser in one task of one provider. `providerId` is `Manifest.id`, never `displayName`. */
167
167
  export type BrowserIsolationScenario = BrowserSessionKeyInput;
168
168
  /** Validates whether two task-browser definitions should share one browser session. */
169
- export declare function assertBrowserIsolationAndReuse(left: BrowserIsolationScenario, right: BrowserIsolationScenario, expectedReuse: boolean): void;
169
+ export declare function assertBrowserSessionIsolation(left: BrowserIsolationScenario, right: BrowserIsolationScenario, expectedReuse: boolean): void;
170
170
  /**
171
171
  * Asserts that no two distinct scenarios in `scenarios` derive the same session key.
172
172
  * Feed it adversarial names — a provider called `A.B` against a task type called