@seriousgaming/sdk 0.0.0-stage → 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +1 -0
  3. package/README.md +29 -2
  4. package/lib/build/callbacks.d.ts +998 -0
  5. package/lib/build/callbacks.js +32 -0
  6. package/lib/build/context-merge.d.ts +59 -0
  7. package/lib/build/context-merge.js +118 -0
  8. package/lib/build/document.d.ts +36 -0
  9. package/lib/build/document.js +8 -0
  10. package/lib/build/encoding.d.ts +26 -0
  11. package/lib/build/encoding.js +78 -0
  12. package/lib/build/endpoints.d.ts +421 -0
  13. package/lib/build/endpoints.js +46 -0
  14. package/lib/build/hooks.d.ts +74 -0
  15. package/lib/build/hooks.js +1 -0
  16. package/lib/build/index.d.ts +18 -0
  17. package/lib/build/index.js +16 -0
  18. package/lib/build/llm.d.ts +166 -0
  19. package/lib/build/llm.js +17 -0
  20. package/lib/build/resource-schema.d.ts +1048 -0
  21. package/lib/build/resource-schema.js +7 -0
  22. package/lib/build/scheduling.d.ts +112 -0
  23. package/lib/build/scheduling.js +217 -0
  24. package/lib/build/seed.d.ts +51 -0
  25. package/lib/build/seed.js +89 -0
  26. package/lib/build/signatures.d.ts +372 -0
  27. package/lib/build/signatures.js +1 -0
  28. package/lib/build/speech.d.ts +102 -0
  29. package/lib/build/speech.js +11 -0
  30. package/lib/build/tick-validation.d.ts +23 -0
  31. package/lib/build/tick-validation.js +96 -0
  32. package/lib/build/timer.d.ts +74 -0
  33. package/lib/build/timer.js +1 -0
  34. package/lib/build/validators.d.ts +116 -0
  35. package/lib/build/validators.js +1 -0
  36. package/lib/commands.d.ts +357 -0
  37. package/lib/commands.js +14 -0
  38. package/lib/e2e.d.ts +238 -0
  39. package/lib/e2e.js +248 -0
  40. package/lib/projection.d.ts +266 -0
  41. package/lib/projection.js +23 -0
  42. package/lib/testing/index.d.ts +13 -0
  43. package/lib/testing/index.js +13 -0
  44. package/lib/testing/logic-args.d.ts +177 -0
  45. package/lib/testing/logic-args.js +229 -0
  46. package/lib/testing/stub-services.d.ts +41 -0
  47. package/lib/testing/stub-services.js +176 -0
  48. package/lib/ui/CrossTeamDataContext.d.ts +36 -0
  49. package/lib/ui/CrossTeamDataContext.js +32 -0
  50. package/lib/ui/PresentationContext.d.ts +72 -0
  51. package/lib/ui/PresentationContext.js +13 -0
  52. package/lib/ui/PresentationWrapper.d.ts +12 -0
  53. package/lib/ui/PresentationWrapper.js +78 -0
  54. package/lib/ui/SessionUserInterfaceCallbacksContext.d.ts +3 -0
  55. package/lib/ui/SessionUserInterfaceCallbacksContext.js +7 -0
  56. package/lib/ui/SessionUserInterfaceDataContext.d.ts +103 -0
  57. package/lib/ui/SessionUserInterfaceDataContext.js +17 -0
  58. package/lib/ui/SessionUserInterfaceHookFailuresContext.d.ts +44 -0
  59. package/lib/ui/SessionUserInterfaceHookFailuresContext.js +15 -0
  60. package/lib/ui/SessionUserInterfaceHostOverlaysContext.d.ts +23 -0
  61. package/lib/ui/SessionUserInterfaceHostOverlaysContext.js +23 -0
  62. package/lib/ui/SessionUserInterfaceLocaleContext.d.ts +11 -0
  63. package/lib/ui/SessionUserInterfaceLocaleContext.js +13 -0
  64. package/lib/ui/SessionUserInterfaceMetaContext.d.ts +39 -0
  65. package/lib/ui/SessionUserInterfaceMetaContext.js +13 -0
  66. package/lib/ui/SessionUserInterfaceParticipantsContext.d.ts +12 -0
  67. package/lib/ui/SessionUserInterfaceParticipantsContext.js +16 -0
  68. package/lib/ui/SessionUserInterfaceTeamConfigurationContext.d.ts +53 -0
  69. package/lib/ui/SessionUserInterfaceTeamConfigurationContext.js +23 -0
  70. package/lib/ui/SessionUserInterfaceTeamLinksContext.d.ts +56 -0
  71. package/lib/ui/SessionUserInterfaceTeamLinksContext.js +12 -0
  72. package/lib/ui/SessionUserInterfaceTeamsContext.d.ts +13 -0
  73. package/lib/ui/SessionUserInterfaceTeamsContext.js +13 -0
  74. package/lib/ui/SessionUserInterfaceThemeContext.d.ts +9 -0
  75. package/lib/ui/SessionUserInterfaceThemeContext.js +7 -0
  76. package/lib/ui/SessionUserInterfaceThemePreferenceContext.d.ts +3 -0
  77. package/lib/ui/SessionUserInterfaceThemePreferenceContext.js +7 -0
  78. package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.d.ts +42 -0
  79. package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.js +26 -0
  80. package/lib/ui/SessionUserInterfaceWrapper.d.ts +8 -0
  81. package/lib/ui/SessionUserInterfaceWrapper.js +321 -0
  82. package/lib/ui/SettingsEditorCallbacksContext.d.ts +3 -0
  83. package/lib/ui/SettingsEditorCallbacksContext.js +7 -0
  84. package/lib/ui/SettingsEditorContext.d.ts +33 -0
  85. package/lib/ui/SettingsEditorContext.js +16 -0
  86. package/lib/ui/SettingsEditorLocaleContext.d.ts +13 -0
  87. package/lib/ui/SettingsEditorLocaleContext.js +15 -0
  88. package/lib/ui/SettingsEditorThemeContext.d.ts +9 -0
  89. package/lib/ui/SettingsEditorThemeContext.js +7 -0
  90. package/lib/ui/SettingsEditorThemePreferenceContext.d.ts +3 -0
  91. package/lib/ui/SettingsEditorThemePreferenceContext.js +7 -0
  92. package/lib/ui/SettingsEditorWrapper.d.ts +13 -0
  93. package/lib/ui/SettingsEditorWrapper.js +74 -0
  94. package/lib/ui/UserInterfaceCallbacksContext.d.ts +3 -0
  95. package/lib/ui/UserInterfaceCallbacksContext.js +7 -0
  96. package/lib/ui/UserInterfaceDataContext.d.ts +78 -0
  97. package/lib/ui/UserInterfaceDataContext.js +11 -0
  98. package/lib/ui/UserInterfaceLocaleContext.d.ts +13 -0
  99. package/lib/ui/UserInterfaceLocaleContext.js +15 -0
  100. package/lib/ui/UserInterfaceOwnTeamContext.d.ts +25 -0
  101. package/lib/ui/UserInterfaceOwnTeamContext.js +26 -0
  102. package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.d.ts +52 -0
  103. package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.js +13 -0
  104. package/lib/ui/UserInterfaceParticipantContext.d.ts +16 -0
  105. package/lib/ui/UserInterfaceParticipantContext.js +24 -0
  106. package/lib/ui/UserInterfaceParticipantsContext.d.ts +12 -0
  107. package/lib/ui/UserInterfaceParticipantsContext.js +13 -0
  108. package/lib/ui/UserInterfaceRunKindContext.d.ts +31 -0
  109. package/lib/ui/UserInterfaceRunKindContext.js +31 -0
  110. package/lib/ui/UserInterfaceTeamsContext.d.ts +12 -0
  111. package/lib/ui/UserInterfaceTeamsContext.js +13 -0
  112. package/lib/ui/UserInterfaceThemeContext.d.ts +9 -0
  113. package/lib/ui/UserInterfaceThemeContext.js +7 -0
  114. package/lib/ui/UserInterfaceThemePreferenceContext.d.ts +3 -0
  115. package/lib/ui/UserInterfaceThemePreferenceContext.js +7 -0
  116. package/lib/ui/UserInterfaceTimerContext.d.ts +10 -0
  117. package/lib/ui/UserInterfaceTimerContext.js +12 -0
  118. package/lib/ui/UserInterfaceValidationContext.d.ts +25 -0
  119. package/lib/ui/UserInterfaceValidationContext.js +14 -0
  120. package/lib/ui/UserInterfaceViewerRoleContext.d.ts +14 -0
  121. package/lib/ui/UserInterfaceViewerRoleContext.js +17 -0
  122. package/lib/ui/UserInterfaceWrapper.d.ts +8 -0
  123. package/lib/ui/UserInterfaceWrapper.js +219 -0
  124. package/lib/ui/expectedParentOrigin.d.ts +10 -0
  125. package/lib/ui/expectedParentOrigin.js +32 -0
  126. package/lib/ui/index.d.ts +50 -0
  127. package/lib/ui/index.js +52 -0
  128. package/lib/ui/internal/SurfaceGate.d.ts +19 -0
  129. package/lib/ui/internal/SurfaceGate.js +17 -0
  130. package/lib/ui/internal/SurfaceScope.d.ts +17 -0
  131. package/lib/ui/internal/SurfaceScope.js +16 -0
  132. package/lib/ui/internal/createContexts.d.ts +50 -0
  133. package/lib/ui/internal/createContexts.js +32 -0
  134. package/lib/ui/internal/document-attributes.d.ts +9 -0
  135. package/lib/ui/internal/document-attributes.js +87 -0
  136. package/lib/ui/internal/surface-timer.d.ts +3 -0
  137. package/lib/ui/internal/surface-timer.js +11 -0
  138. package/lib/ui/internal/useLatestRef.d.ts +7 -0
  139. package/lib/ui/internal/useLatestRef.js +11 -0
  140. package/lib/ui/internal/useOptimisticMerge.d.ts +19 -0
  141. package/lib/ui/internal/useOptimisticMerge.js +28 -0
  142. package/lib/ui/internal/useSurfaceControls.d.ts +52 -0
  143. package/lib/ui/internal/useSurfaceControls.js +19 -0
  144. package/lib/ui/internal/useTypedPastState.d.ts +17 -0
  145. package/lib/ui/internal/useTypedPastState.js +17 -0
  146. package/lib/ui/mutation-commit.d.ts +32 -0
  147. package/lib/ui/mutation-commit.js +1 -0
  148. package/lib/ui/mutation-outcome.d.ts +66 -0
  149. package/lib/ui/mutation-outcome.js +49 -0
  150. package/lib/ui/request-id.d.ts +18 -0
  151. package/lib/ui/request-id.js +44 -0
  152. package/lib/ui/testing.d.ts +365 -0
  153. package/lib/ui/testing.js +572 -0
  154. package/lib/ui/tick-snapshot.d.ts +28 -0
  155. package/lib/ui/tick-snapshot.js +34 -0
  156. package/lib/ui/ui-protocol.d.ts +799 -0
  157. package/lib/ui/ui-protocol.js +50 -0
  158. package/lib/ui/useAsset.d.ts +80 -0
  159. package/lib/ui/useAsset.js +139 -0
  160. package/lib/ui/useEndpointCallbacks.d.ts +31 -0
  161. package/lib/ui/useEndpointCallbacks.js +68 -0
  162. package/lib/ui/useHostChannel.d.ts +90 -0
  163. package/lib/ui/useHostChannel.js +338 -0
  164. package/lib/ui/useMutationReporter.d.ts +100 -0
  165. package/lib/ui/useMutationReporter.js +97 -0
  166. package/lib/ui/usePastState.d.ts +39 -0
  167. package/lib/ui/usePastState.js +63 -0
  168. package/lib/ui/useViewerStorage.d.ts +54 -0
  169. package/lib/ui/useViewerStorage.js +141 -0
  170. package/package.json +83 -3
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The host's automatic tick timer, as every reader sees it (§12.3).
3
+ *
4
+ * One shape wherever a timer appears: the `setTimer` payload a game surface
5
+ * receives, each team's entry in a session surface's `SessionData`, an
6
+ * endpoint's `session.teams[].timer`, and the state projection (§20).
7
+ * Durations are milliseconds and end in `Ms`; timestamps are milliseconds
8
+ * since the epoch and end in `At`.
9
+ *
10
+ * The host pushes a new value whenever the *schedule* changes (a new tick is
11
+ * scheduled, the timer pauses or resumes, the controller disables ticking).
12
+ * It does not push one every second: a surface that wants a live countdown
13
+ * computes it from `nextTickAt` in a local `requestAnimationFrame` (or
14
+ * `setInterval`) loop, which keeps React out of the per-frame path.
15
+ *
16
+ * `nextTickAt` is in the same clock-space as `Date.now()`, so the remaining
17
+ * time is `nextTickAt - Date.now()`. Hosts are responsible for stamping it in
18
+ * a clock the consumer recognises: automatic for a browser on the same machine
19
+ * as the host, NTP-synced clocks across machines. The wrapper does not
20
+ * estimate clock skew, since with only two timestamps it cannot be told apart
21
+ * from message staleness.
22
+ */
23
+ export interface TimerState {
24
+ /**
25
+ * Whether the tick controller currently has automatic ticking enabled.
26
+ * When false, no countdown should be shown: the game is manual-tick only,
27
+ * or the controller has decided to stop scheduling.
28
+ */
29
+ enabled: boolean;
30
+ /** Whether the host has paused automatic ticking. */
31
+ paused: boolean;
32
+ /**
33
+ * When the next automatic tick is due (epoch milliseconds, in `Date.now()`
34
+ * space). Null when nothing is scheduled: paused, complete, or `enabled`
35
+ * is false.
36
+ */
37
+ nextTickAt: number | null;
38
+ /**
39
+ * The full length of the currently scheduled window in milliseconds, within
40
+ * the §11.8 bounds. Useful for progress bars (`elapsed / intervalMs`). Null
41
+ * when nothing is scheduled.
42
+ */
43
+ intervalMs: number | null;
44
+ /**
45
+ * When the current pause began (epoch milliseconds), or null when the timer
46
+ * is not paused.
47
+ */
48
+ pausedAt: number | null;
49
+ /**
50
+ * Total paused time in milliseconds since the schedule started, not
51
+ * counting the current pause. Combine with `pausedAt` for a live total:
52
+ *
53
+ * ```ts
54
+ * const livePausedMs = timer.pausedMs + (timer.pausedAt ? Date.now() - timer.pausedAt : 0);
55
+ * ```
56
+ */
57
+ pausedMs: number;
58
+ /**
59
+ * How far facilitator extensions have moved the *currently scheduled* tick,
60
+ * in milliseconds. Positive when the deadline was pushed out, negative when
61
+ * it was pulled in, and 0 for an unadjusted window. Resets with each newly
62
+ * scheduled tick, so it describes this window rather than the session.
63
+ *
64
+ * Read it to say what happened rather than inferring it from a moved
65
+ * `nextTickAt`: a deadline that jumped could equally be a fresh schedule,
66
+ * and 'extended by 2m' is worth showing the room.
67
+ */
68
+ extendedMs: number;
69
+ /**
70
+ * When the current schedule first started (epoch milliseconds), or null
71
+ * when no schedule has started yet.
72
+ */
73
+ scheduleStartedAt: number | null;
74
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,116 @@
1
+ import { Participant } from './hooks.js';
2
+ import { LogicMeta } from './signatures.js';
3
+ /**
4
+ * Verdict returned by a validator. `ok: true` means the proposed state passes
5
+ * this check; `ok: false` rejects it and the runtime returns the message to
6
+ * the caller. The message is free-form — games encode structured data
7
+ * (locale key, JSON blob, etc.) inside it if they need to.
8
+ */
9
+ export type ValidationResult = {
10
+ ok: true;
11
+ } | {
12
+ ok: false;
13
+ message: string;
14
+ };
15
+ /**
16
+ * Who submitted the mutation a validator is gating.
17
+ *
18
+ * A union rather than an optional participant, because the two cases are not
19
+ * 'identity, or the absence of it'. They are two different callers, and a rule
20
+ * that means something different for each has to say which it is handling. The
21
+ * shape makes that unavoidable: `participant` is unreachable until `role` has
22
+ * been narrowed, so a validator cannot read an identity it has not first
23
+ * decided it has.
24
+ *
25
+ * An observer is a facilitator watching one team on that team's own play
26
+ * surface (§13.3). They are rendered the same user interface a participant is,
27
+ * with the same controls, so their writes are put to validators on the same
28
+ * terms. A game that wants a facilitator to be able to do what a participant
29
+ * cannot says so here, deliberately, rather than the runtime deciding it for
30
+ * every game at once.
31
+ */
32
+ export type ValidatorActor = {
33
+ role: 'participant';
34
+ participant: Participant;
35
+ }
36
+ /** An observer holds no participant record, so the team is all there is. */
37
+ | {
38
+ role: 'observer';
39
+ teamId: string;
40
+ };
41
+ /**
42
+ * Arguments of a validator's `UpdateData` gate, which judges a participant's
43
+ * context write. `previous` is the state before the write; `next` is the
44
+ * proposed state after it. Validators are read-only: they return a verdict,
45
+ * never modify the proposed state.
46
+ */
47
+ export interface ValidatorFunctionArgs<TContext, TSettings> {
48
+ previous: TContext;
49
+ next: TContext;
50
+ actor: ValidatorActor;
51
+ /**
52
+ * The settings resources this resource declared in `settings`, keyed by
53
+ * identifier: resolved from their defaults, the active scenario and the
54
+ * session's overrides, and fixed when play starts (§8). Read-only.
55
+ */
56
+ settings: TSettings;
57
+ /**
58
+ * The facts true of the whole run: its locale, its seed, whether it is the
59
+ * game being played or a walkthrough beside it, and when this run of the
60
+ * validators started (`now`).
61
+ *
62
+ * A validator gates a participant's action rather than running as part of
63
+ * a tick, so this is {@link LogicMeta} rather than the `RunMeta` an engine
64
+ * receives. Use `locale` to phrase a rejection in the session's language.
65
+ */
66
+ meta: LogicMeta;
67
+ /**
68
+ * The participants on the actor's team, taken when the validators started
69
+ * (§15.3). Read-only, and a copy per call.
70
+ */
71
+ participants: readonly Readonly<Participant>[];
72
+ }
73
+ /**
74
+ * A validator's `UpdateData` export: the gate on a participant's context
75
+ * write. Engines, hooks, endpoints and a session surface bypass it
76
+ * (system-trusted).
77
+ */
78
+ export type ValidatorFunction<TContext = unknown, TSettings = unknown> = (args: ValidatorFunctionArgs<TContext, TSettings>) => Promise<ValidationResult>;
79
+ /** Arguments of a validator's `RequestTick` gate. */
80
+ export interface RequestTickFunctionArgs<TContext, TSettings> {
81
+ /**
82
+ * The requesting team's board as it stands. A request changes nothing
83
+ * until the tick runs, so there is no `previous` and `next`: gate on the
84
+ * board, such as a pacing capability the facilitator sets.
85
+ */
86
+ context: TContext;
87
+ /**
88
+ * The tick the request would run: the requesting team's head tick plus
89
+ * one, so a first request asks for tick 1.
90
+ */
91
+ requestedTick: number;
92
+ actor: ValidatorActor;
93
+ /**
94
+ * The settings resources this resource declared in `settings`, keyed by
95
+ * identifier: resolved from their defaults, the active scenario and the
96
+ * session's overrides, and fixed when play starts (§8). Read-only.
97
+ */
98
+ settings: TSettings;
99
+ meta: LogicMeta;
100
+ /** The participants on the requesting team, as `UpdateData` receives them. */
101
+ participants: readonly Readonly<Participant>[];
102
+ }
103
+ /**
104
+ * A validator's `RequestTick` export: the gate on a participant's request for
105
+ * the next tick. Only a player surface's request reaches it; the facilitator's
106
+ * ticks, the timer's and every system-trusted caller's pass straight through.
107
+ */
108
+ export type RequestTickFunction<TContext = unknown, TSettings = unknown> = (args: RequestTickFunctionArgs<TContext, TSettings>) => Promise<ValidationResult>;
109
+ /**
110
+ * A single validator rejection returned to the caller. The runtime collects
111
+ * every rejection (form-style UX) rather than short-circuiting on the first.
112
+ */
113
+ export interface ValidationRejection {
114
+ validatorIdentifier: string;
115
+ message: string;
116
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,357 @@
1
+ /**
2
+ * What a client may ask a session to do (§20).
3
+ *
4
+ * One closed command set, shared by every client of the dev server: the
5
+ * browser console, the CLI, a Playwright suite through `runCommand`, and an
6
+ * agent posting to `/api/command`. Published from the SDK rather than declared
7
+ * inside the runtime so a test is type-checked against the commands the
8
+ * runtime actually accepts, and a misspelled field fails to compile rather
9
+ * than coming back as a 400.
10
+ *
11
+ * The runtime that validates these at its boundary lives in the tools
12
+ * package. This module is types only.
13
+ */
14
+ import type { PastStateEntry, PastStateQuery } from './build/callbacks.js';
15
+ import type { EndpointFailure } from './build/endpoints.js';
16
+ import type { ViewerRole } from './build/signatures.js';
17
+ import type { EndpointAuditEntry, FaultKind, StateProjection } from './projection.js';
18
+ /** Addresses one team by its stable index, or the session when absent. */
19
+ export interface TeamScope {
20
+ /** Stable team index (§5.6), not an array position. */
21
+ teamIndex?: number;
22
+ }
23
+ /** Who is asking, where the operation is one a participant can perform. */
24
+ export interface Actor {
25
+ participantId?: string;
26
+ teamId?: string;
27
+ /**
28
+ * What the host holds the sending surface as, where it holds it as
29
+ * anything (§13.3).
30
+ *
31
+ * Absence of `participantId` is not on its own a statement that nobody is
32
+ * asking: the CLI, a session surface and an observer all write without
33
+ * one, and so did a player surface whose slot the console had failed to
34
+ * resolve. The first three are deliberately identity-free and system
35
+ * trusted; the fourth was a participant's write being taken as one. The
36
+ * role separates them, so the session can refuse what it cannot attribute
37
+ * instead of trusting it.
38
+ *
39
+ * Host bookkeeping, never a claim the guest makes: the console resolves it
40
+ * from the route and the roster, exactly as it resolves `participantId`.
41
+ */
42
+ viewerRole?: ViewerRole;
43
+ }
44
+ export type { ViewerRole };
45
+ /**
46
+ * Every state-changing operation. Each one goes through the session's single
47
+ * queue, in submission order (§9.7).
48
+ */
49
+ export type MutationCommand =
50
+ /**
51
+ * A tick. `Actor` is present when a participant's or observer's surface
52
+ * asked for it (§15), which puts it to the validators gating
53
+ * `requestTick`; a facilitator's, the CLI's or a timer's carries none.
54
+ */
55
+ ({
56
+ type: 'tick';
57
+ } & TeamScope & Actor) | ({
58
+ type: 'undo';
59
+ } & TeamScope) | ({
60
+ type: 'reset';
61
+ } & TeamScope)
62
+ /** Leave the configuration stage and initialise (§8.3). */
63
+ | {
64
+ type: 'play';
65
+ }
66
+ /**
67
+ * Go back to the configuration stage, for a game that has one.
68
+ *
69
+ * The inverse of `play`, and a reset with it: configuration is resolved
70
+ * when the session initialises (§8.2), so changing it after the fact only
71
+ * means anything if the session starts again on the new values.
72
+ */
73
+ | {
74
+ type: 'reconfigure';
75
+ }
76
+ /**
77
+ * Reinitialise the session from the package, as if it had just started.
78
+ *
79
+ * Distinct from `reset`, which returns the session to its own tick 0 with
80
+ * the scenario, team count and locale it has. This re-resolves all three,
81
+ * so an omitted `scenarioId` goes back to the package's default rather than
82
+ * staying on whatever is active.
83
+ */
84
+ | {
85
+ type: 'reinitialise';
86
+ teams?: number;
87
+ scenarioId?: string | null;
88
+ locale?: string;
89
+ /**
90
+ * Participants to seed each team with: one count for every team, or
91
+ * one per team. Zero is allowed. Kept for later re-initialisations,
92
+ * like `teams`, until a new team count leaves a per-team list behind.
93
+ */
94
+ participants?: number | number[];
95
+ } | ({
96
+ type: 'updateContext';
97
+ payload: Record<string, unknown>;
98
+ /** Paths to remove after the payload merges (§9.5). */
99
+ deletes?: (string | string[])[];
100
+ /**
101
+ * The player surface the write came from, supplied by the host from
102
+ * what it mounted and never by the page. The write is held to that
103
+ * surface's `writes` (§9.5). Absent for a system-trusted caller: the
104
+ * session surface, the CLI, or logic.
105
+ */
106
+ uiIdentifier?: string;
107
+ /**
108
+ * The session surface a facilitator's team write came from, supplied
109
+ * by the host like `uiIdentifier`. The payload may change only
110
+ * capabilities that surface declares in `writes`, and may carry
111
+ * another capability unchanged; every path in `deletes` must name a
112
+ * team-scope capability it writes (§9.5.1). Absent for every other
113
+ * caller.
114
+ */
115
+ sessionUiIdentifier?: string;
116
+ } & TeamScope & Actor)
117
+ /**
118
+ * A shared-store write (§9.5.1). Exactly one of the two identifiers is
119
+ * present, and it names what authorised the write: a session surface's
120
+ * `writes` array for a facilitator write, or a session-scoped endpoint's
121
+ * for one of its patches (§6.12). An endpoint has no surface to borrow an
122
+ * identifier from, and a facilitator agent calling one has no bundle at all.
123
+ */
124
+ | {
125
+ type: 'updateSharedContext';
126
+ uiIdentifier?: string;
127
+ endpointIdentifier?: string;
128
+ payload: Record<string, unknown>;
129
+ /**
130
+ * Paths to remove from the store after the payload merges (§9.5), each
131
+ * under a shared capability the writer declares. Set by a
132
+ * session-scoped endpoint's `deletes` (§6.12).
133
+ */
134
+ deletes?: (string | string[])[];
135
+ }
136
+ /**
137
+ * Write into the session-override layer (§8.2). `uiIdentifier` names the
138
+ * settings editor that sent it, which may change only what it
139
+ * `configures` (§6.5); a caller naming none is system-trusted.
140
+ */
141
+ | {
142
+ type: 'updateSettings';
143
+ uiIdentifier?: string;
144
+ payload: Record<string, unknown>;
145
+ }
146
+ /**
147
+ * Open the scenario editor's draft of a scenario (§6.5), or of none for
148
+ * one started from the package's own settings. A draft already open on
149
+ * it is kept. The draft belongs to no session: it is resolved from the
150
+ * scenario, never from the session's override layer, and reaches a
151
+ * session only once it is saved as a scenario.
152
+ */
153
+ | {
154
+ type: 'editScenario';
155
+ scenarioId: string | null;
156
+ }
157
+ /** What the scenario editor sends in `updateSettings`: an edit to its draft (§6.5). */
158
+ | {
159
+ type: 'updateScenarioDraft';
160
+ uiIdentifier?: string;
161
+ scenarioId: string | null;
162
+ payload: Record<string, unknown>;
163
+ } | {
164
+ type: 'addTeam';
165
+ name?: string;
166
+ participants?: number;
167
+ } | {
168
+ type: 'removeTeam';
169
+ teamIndex: number;
170
+ } | {
171
+ type: 'renameTeam';
172
+ teamId: string;
173
+ name: string;
174
+ }
175
+ /** From a player surface; the host resolves the team (§12.5). */
176
+ | ({
177
+ type: 'renameOwnTeam';
178
+ name: string;
179
+ } & Actor) | {
180
+ type: 'addParticipant';
181
+ teamId: string;
182
+ name?: string;
183
+ } | {
184
+ type: 'renameParticipant';
185
+ participantId: string;
186
+ name: string;
187
+ } | {
188
+ type: 'moveParticipant';
189
+ participantId: string;
190
+ teamId: string;
191
+ } | {
192
+ type: 'setWaitingRoom';
193
+ open: boolean;
194
+ }
195
+ /**
196
+ * Throw the walkthrough away and start it again at tick 0 (§5.7).
197
+ *
198
+ * Handled by the host rather than by a session: it replaces the run a
199
+ * command would otherwise be addressed to, so the run cannot settle it.
200
+ */
201
+ | {
202
+ type: 'resetWalkthrough';
203
+ } | {
204
+ type: 'selectScenario';
205
+ scenarioId: string | null;
206
+ } | {
207
+ type: 'setLocale';
208
+ locale: string;
209
+ } | ({
210
+ type: 'pauseTimer';
211
+ } & TeamScope) | ({
212
+ type: 'resumeTimer';
213
+ } & TeamScope) | ({
214
+ type: 'extendTick';
215
+ byMs: number;
216
+ } & TeamScope)
217
+ /**
218
+ * Move a fake clock forward, running every automatic tick that comes due.
219
+ * Refused on the real clock: only `sdk dev --fake-clock` starts a session
220
+ * whose time can be moved by hand.
221
+ */
222
+ | {
223
+ type: 'advanceClock';
224
+ byMs: number;
225
+ }
226
+ /**
227
+ * Arm a failure this runtime cannot otherwise produce (§3.3 of the design).
228
+ *
229
+ * @internal The SDK dev server's fault injection; see `FaultKind`.
230
+ */
231
+ | {
232
+ type: 'armFault';
233
+ fault: FaultKind;
234
+ times?: number;
235
+ reason?: string;
236
+ }
237
+ /** @internal The SDK dev server's fault injection; see `FaultKind`. */
238
+ | {
239
+ type: 'disarmFault';
240
+ fault: FaultKind;
241
+ };
242
+ /**
243
+ * Every read. None of these enters the queue: a read is never blocked behind a
244
+ * mutation (§9.7), so a tick in flight must not delay one.
245
+ */
246
+ export type QueryCommand = {
247
+ type: 'getState';
248
+ }
249
+ /**
250
+ * `uiIdentifier` names the calling surface, whose `endpoints` allowlist
251
+ * bounds what it may call (§6.12). `external` marks a caller outside the
252
+ * game, such as a facilitator's AI agent, which names no surface and
253
+ * reaches only an endpoint whose `visibility` is `external`.
254
+ */
255
+ | ({
256
+ type: 'callEndpoint';
257
+ endpointIdentifier: string;
258
+ request: unknown;
259
+ uiIdentifier?: string;
260
+ external?: boolean;
261
+ /**
262
+ * Who is behind an external call, as the host authenticated them.
263
+ * Accepted only with `external`, and passed to the endpoint as
264
+ * `caller.principal`.
265
+ */
266
+ principal?: {
267
+ kind: string;
268
+ id: string;
269
+ name?: string;
270
+ };
271
+ /**
272
+ * The scenario a call from the scenario editor is editing, whose
273
+ * draft the endpoint's settings resolve from (§6.5, §6.12). Null for
274
+ * an editor opened on no scenario; absent for the one in force.
275
+ */
276
+ scenarioId?: string | null;
277
+ } & TeamScope & Actor)
278
+ /**
279
+ * `uiIdentifier` names the asking surface, whose declarations bound what
280
+ * it may read (§12.5). Omitted for a caller with no surface, such as the
281
+ * CLI, which is system-trusted.
282
+ */
283
+ | ({
284
+ type: 'getPastState';
285
+ query: PastStateQuery;
286
+ uiIdentifier?: string;
287
+ } & Actor) | ({
288
+ type: 'getAllTeamsParticipants';
289
+ uiIdentifier?: string;
290
+ } & Actor)
291
+ /** Endpoint calls that changed something, oldest first (§6.12). */
292
+ | {
293
+ type: 'getEndpointAudit';
294
+ }
295
+ /**
296
+ * The package's endpoints, as a caller outside the game discovers them:
297
+ * what each is for, what it takes and returns, and what it may change.
298
+ * `external` narrows the list to the ones such a caller may call.
299
+ */
300
+ | {
301
+ type: 'listEndpoints';
302
+ external?: boolean;
303
+ };
304
+ /** One endpoint, as `listEndpoints` describes it. */
305
+ export interface EndpointListing {
306
+ identifier: string;
307
+ displayName?: string;
308
+ description?: string;
309
+ scope: 'session' | 'team';
310
+ visibility: 'internal' | 'external';
311
+ requestSchema: Record<string, unknown>;
312
+ responseSchema: Record<string, unknown>;
313
+ /**
314
+ * Capabilities it may change, and session actions it may carry out. An
315
+ * agent host deciding whether a call needs a person's approval reads these:
316
+ * an endpoint that only reads is a different request from one that ticks.
317
+ */
318
+ writes: string[];
319
+ actions: string[];
320
+ }
321
+ export type Command = MutationCommand | QueryCommand;
322
+ /** What a query answered with. */
323
+ export type QueryResult = {
324
+ type: 'state';
325
+ state: StateProjection;
326
+ }
327
+ /**
328
+ * `blobs` is present on an external call whose response carries `blob:`
329
+ * references: each one resolved to a URL the caller can fetch it from,
330
+ * because a caller outside the game has no `getAssetUrl` of its own.
331
+ */
332
+ | {
333
+ type: 'endpoint';
334
+ response: unknown;
335
+ blobs?: Record<string, string>;
336
+ }
337
+ /**
338
+ * A `callEndpoint` that failed (§6.12): why, and which of its effects had
339
+ * already landed. An answer rather than a throw, so every transport
340
+ * carries it unchanged.
341
+ */
342
+ | {
343
+ type: 'endpointFailure';
344
+ failure: EndpointFailure;
345
+ } | {
346
+ type: 'pastState';
347
+ entries: PastStateEntry[];
348
+ } | {
349
+ type: 'participants';
350
+ participants: unknown[];
351
+ } | {
352
+ type: 'endpointAudit';
353
+ entries: EndpointAuditEntry[];
354
+ } | {
355
+ type: 'endpoints';
356
+ endpoints: EndpointListing[];
357
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * What a client may ask a session to do (§20).
3
+ *
4
+ * One closed command set, shared by every client of the dev server: the
5
+ * browser console, the CLI, a Playwright suite through `runCommand`, and an
6
+ * agent posting to `/api/command`. Published from the SDK rather than declared
7
+ * inside the runtime so a test is type-checked against the commands the
8
+ * runtime actually accepts, and a misspelled field fails to compile rather
9
+ * than coming back as a 400.
10
+ *
11
+ * The runtime that validates these at its boundary lives in the tools
12
+ * package. This module is types only.
13
+ */
14
+ export {};